[I'm not really sure that this is a RC.SE related question at all, as it asks for a basic strategy independent of technology. Will vote for getting it moved.]
There are only two basic strategies to solve this:
a) Compress List as One Blob - Decompress Partitially Virtual
The whole data structure (all data/list elements) gets compressed including list management (pointers/length delimiters/stop words/etc.) as one item.
To access a data item decoding starts with the whole blob, but the decoder does not write resulting data to memory, but hands every byte to the list interpreter (*1) which will interpret list management information until the right sub block comes along. Only after that all data will be written to memory (*2. That function will return with some condition code telling the decompressor to continue or quit - the later as soon as the end of that list element is reached.
Going this way so splits decompressing into three phased
- Virtual decompressing all data before the desired entry
- Real decompression of the entry
- Virtual decompression afterwards (aka doing noting :))
There are a few advantages and some quite important disadvantages:
- Possibly highest compression ration (depending on method and data)
- Use of rather standard tools for creation of the blog
- List structure must support streaming access (no back or forward referenced access)
- Decoding Software must be (re-)written to support a callback instead of memory write
- High variation of access time
- Later items will have considerable higher access time
- High over all processing time
b) Compress/Decompress Each Item On Its Own
Here each list item is compressed on it's own and then put into the list structure. For decompression each item will be decompressed directly on it's own.
- Standard tools (functions) can be used to decode each element
- Finding an item is is a basic memory access
- Access time is (almost) independent of position
- Only the data item requested needs to be decoded.
- Decoding is as fast as possible
- High flexibility for item handling
- Creation of the data structure may need additional tools/code
- Compression may be less effective
- Worst case compressed ata may be longer than uncompressed
The later is quite depended on compression method and data structure. A directory based compression will yield dismal results, while algorithmic compression may not show any difference. Likewise limited value range data (like Text) may show better results than binary data. While both are common place knowledge for compression, they do have more influence on smaller data chunks.
The item based approach does offer a high degree of flexibility as each entry can be handled different. A flag may note for example if an entry is compressed at all - like for short entries or such where compression isn't effective at all due their random nature. It could also note the use of specific compression methods depending on data type.
In fact, content specific compression may produce a way more desirable result than a generic method, especially with limited resources of memory and CPU. Just think of the good old ZSCII compression. Similar can easy be done for certain value fields and may result in shorter forms than generic compression (*3).
*1 - Like calling a list input function (callback) with that byte in A.
*2 - Or forwarded it using a callback to whoever needs that data - doing so might a lot faster if that data needs to be interpreted only once.
*3 - In some way this can be seen as turning a data based dictionary into a code based one. A gain is made if the resulting code is shorter than the dictionary otherwise added.