Я хочу создать гигантский массив упакованных данных и сохранить его на диске. Я использую writePackedMessageToFd (). Тем не менее, поскольку входные данные очень велики (50 ГБ), мне нужно разместить фрагменты сообщения на диске, чтобы освободить память.
Возможно ли это с текущей версией Cap’n Proto?
Примечание: этот вопрос отличается от упомянутого дублирующего вопроса тем, что выходные данные не нуждаются в потоковой передаче, например, теоретически могут быть и другие параметры, такие как растущий файл, который содержит все (незаконченное) сообщение за первый проход. И второй проход может закончить сообщение.
То, что вы описываете, вероятно, не сработает. При чтении упакованного сообщения с диска вы должны предварительно прочитать и распаковать все сообщение, что потребует достаточного количества физической оперативной памяти для того, чтобы все это было распаковано.
У вас есть два варианта:
Разбейте сообщение на множество частей. Сообщения Cap’n Proto являются саморазграничением, поэтому вы можете записывать несколько сообщений в файл по одному, а затем позже читать их по одному в том же порядке.
Не используйте упакованный формат. Если сообщение не упаковано, то вы можете mmap()
Это. Затем операционная система будет считывать части в память при обращении к ним, а затем может при необходимости вычистить их обратно из памяти. В этом случае чтение тривиально, но написание файла изначально затруднительно. Предположительно, процесс записи файла также не хватает места для всего файла в памяти. Cap’n Proto в настоящее время не поддерживает запись через mmap (доступный для записи mmap проблематичен), но обычно есть еще один прием, который вы можете сделать: вероятно, большие куски вашего сообщения на самом деле происходят непосредственно из некоторых входных файлов, то есть сообщение содержит большой байт капли из других файлов. В этом случае вы можете использовать mmap () в каждом из этих файлов, а затем включить их в сообщение, используя capnp::Orphanage::referenceExternalData()
, Таким образом, не все файлы должны быть резидентными одновременно; ОС будет последовательно выводить и выводить каждую из них по мере записи окончательного результата. Смотрите этот ответ для более подробной информации и пример кода.
Других решений пока нет …