A BiTable is a table that can be seen as an optimized pair of (Table[LitId, Val], Table[Val, LitId]).
BiTable[T] = object vals: seq[T] keys: seq[LitId]
LitId = distinct uint32
proc `$`(x: LitId): string {.borrow, ...raises: [], tags: [].}
proc `<=`(x, y: LitId): bool {.borrow, ...raises: [], tags: [].}
proc `<`(x, y: LitId): bool {.borrow, ...raises: [], tags: [].}
proc `==`(x, y: LitId): bool {.borrow, ...raises: [], tags: [].}
proc `[]`[T](t: BiTable[T]; litId: LitId): lent T {.inline.}
proc `[]`[T](t: var BiTable[T]; litId: LitId): var T {.inline.}
proc getKeyId[T](t: BiTable[T]; v: T): LitId
proc getOrIncl[T](t: var BiTable[T]; v: T): LitId
proc hash(x: LitId): Hash {.borrow, ...raises: [], tags: [].}
proc hash[T](t: BiTable[T]): Hash
proc hasLitId[T](t: BiTable[T]; x: LitId): bool
proc len[T](t: BiTable[T]): int
proc load[T](f: var RodFile; t: var BiTable[T])
proc store[T](f: var RodFile; t: BiTable[T])