You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,10 +6,15 @@ This change log follows the conventions of
6
6
7
7
## [Unreleased][unreleased]
8
8
9
-
### Changed
9
+
### Fixed
10
10
11
-
- Reworked the database export Kaitai Struct definition to incorporate some important discoveries by the Mixxx and rekordcrate developers (thanks once again [@Swiftb0y](https://github.com/Swiftb0y)): all tables that use string offsets have subtypes which control whether those offsets are eight or sixteen bits.
11
+
- Reworked the database export Kaitai Struct definition to incorporate some important discoveries by the [Mixxx](https://mixxx.org) and [rekordcrate](https://github.com/Holzhaus/rekordcrate) developers (thanks once again [@Swiftb0y](https://github.com/Swiftb0y)): all tables that use string offsets have subtypes which control whether those offsets are eight or sixteen bits.
12
12
We had previously only noted that for the Artists table, but the Album, Tag, and Tag Track tables behave this way as well, and in fact even the Track table follows this pattern, but its offsets always use the sixteen bit variant because the rows are so big.
13
+
- The understanding of row counts in DeviceSQL data pages has been broken since the very beginning (though we had some clumsy workarounds that were good enough for reading).
14
+
Thanks to [Robin McCorkell](https://github.com/RobinMcCorkell) we now can properly interpret these non-byte-aligned numbers.
15
+
16
+
### Changed
17
+
13
18
- Updated the analysis file Kaitai Struct definition to cope with the fact that rekordbox sometimes puts truly bizarre values (we have seen `f3` and `f9`) in the track bank byte of song structure tags.
14
19
Previously this cause construction of the entire tag object to fail because no matching enumeration value could be found.
15
20
Now we have a separate `raw_bank` field that holds the numeric value, and `bank` is a value instance that can be `null` when `raw_bank` is not recognizable.
@@ -36,7 +41,7 @@ May the Fourth be with you.
36
41
- Upgraded Kaitai Struct to version 0.10, which includes a number of
37
42
fixes and adds linting of mapped values.
38
43
> :wrench: This is a backwards-incompatible change.
39
-
- Since we are already backwards incompatible with pervious releases,
44
+
- Since we are already backwards incompatible with previous releases,
40
45
changed some mapped value names to correspond to
41
46
the KSY style guide and fix linter errors reported by KSC 0.10:
42
47
1. In `rekordbox_pdb.ksy` renamed `num_groups` to `num_row_groups`.
@@ -196,20 +195,11 @@ This might be used by the history feature, or might be some kind of data integri
196
195
197
196
We don't know what _unknown~2~_ contains, though it is often/always zero. It may be an extension of _version_ to 64-bits?
198
197
199
-
Next, __num_rows_small__ (abbreviated _n~rs~_ in the byte field diagram above) holds the number of row offsets (valid or not) that are present in the page, unless __num_rows_large__ (below) holds a value that is larger than it (but not equal to `1fff`). To find the actual rows, you need to scan all 16 entries of each of the row groups present in the page, ignoring any whose <<#row-presence-bits,row presence bit>> is zero.
200
-
This seems like a strange mechanism for dealing with the fact that some tables (like playlist entries) have a lot of very small rows, too many to count with a single byte.
201
-
But then why not just always use __num_rows_large__?
202
-
203
-
__num_rows_valid__ (abbreviated _num~rv~_) holds the number of valid rows multiplied by 0x20 (i.e. the first 5 bits are not part of the counter). This count does reflect invalidated rows unlike __num_rows_small__.
* Page containing 7 valid rows and some deleted rows: _num_rows_small_=10, _num_rows_large_=0x1fff, _num_rows_valid_=224
198
+
The three bytes{nbsp}``8``–``a``, labeled “row counts”, actually contain two non-byte-aligned numbers.
199
+
The first 13 bits, __num_row_offsets__ keeps track of how many row offsets have ever been allocated in the heap, even if some of them are no longer valid.
200
+
This number only ever increases over time, and can be used to calculate how many row groups are present in the page.
201
+
The final 11 bits, __num_rows__, report the number of valid rows that are currently present in the table.footnote:[It is unclear why these two values are packed into three bytes like this.
202
+
We did not understand this structure, and had to rely on clumsy workarounds, until https://github.com/RobinMcCorkell[Robin McCorkell] figured this out in December 2025.]
213
203
214
204
Byte{nbsp}``1b`` is called __page_flags__ (abbreviated _p~f~_ in the diagram).
215
205
According to Mr. Lesniak, “strange” (non-data) pages will have the value `44` or `64`, and other pages have had the values `24` or `34`.
@@ -219,7 +209,7 @@ Bytes{nbsp}``1c``-`1d` are called __free_size__ (abbreviated _free~s~_ in the di
219
209
220
210
Bytes{nbsp}``20``-`21`, _u~5~_ , are of unclear purpose. Mr. Lesniak labeled them “(0→1: 2).”
221
211
222
-
Bytes{nbsp}``22``-`23`, __num_rows_large__ (abbreviated _num~rl~_ in the diagram) hold the number of entries in the row index at the end of the page when that value is too large to fit into __num_rows_small__ (as mentioned above), and that situation seems to be indicated when this value is larger than __num_rows_small__, but not equal to `1fff`.
212
+
Bytes{nbsp}``22``-`23`, labeled __unk~rows~__, hold a value that seems related to the number of rows in the table in an unclear way, but sometimes instead equals `1fff`.
223
213
224
214
_u~6~_ at bytes{nbsp}``24``-`25` seems to have the value `1004` for strange pages, and `0000` for data pages.
225
215
And Mr. Lesniak describes _u~7~_ at bytes{nbsp}``26``-`27` as “always 0 except 1 for history pages, num entries for strange pages?”
0 commit comments