Hintergrund: Ich schreibe C-Code für Mikrocontroller, um eine EBML-Datei zu schreiben. EBML ist wie ein binäres XML mit verschachtelten Elementen, aber anstelle von Start- und End-Tags gibt es eine Start-ID, eine Länge und dann die Daten. Ich schreibe dies in einer Anwendung mit geringem Stromverbrauch in externes Flash, daher möchte ich die Flash-Zugriffe auf ein Minimum beschränken. Der Speicher ist ebenfalls begrenzt, da nichts jemals einfach ist.
Wenn ich das gesamte EBML-Element im Speicher behalten kann, ist es einfach, es zu generieren, da ich zurückgehen und die Länge jedes Elements eingeben kann, nachdem ich weiß, wie lang es ist. Das Problem ist, was zu tun ist, wenn ich nicht das gesamte Element im Speicher halten kann. Die Optionen, die ich sehe, sind:
- Schreiben Sie, was ich weiß, und gehen Sie dann zurück und fügen Sie die Längen hinzu (am einfachsten, fügt aber mehr Flash-Zugriff hinzu, als ich möchte).
- Berechnen Sie die Länge jedes Elements, bevor ich mit dem Schreiben beginne (relativ einfach, aber viel Prozessorzeit).
- Wechseln Sie den Modus, sobald mein Speicher voll ist, so dass ich dann mit den Daten fortfahre, aber nur, um die Längen für Elemente zu berechnen, die bereits im Speicher reserviert sind. Schreiben Sie dann, was ich im Speicher habe, und gehen Sie zurück und verarbeiten Sie die Daten dort weiter, wo ich aufgehört habe. (Meine bisherige Lieblingsoption)
- Geben Sie Elementen eine maximale oder Worst-Case-Länge, wenn sie geschrieben werden müssen und ihre endgültige Länge noch nicht bekannt ist. (Einfacher als oben, könnte aber nach hinten losgehen und Platz verschwenden)
Frage: Es scheint, dass dies ein relativ häufiges Thema sein sollte, über das die Leute nachgedacht haben. Ich weiß, dass es auch beim Bilden einiger Datenpakete passieren kann. Gibt es eine bessere / allgemeinere / akzeptiertere Technik, die mir hier fehlt? Oder nur einige Begriffe für das Problem, nach dem ich suchen kann?
quelle
Antworten:
Wenn Sie nicht wissen, wie lang Ihre Nutzlast sein wird, ist dies selten ein Grund zur Sorge, auch wenn Sie sich nicht an die Position erinnern und die Länge später wieder auffüllen können:
Notieren Sie sich einfach "unbekannte Größe".
Diese Funktion hängt von der Nutzlast ab, die aus EBML-Elementen besteht, und das folgende Element ist jedoch kein gültiges untergeordnetes Element.
Wenn Sie möchten, können Sie die resultierende EBML später nach Belieben offline kanonisieren, z. B. "keine unbekannten Größen, minimale Größe" oder "minimale Größe, unbekannte Größen vermeiden".
Weitere Informationen finden Sie im EBML RFC-Entwurf auf matroska.org.
quelle
Wenn ein einzelnes Element mit einer festen Anzahl von Unterelementen zu groß ist, sollten Sie möglicherweise versuchen, es in ein Schema zu unterteilen. Ich kenne dieses Format nicht, aber höchstwahrscheinlich können Sie darin eine maximale Länge definieren.
Für Sequenzen können Sie versuchen, die maximale Anzahl von Unterelementen und "Streams" zu definieren, die in der nächsten Datei verbleiben
Bereiten Sie für Elemente, die möglicherweise die maximale Speichergröße überschreiten, einen Stapel mit Paaren vor: Position der reservierten Elementlänge und Längenzähler. Speichern Sie beim Popup den aktuellen Zähler in der aktuellen Markierung und addieren Sie den Wert zum nächsten Zähler.
Versuchen Sie im Allgemeinen, die Anzahl der zu großen Elemente zu minimieren
quelle
KISS und YAGNI.
Wählen Sie Option 1 und wiederholen Sie diese, wenn dies zu einem echten Problem wird.
Zumindest für ähnliche Anwendungsfälle mit ähnlichen Binärformaten ist dies die einfachste / einfachste / beste Lösung, wenn nur einige Werte auf diese Weise gefüllt werden mussten. Wenn Sie dies für jeden einzelnen Datenblock tun müssen, liegt möglicherweise ein Architekturfehler vor.
quelle