Four Stream Index Compressor
In the same way that a modern CPU manages a small number of prefetch streams, we keep object references short (ideally one byte) by managing a small array of Ints that point to recently accessed referenced objects. During serialization, an algorithm decides whether to reuse an existing pointer, adjusting it by a small offset, or jump to a new absolute position because there were no pointers close enough to produce an efficient relative adjustment. During deserialization, the pointers are used to reconstruct each offset or new absolute position, and the appropriate pointer is updated in exactly same way as occurred during serialization.
When an absolute pointer is used, a 0..3 counter indicates which of the four pointers should be replaced. That counter is then incremented (mod 4) to the next pointer that will be replaced.
Constructors
Functions
Check if we're between 16 before and 15 after one of the pointers, (always starting with the 0th one). If so, bias the delta to be 0..31, shift it left twice, and add the pointer number 0..3 that was used. Also adjust that pointer to the new value. That produces a value in 0..127, which gets written in one byte by the serializer.
The next value that would be used as an index. Do not change the currentIndex.
Do the reverse of compress().
The current index has just advanced. Track it to allow relative backward offsets to be used when necessary.