Подтвердить что ты не робот

Буферы протоколов - хранить двойной массив, 1D, 2D и 3D

Как может быть массив двойного (1D), сохраненный с использованием буфера протокола? Как насчет многомерных (2D или 3D) плотных массивов?

4b9b3361

Ответ 1

Массив double будет лучше всего сохранен через

repeated double foo = 5 [packed=true];

repeated заставляет его действовать как список, позволяя несколько элементов; packed исключает заголовок для каждого элемента.

Прямая поддержка прямоугольных (или более высоких) массивов в protobuf отсутствует. Ближайшим является хранить что-то вроде:

repeated innerType foo = 5; // note, can't be "packed"

message innerType {
    repeated double foo = 1 [packed=true];
}

это в целом похоже на зубчатый массив, но с элементом между каждым уровнем.

Ответ 2

Можно просто имитировать макет памяти C/С++:

message DoubleMatrix {
  required uint32 rows = 1;
  required uint32 cols = 2;
  repeated double data = 3 [packed=true];
}

Чтобы получить доступ к данным, используйте data[i*cols+j] (row-major) или data[i+rows*j] (column-major). Для квадратных матриц необходимо сохранить только один из rows/cols. Технически даже в прямоугольном случае protobuf будет знать длину данных, а другое значение может быть получено.

Для удобства использования можно было бы, вероятно, перенести Matrix на С++ классом адаптера, который позволяет получить доступ через double MatrixAdapter::get(int row, int col); он также может проверить data_size()==rows()*cols().