Cache Index¶
An index is one category of cache content - models, sprites, maps, and so on - and is stored as
a main_file_cache.idxN file that says where each of its archives lives inside the single
main_file_cache.dat2 data file.
ECacheIndex names the ones worth knowing about. TCacheIndex opens one and reads its reference table; TCacheIndex.Cache unpacks its archives.
CacheIndex.Create¶
function TCacheIndex.Create(id: Integer; constref reader: TCacheReader): TCacheIndex; static;
function TCacheIndex.Create(id: ECacheIndex; constref reader: TCacheReader): TCacheIndex; static; overload;
Opens index id of reader’s cache by reading its .idxN file, and raises if that file is
missing.
This only opens the index. Its reference table is read by TCacheIndex.Load, which TCacheReader.Load calls straight afterwards.
CacheIndex.ReadArchiveSector¶
function TCacheIndex.ReadArchiveSector(id, owner: Integer; constref data: TByteArray): TArchiveSector;
Reassembles archive id out of the data file and returns it still compressed - call
TArchiveSector.Decompress on the result to get at its contents.
data is the index table to look the archive up in, and owner is the index number the sectors
must be tagged with. An archive is not stored in one piece: the index gives its total size and
the position of its first sector, and every sector’s header points at the next one. Each header
also repeats the archive id, the sector’s position in the chain and the owning index, all of
which are checked as the chain is walked - anything that does not line up means the cache is
corrupt or the archive does not exist, and an empty sector is returned.
CacheIndex.Load¶
procedure TCacheIndex.Load();
Reads this index’s entry out of the master index, which is where its reference table lives.
The reference table is what says which archives the index holds and what is in them, so this has to run before the index can be used for anything.
CacheIndex._CacheArchive¶
procedure TCacheIndex._CacheArchive(idx: Integer);
Decompresses the archive sitting at position idx of this index’s archive list and splits it
into its files. An archive that is already cached is left alone.
CacheIndex.Cache¶
procedure TCacheIndex.Cache();
procedure TCacheIndex.Cache(id: Integer); overload;
procedure TCacheIndex.Cache(archive: EConfigArchive); overload;
Decompresses this index’s archives and splits them into their files, leaving the contents in
ReferenceTable.Archives.
Without arguments every archive is decompressed. Given an archive id, or for the config index an
EConfigArchive name, only that one is - which is what you want when a few archives are all
you are after, because decompressing a whole index is expensive: all of ECacheIndex.MAPS unpacks
well over a hundred megabytes, and of the few hundred milliseconds the config index costs the item
and enum archives are a small part. An id the index does not hold is ignored, since the lookup
that follows raises on it anyway.
Each form is a no-op once the archives it covers are cached, so calling it before reaching for an archive’s data is safe.
Example:
CacheReader.Indices[ECacheIndex.CONFIGS].Cache(EConfigArchive.ITEM);
archive := CacheReader.Indices[ECacheIndex.CONFIGS].ReferenceTable.Archives.Value[EConfigArchive.ITEM];