Справочная информация: я пишу код микроконтроллера C для записи файла EBML. EBML похож на двоичный XML с вложенными элементами, но вместо начального и конечного тегов есть начальный идентификатор, длина, а затем данные. Я записываю это во внешнюю флэш-память в приложении с низким энергопотреблением, поэтому я бы хотел, чтобы доступ к флэш-памяти был минимальным. Память также ограничена, потому что нет ничего легкого.
Когда я могу сохранить весь элемент EBML в памяти, генерировать его легко, потому что я могу вернуться и заполнить длину каждого элемента после того, как узнаю, что это за длина. Проблема в том, что делать, когда я не могу удержать весь элемент в памяти. Варианты, которые я вижу:
- Напишите то, что я знаю, затем вернитесь назад и добавьте длины (проще всего, но добавляет больше флэш-доступа, чем я хочу)
- Рассчитайте длину каждого элемента, прежде чем я начну писать (относительно легко, но много процессорного времени)
- Переключайте режимы, как только моя память заполняется, так что я затем продолжаю просматривать данные, но только для расчета длин для элементов, уже зарезервированных в памяти. Затем напишите, что у меня в памяти, и вернитесь назад и продолжите обработку данных, с которых я остановился. (Мой любимый вариант пока)
- Дайте элементам максимальную или наихудшую длину, когда они должны быть записаны, а их конечная длина еще не известна. (Проще, чем выше, но может иметь неприятные последствия и тратить пространство)
Вопрос: Похоже, это должно быть относительно распространенной проблемой, о которой думали люди. Я знаю, что это также может произойти при формировании некоторых пакетов данных. Есть ли здесь лучшая / более распространенная / более приемлемая техника, которую я пропускаю? Или просто некоторые термины для вопроса, который я могу найти?
источник
Ответы:
Если вы не знаете, какой длины будет ваша полезная нагрузка, это редко вызывает беспокойство, даже если вы не можете запомнить позицию и заполнить длину позже:
Просто запишите «неизвестный размер».
Эта функция зависит от полезной нагрузки, состоящей из элементов EBML и следующего элемента, который не является допустимым дочерним элементом.
Если вы хотите, вы можете позже канонизировать полученный EBML в автономном режиме по вашему усмотрению любым удобным для вас способом, например «без неизвестных размеров, минимального размера» или «с минимальным размером, избегайте неизвестных размеров».
За подробностями обращайтесь к проекту EBML RFC на matroska.org.
источник
Если отдельный элемент с фиксированным числом подэлементов слишком велик, то, возможно, вам следует попытаться разделить его на схему. Я не знаю этот формат, но, скорее всего, вы можете определить максимальную длину в нем.
Для последовательностей вы можете попытаться определить максимальное количество подэлементов и «поток», оставшихся в следующем файле
Для элементов, потенциально превышающих максимальный объем памяти, подготовьте стек, содержащий пары: зарезервированное положение длины элемента и счетчик длины. При всплытии сохраните текущий счетчик в текущем маркере и добавьте его значение к следующему счетчику.
В общем постарайтесь минимизировать количество слишком больших элементов
источник
ПОЦЕЛУЙ и ЯГНИ.
Выберите вариант № 1, и если это станет реальной проблемой - только затем повторите это.
По крайней мере, для похожих случаев использования со схожими двоичными форматами, когда нужно было заполнить только пару значений таким образом, это самое простое / простое / лучшее решение. Если вам нужно сделать это для каждого куска данных - это может быть недостатком архитектуры.
источник