FlatBuffers Хранение / Размер Гарантии - PullRequest
0 голосов
/ 20 мая 2019

FlatBuffers специально избегает определенной стандартизации / гарантий кодирования. По документации:

(https://google.github.io/flatbuffers/flatbuffers_internals.html)

Это может означать, что две разные реализации могут давать разные двоичные файлы с одинаковыми входными значениями, и это совершенно верно.

Хорошо, но строки закодированы на диске непосредственно из какого-либо представления, которое им было дано, или закодированы в каком-то другом представлении? Являются ли операции кодирования с использованием одной и той же версии FlatBuffers и сгенерированного кода детерминированными (N операций с одинаковыми параметрами дают идентичные результаты)?

А как насчет размеров? Будет ли уменьшение размера динамических структур (например, векторов, когда строковые значения делаются короче) привести к соответствующему уменьшению размера кодированной структуры?

Я действительно не понимаю, как работает строковое кодирование, и у меня нет времени разбирать внутренний код.

Я создал пример определения, которое имеет общую структуру parent-> child-> grandchild, где тип parent имеет вектор типа child и Тип grandchild встраивает строку, а также struct . Я хотел преувеличить любую энтропию, которую различные типы значений могут внести в выходной размер, включив несколько из них. Затем я заполнил строковое значение в внуке пятирунной строкой, умноженной на пятьдесят, и итеративно уменьшил множитель на единицу вручную и каждый раз печатал выходной размер окончательного кодирования:

$ go run main.go
String size: (250)
Output encoding size: (400)

$ go run main.go
String size: (245)
Output encoding size: (400)

$ go run main.go
String size: (240)
Output encoding size: (392)

$ go run main.go
String size: (235)
Output encoding size: (384)

Почему выходной размер кодировки не меняется после того, как я отбросил пять байтов от исходного строкового значения? Почему он уменьшается на восемь байтов на каждые пять байтов, которые я удаляю из исходной строки? Поскольку это строки, я не думаю, что выравнивание сыграет здесь какую-то роль.

У меня все еще есть вопросы выше, но кажется, что может быть безопасным предположением (э-э, гарантия), что 1) размер кодировки стабилен для тех же аргументов, и 2) будет сокращаться вместе с уменьшением размера одного или нескольких значений в нем. Это правда?

Спасибо, что сэкономили мне немного времени и ошибок, так как в настоящее время мне не приходится взламывать это самостоятельно (надеюсь).

Для справки, это определение:

namespace testformat;

struct Vector {
    field9:ulong;
    field10:ulong;
    field11:ulong;
}

table Grandchild {
    field5:ulong;
    string6:string;
    field7:ulong;
    field8:Vector;
}

table Child {
    field3:ulong;
    field4:ulong;
    grandchild:Grandchild;
}

table Parent {
    field1:ulong;
    field2:ulong;
    children:[Child];
}

root_type Parent;

Это часть кода Go с повторяющимся строковым значением, которое я изменяю (вверху):

stringValue := strings.Repeat("strin", 50)
fmt.Printf("String size: (%d)\n", len(stringValue))

stringOffset := b.CreateString(stringValue)

testformat.GrandchildStart(b)

testformat.GrandchildAddField5(b, 44)
testformat.GrandchildAddString6(b, stringOffset)
testformat.GrandchildAddField7(b, 55)

vectorOffset := testformat.CreateVector(b, 11, 22, 33)
testformat.GrandchildAddField8(b, vectorOffset)

grandchildOffset := testformat.GrandchildEnd(b)

1 Ответ

0 голосов
/ 20 мая 2019

Здесь содержится много вопросов, поэтому вот несколько ответов:

  • строки: FlatBuffers хранит их как UTF-8, поэтому на языках, где ввод уже может быть UTF-8 (например, обычно в C ++), сериализация этих данных является прямой копией без какой-либо обработки. В языках, которые используют другие представления (например, Java), существует шаг преобразования при сериализации.
  • Размер: да, уменьшение размера вектора обычно уменьшает размер буфера, но не обязательно в равной степени. Например, если у вас есть вектор шорт, уменьшение размера на 1 элемент может уменьшить буфер на 0 или 4, в зависимости от выравнивания.
  • В своем эксперименте вы снова видите эффект выравнивания и заполнения. Все выровнено по своему размеру (что, как почти все языки программирования хранят данные под капотом в памяти). Поэтому, если ваш буфер содержит double или long или что-то еще, размер буфера будет изменяться только с шагом 8 байт. Строка выравнивается по 4 байтам по своему размеру, но фактические строковые данные выровнены только по 1 байту, поэтому можно добавлять символы в строку без изменения размера буфера, поскольку она просто использует больше того, что было ранее байты заполнения. Даже если строковые байты не нуждаются в выравнивании, смежные данные могут.
  • 1: только если в том же порядке или в том же языке / реализации. Некоторые реализации могут изменить порядок, который влияет на выравнивание и заполнение.
  • 2: Как я показал выше, уменьшение размера буфера только косвенно связано с уменьшением элементов.
...