# Reference Table An index's catalogue: which archives it holds, which files are in each of them, and the revisions and checksums of both. It is read when the cache is opened, so what exists is known long before anything is decompressed. - - - ## ReferenceTable.Create ```pascal function TReferenceTable.Create(id: Integer): TReferenceTable; static; ``` An empty reference table for index `id`. {ref}`TReferenceTable.Read` fills it in. - - - ## ReferenceTable.Contains ```pascal function TReferenceTable.Contains(id: Integer): Boolean; ``` Whether this index holds an archive with the given id. - - - ## ReferenceTable flags ```pascal function TReferenceTable.HasName(): Boolean; function TReferenceTable.HasWhirlpool(): Boolean; function TReferenceTable.HasLengths(): Boolean; function TReferenceTable.HasChecksums(): Boolean; ``` Which optional fields this table stores for each of its archives. The table's `Mask` is a bitfield that says which of the four are present, and they appear in that order in the encoded table, so {ref}`TReferenceTable.Read` has to consult these to know where each following field starts. - - - ## ReferenceTable.Read ```pascal procedure TReferenceTable.Read(const data: TByteArray; var offset: Integer); ``` Decodes an index's reference table: which archives it holds, which files are in each of them, and the metadata the table carries about both. The table is stored column by column rather than archive by archive - every archive's CRC, then every archive's revision, and so on - so this makes one pass per field over the whole archive list. Ids themselves are stored as deltas from the previous id, which is why they accumulate and why they always come out ascending. Version 7 tables write ids as {ref}`ReadBigSmart` because they can exceed 16 bits; earlier ones always use 2 bytes. Anything outside versions 5 to 7 raises. Opening a cache runs this over every index, which comes to some hundreds of thousands of ids and as many again of per-archive fields, and it is the bulk of what {ref}`TCacheReader.Load` costs. So the id and 32 bit reads are written out here rather than going through {ref}`ReadBigSmart` and {ref}`Read32Bits` - a call per field is worth about a third of the running time at this scale - and the version is branched on once instead of once per id. - - - ## ReferenceTable.ArchiveID ```pascal function TReferenceTable.ArchiveID(const name: String): Integer; ``` The id of the archive named `name`, or `-1` if this index has no such archive. The cache does not store names, only their hashes, so this compares against {ref}`CacheString2Hash` of the name. Example: ```pascal id := CacheReader.Indices[ECacheIndex.SPRITES].ReferenceTable.ArchiveID('mapscene'); ```