Как может быть массив двойного (1D), сохраненный с использованием буфера протокола? Как насчет многомерных (2D или 3D) плотных массивов?
Буферы протоколов - хранить двойной массив, 1D, 2D и 3D
Ответ 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()
.