FixedHash

FixedHash is a custom Grezzo format for serializing hash tables that map string keys to arbitrary binary blobs.

FixedHash
File format
Endianness little
Version 1
This article is about the file format in general. For actual values, check the game RomFS.

Hash function

String keys are hashed using the following hash function:

u32 Hash(const char* key) {
  u32 hash = 0;
  while (*key) {
    hash ^= *key++ + (h >> 2) + (h << 5);
  }
  return hash;
}

Format

Offset Type Description
0x0 u8 Magic (must be 0x3D)
0x1 u8 Version (must be 1)
0x2 u16 Number of hash table buckets (N)
0x4 u16 Number of child FixedHash nodes
0x6 u16 Padding? [check]
0x8 u32[N + 1] Offsets to the first entry in each bucket (relative to the Entries section)
0xFFFFFFFF for empty buckets.
X = (0x8 + 4*(N+1) + 3) & -8 u64 Entries section size
X + 8 Entry[...] Entries
Y = align(X + entries section size, 8) u64 Entry offsets section size
Y + 8 u32[...] Entry offsets (relative to the Entries section)
Z = align(Y + entry offset section size, 8) u64 Data section size
Z + 8 any Data
A = align(Z + data section size, 4) u32 Names section size
A + 4 C strings Names

Entry

Offset Type Description
0x0 u16 Node index if this describes a FixedHash child node (if so, it must be <= 0xFFED)

Otherwise, must be >= 0xFFF0 for non-node data.

0x2 u16 Name offset (relative to the Name section)
0x4 u32 Name hash
0x8 u32 Next entry offset (relative to the Entries section) for hash table collision resolution.
0xFFFFFFFF if there is no other entry in the bucket.
0xC u32 Data offset (relative to the Data section)

For non-node data, the data size is stored at offset+0 as a u64 and the actual data is at offset+8.