Antecedentes: estou escrevendo o código C do microcontrolador para gravar um arquivo EBML. A EBML é como um XML binário com elementos aninhados, mas em vez de tags de início e fim, há um ID de início, comprimento e, em seguida, os dados. Estou escrevendo isso no Flash externo em um aplicativo de baixa potência, por isso, gostaria de manter o mínimo possível o acesso ao flash. A memória também é limitada, porque nada é fácil.
Quando posso manter todo o elemento EBML na memória, é fácil gerá-lo, pois posso voltar e preencher o comprimento de cada elemento depois de saber qual é esse comprimento. O problema é o que fazer quando não consigo armazenar todo o elemento na memória. As opções que vejo são:
- Escreva o que eu sei, depois volte e adicione os comprimentos (mais fácil, mas adiciona mais acesso ao flash do que eu quero)
- Calcular o comprimento de cada elemento antes de começar a escrevê-lo (relativamente fácil, mas muito tempo do processador)
- Alterne os modos assim que a memória ficar cheia, para que eu continue com os dados, mas apenas para calcular os comprimentos dos elementos já reservados na memória. Em seguida, escreva o que tenho na memória e volte e continue processando os dados de onde parei. (Minha opção favorita até agora)
- Forneça aos elementos um comprimento máximo ou pior, quando eles precisam ser gravados e seu comprimento final ainda não é conhecido. (Mais fácil do que acima, mas pode sair pela culatra e desperdiçar espaço)
Pergunta: Parece que esse deve ser um problema relativamente comum em que as pessoas pensaram. Eu sei que isso também pode acontecer ao formar alguns pacotes de dados. Existe uma técnica melhor / mais comum / mais aceita que estou perdendo aqui? Ou apenas alguns termos para o problema que eu posso pesquisar?
fonte
Respostas:
Se você não souber quanto tempo sua carga útil terá, isso raramente é motivo de preocupação, mesmo que você não consiga se lembrar da posição e preencha o comprimento posteriormente:
Apenas anote "tamanho desconhecido".
Esse recurso depende da carga útil que consiste em elementos EBML e o elemento a seguir não é um elemento filho válido.
Se desejar, você pode canonizar posteriormente a EBML resultante offline, conforme sua conveniência, da maneira que desejar, por exemplo, "sem tamanhos desconhecidos, tamanho mínimo" ou "tamanho mínimo, evitar tamanhos desconhecidos".
Consulte o rascunho de RFC da EBML em matroska.org para obter detalhes.
fonte
Se um único elemento com número fixo de subelementos for muito grande, talvez você deva tentar dividi-lo no esquema. Não conheço esse formato, mas provavelmente você pode definir um comprimento máximo nele.
Para seqüências, você pode tentar definir a contagem máxima de subelementos e o "fluxo" restantes no próximo arquivo
Para elementos que excedam o tamanho máximo da memória, prepare uma pilha contendo pares: localização do comprimento do elemento reservado e contador de comprimento. No pop, salve o contador atual no marcador atual e adicione seu valor ao próximo contador.
Em geral, tente minimizar o número de elementos muito grandes
fonte
BEIJO e YAGNI.
Escolha a opção 1 e se ela se tornar um problema real - só então reitere nela.
Pelo menos para casos de uso semelhantes com formatos binários semelhantes, quando apenas alguns valores precisavam ser preenchidos dessa maneira, essa é a solução mais simples / mais fácil / melhor. Se você precisar fazer isso em cada parte dos dados - pode ser uma falha na arquitetura.
fonte