Menulis di awal file sesuatu yang hanya Anda ketahui di bagian akhir

9

Latar Belakang: Saya sedang menulis kode micro controller C untuk menulis file EBML. EBML seperti XML biner dengan elemen bersarang, tetapi alih-alih tag awal dan akhir, ada ID awal, panjang, dan kemudian data. Saya menulis ini ke Flash eksternal dalam aplikasi daya rendah, jadi saya ingin menjaga agar flash mengakses seminimal mungkin. Memori juga terbatas, karena tidak ada yang mudah.

Ketika saya bisa menyimpan seluruh elemen EBML dalam memori, kemudian membuatnya mudah karena saya bisa kembali dan mengisi panjang setiap elemen setelah saya tahu berapa panjangnya. Masalahnya adalah apa yang harus dilakukan ketika saya tidak dapat menahan seluruh elemen dalam memori. Pilihan yang saya lihat adalah:

  • Tulis apa yang saya tahu, lalu kembali dan tambahkan panjangnya (termudah, tetapi tambahkan lebih banyak akses flash daripada yang saya inginkan)
  • Hitung panjang setiap elemen sebelum saya mulai menulisnya (relatif mudah, tetapi banyak waktu prosesor)
  • Beralih mode begitu ingatan saya terisi, sehingga saya kemudian melanjutkan melalui data, tetapi hanya untuk menghitung panjang untuk elemen yang sudah disimpan dalam memori. Kemudian tulis apa yang ada dalam memori saya, dan kembali dan lanjutkan memproses data dari tempat saya tinggalkan. (Pilihan favorit saya sejauh ini)
  • Berikan elemen panjang kasus maksimum atau terburuk ketika mereka perlu ditulis dan panjang akhir mereka belum diketahui. (Lebih mudah daripada di atas, tetapi bisa menjadi bumerang dan membuang-buang ruang)

Pertanyaan: Sepertinya ini seharusnya menjadi masalah yang relatif umum yang dipikirkan orang. Saya tahu itu juga bisa terjadi ketika membentuk beberapa paket data. Apakah ada teknik yang lebih baik / lebih umum / lebih diterima yang saya lewatkan di sini? Atau hanya beberapa istilah untuk masalah yang bisa saya cari?

pscheidler
sumber
1
/ sccs bekerja dengan cara ini: ia menulis checksum dari semua byte di awal file setelah selesai menulis. Berfungsi hebat pada Unix yang dapat melakukan operasi file yang diperlukan secara atom (mis. Solaris) dan menyebabkan masalah sporadis aneh pada Unix yang tidak dapat melakukan itu, misalnya Linux
gnat

Jawaban:

2

Jika Anda tidak tahu berapa lama muatan Anda akan, itu jarang menimbulkan kekhawatiran bahkan jika Anda tidak dapat mengingat posisi dan mengisi ulang panjangnya nanti:

Catat "ukuran tidak diketahui".

Fitur itu tergantung pada payload yang terdiri dari elemen-elemen EBML dan elemen berikut ini yang tidak menjadi elemen anak yang valid.

Jika mau, nanti Anda bisa mengkanoniskan EBML offline yang dihasilkan sesuka Anda, misalnya "tanpa ukuran yang tidak diketahui, ukuran minimal" atau "ukuran minimal, hindari ukuran yang tidak diketahui".


Lihat Draft EBML RFC di matroska.org untuk detailnya.

Deduplicator
sumber
Ini bagus! Itu adalah sesuatu yang tidak saya sadari dan menghindari masalah inti, tetapi saya masih ingin panduan tentang cara yang baik untuk menyelesaikan masalah inti. Menggunakan elemen ukuran yang tidak dikenal tampaknya dapat membatasi kompatibilitas di masa depan, karena perangkat lunak lama akan keluar secara prematur pada elemen baru.
pscheidler
Anda memerlukan DTD yang tepat atau Anda tidak bisa benar-benar memecahkan kode EBML. Nah, jika semua elemen yang tidak diketahui berukuran Anda dapat melewati mereka, tetapi apakah itu cukup? Cukup poskan proses setiap EBML yang ingin Anda simpan offline jika itu.
Deduplicator
Kami menggunakan skema kami sendiri, yang akan diperluas. Ini telah dirancang dengan pengetahuan bahwa perangkat lunak yang lebih tua mungkin pada akhirnya harus mengabaikan beberapa data. Tetapi ini adalah fitur hebat EBML yang tidak saya sadari, jadi saya menerima jawabannya.
pscheidler
0

Jika satu elemen dengan jumlah subelemen tetap terlalu besar, maka mungkin Anda harus mencoba membaginya dalam skema. Saya tidak tahu format ini, tetapi kemungkinan besar Anda bisa menentukan panjang maksimum di dalamnya.

Untuk urutan Anda bisa mencoba menentukan jumlah maksimum sub-bagian dan "streaming" yang tersisa di file berikutnya

Untuk elemen yang berpotensi melebihi ukuran memori maksimal, siapkan tumpukan yang berisi pasangan: lokasi panjang elemen yang dicadangkan dan penghitung panjang. Pada pop simpan penghitung saat ini di penanda saat ini dan tambahkan nilainya ke penghitung berikutnya.

Secara umum cobalah untuk meminimalkan jumlah elemen yang terlalu besar

Whoot
sumber
Yah, dia mungkin bisa melakukannya untuk elemen EBML-nya sendiri, tapi itu masih tidak membantunya dengan elemen induk.
Deduplicator
Gagasan Anda akan berhasil, tetapi saya lebih suka membuat sistem yang dapat menangani elemen besar, alih-alih membatasi skema sehingga ia menghindari elemen besar.
pscheidler
Solusi ini akan bekerja untuk elemen besar juga, hanya berhati-hati dengan ukuran tumpukan. Dan jika menyangkut skema ... menganggapnya sebagai bahasa yang digunakan aplikasi Anda, jika yang satu tidak bisa menangani yang rumit, maka yang lain harus menyesuaikan atau diperlukan penerjemah. Banyak pengembang (setidaknya C / C ++ yang saya tahu) cenderung untuk menghindari perubahan skema / desain seperti kebakaran, yang kemudian menghasilkan sistem yang buruk. Jika komponen lain tidak dapat menyesuaikan, maka mungkin komponen tersebut tidak terurai / didesain dengan buruk. Jika ada alasan lain untuk tidak berubah, maka Anda mungkin harus mempertimbangkan penggunaan perangkat keras yang berbeda
Whoot
0

KISS dan YAGNI.
Pilih opsi # 1 dan jika itu menjadi masalah nyata - baru kemudian tegaskan kembali.

Setidaknya untuk kasus penggunaan serupa dengan format biner yang serupa, ketika hanya beberapa nilai yang harus diisi sedemikian rupa, ini adalah solusi paling sederhana / termudah / terbaik. Jika Anda harus melakukan ini pada masing-masing dan setiap data - maka itu mungkin merupakan cacat dalam arsitektur.

Kromster
sumber