Skip to content

RefgetTranscripts (reftx) Reference

RefgetTranscripts (reftx) is a compact binary transcript store for HGVS coordinate mapping. It finds a transcript with a binary search over a sorted hash index, so lookups are O(log n). A store can be read from disk with a memory map, with positioned reads (pread), or from bytes already in memory (which is how it runs in the browser).

The code lives in the gtars-refget crate, in the gtars_refget::transcripts module.

use gtars_refget::transcripts::{ReadonlyTxStore, TxBackend, TxStoreBuilder};
// Chromosome digests are the 24 raw bytes behind a refget "SQ." accession.
let raw = base64_url::decode("<sha512t24u digest of chr7>").expect("valid base64url");
let chr7_digest: [u8; 24] = raw.as_slice().try_into()?;
// Build a store from cdot JSON
let mut builder = TxStoreBuilder::new();
builder.add_chrom_mapping("NC_000007.14", chr7_digest);
builder.load_mane_summary("MANE.GRCh38.v1.3.summary.txt.gz")?; // optional, load before ingest
builder.ingest_cdot("cdot.grch38.json.gz")?;
builder.build("transcripts.reftx")?;
// Open and query
let store = ReadonlyTxStore::open_with_backend("transcripts.reftx", TxBackend::Pread)?;
if let Some(tx) = store.lookup("NM_004333.6") {
println!("{}: {} exons on {:?}", tx.accession, tx.exons.len(), tx.strand);
}

Add gtars-refget with the transcripts feature:

[dependencies]
gtars-refget = { git = "https://github.com/databio/gtars", branch = "dev", features = ["transcripts"] }

The API is split in two by Cargo feature:

FeatureWhat you get
transcriptsThe core, which works on every target including WASM: ReadonlyTxStore (with from_bytes), TranscriptRef, the models, CoordinateMapper, the mature mRNA helpers, and build_reftx_bytes_in_memory
transcripts + filesystemAlso the file-based parts: TxStore, TxBackend, TxStoreBuilder, and the ReadonlyTxStore::open_* constructors

filesystem is on by default. For WASM, use default-features = false, features = ["transcripts"].

All public types are re-exported from gtars_refget::transcripts (and from the crate root).


Immutable transcript store for read access. All lookups take &self, so one store can be shared across threads with Arc<ReadonlyTxStore>.

Every constructor checks the header and returns an error if the magic number or format version is wrong. Stores with fewer than 500,000 transcripts are fully decoded into memory when opened.

pub fn open_with_backend<P: AsRef<Path>>(path: P, backend: TxBackend) -> Result<Self>

Open a .reftx file with the backend you choose. Needs the filesystem feature.

Parameters:

  • path - Path to a .reftx file
  • backend - TxBackend::Pread or TxBackend::Mmap
pub enum TxBackend {
Mmap,
Pread,
}
  • Pread - Positioned reads on the file. No memory mapping. The safe default for a single process.
  • Mmap - Memory-map the whole file. Best when many processes read the same large store, since they share the OS page cache. The file must not be changed or truncated while it is mapped. The builder always writes files with an atomic rename, so this is safe for files it produced.
pub fn open_mmap<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn open_pread<P: AsRef<Path>>(path: P) -> Result<Self>

Shortcuts for open_with_backend with a fixed backend. Need the filesystem feature.

pub fn from_bytes(bytes: Vec<u8>) -> Result<Self>

Build a store from the full contents of a .reftx file held in memory. Uses no file system and no memory map, so it works on every target, including WASM.

Example:

let bytes = std::fs::read("transcripts.reftx")?;
let store = ReadonlyTxStore::from_bytes(bytes)?;
pub fn len(&self) -> u64
pub fn is_empty(&self) -> bool

Number of transcripts in the store, and whether it is zero.

pub fn lookup(&self, accession: &str) -> Option<TranscriptRef<'_>>

Look up a transcript by accession. Uses an O(log n) binary search on the index.

Parameters:

  • accession - Transcript accession with version (e.g., "NM_004333.6")

Returns: Option<TranscriptRef<'_>> - A reference to the cached transcript, or a freshly decoded one

Example:

use std::sync::Arc;
let store = ReadonlyTxStore::open_pread("transcripts.reftx")?;
let shared = Arc::new(store);
// Multiple threads can call lookup at the same time
let tx = shared.lookup("NM_004333.6");
pub fn lookup_mane(&self, gene: &str) -> Option<Transcript>

Look up the MANE Select transcript for a gene symbol. The match ignores case ("braf" finds "BRAF"). Returns None if the gene has no MANE Select transcript, or if the store was built without MANE data.

Parameters:

  • gene - Gene symbol (e.g., "BRAF")

Returns: Option<Transcript> - An owned copy of the MANE Select transcript

pub fn has_mane_index(&self) -> bool

Returns true if the store has a MANE gene index, meaning lookup_mane can find anything.


pub enum TranscriptRef<'a> {
Cached(&'a Transcript),
Owned(Transcript),
}

The value returned by ReadonlyTxStore::lookup. It derefs to Transcript, so you can read fields directly (tx.accession, tx.exons).


Mutable, memory-mapped store for the setup phase. Use it when you want to choose which transcripts are decoded ahead of time, then convert it to a ReadonlyTxStore. Needs the filesystem feature. If you just want to read a store, ReadonlyTxStore::open_with_backend is simpler.

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn open_mmap<P: AsRef<Path>>(path: P) -> Result<Self>

Open a store from disk with a memory map. open is the same as open_mmap. Returns an error if the magic number or version is invalid.

pub fn len(&self) -> u64
pub fn is_empty(&self) -> bool
pub fn lookup(&self, accession: &str) -> Option<Transcript>

Look up a transcript by accession (O(log n) binary search). Returns an owned Transcript.

pub fn ensure_decoded(&mut self, accession: &str) -> Result<()>

Decode one transcript into the internal cache ahead of time. The cache is carried into the ReadonlyTxStore.

pub fn ensure_decoded_where<F>(&mut self, predicate: F) -> Result<usize>
where
F: Fn(&Transcript) -> bool,

Decode all transcripts that match a predicate into the cache. Returns how many were cached.

Example:

// Pre-load all BRAF transcripts
let count = store.ensure_decoded_where(|tx| tx.gene == "BRAF")?;
pub fn into_readonly(self) -> ReadonlyTxStore

Convert to a memory-mapped ReadonlyTxStore. If the store has fewer than 500,000 transcripts and nothing has been cached yet, this decodes every transcript into memory first.

pub fn into_readonly_lazy(self) -> ReadonlyTxStore

Convert without decoding anything extra. Transcripts not already cached are decoded from the file on each lookup. Use this when only a few transcripts will be queried.


Builds a .reftx file from cdot JSON. Needs the filesystem feature.

pub fn new() -> Self

Create an empty builder. TxStoreBuilder::default() does the same.

pub fn add_chrom_mapping(&mut self, name: &str, digest: [u8; 24])

Register a chromosome name and its refget digest. The digest is the 24 raw bytes of the sequence's sha512t24u digest (the part after SQ., base64url-decoded).

Parameters:

  • name - Chromosome name as it appears in the cdot file (e.g., "NC_000001.11")
  • digest - 24-byte refget digest
pub fn load_mane_summary<P: AsRef<Path>>(&mut self, path: P) -> Result<usize>

Load MANE flags from an NCBI MANE summary TSV (plain or .gz). It reads the RefSeq_nuc, Ensembl_nuc, and MANE_status columns, so both RefSeq and Ensembl transcripts get their flags.

Call this before ingest_cdot. Flags are attached to transcripts as they are ingested.

Parameters:

  • path - Path to the MANE summary file

Returns: Count of accession entries loaded (RefSeq and Ensembl accessions are counted separately)

pub fn has_mane_flags(&self) -> bool

Returns true if any MANE flags have been loaded.

pub fn ingest_cdot<P: AsRef<Path>>(&mut self, path: P) -> Result<usize>

Ingest a cdot-style JSON file (plain or .json.gz). Skips transcripts whose chromosome was not registered with add_chrom_mapping, transcripts with a strand other than 1 or -1, and transcripts with no exons.

The reader expects a top-level transcripts object. Each entry needs id, contig, strand, and exons (a list of [start, end] pairs), plus optional gene_name, cds_start, and cds_end.

Parameters:

  • path - Path to the JSON file

Returns: Count of transcripts ingested

pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool

Number of transcripts staged so far. Transcripts can also be added directly through the public transcripts: Vec<Transcript> field.

pub fn build<P: AsRef<Path>>(&mut self, output: P) -> Result<()>

Write the binary store to disk. Returns an error if no transcripts are staged. The file is written to a temporary file and then renamed into place, so readers never see a half-written file. A <output>.lock file stops two builders from writing the same path at once.

Parameters:

  • output - Output path for the .reftx file

Example:

let mut builder = TxStoreBuilder::new();
builder.add_chrom_mapping("NC_000007.14", chr7_digest);
builder.load_mane_summary("MANE.GRCh38.v1.3.summary.txt.gz")?;
let count = builder.ingest_cdot("cdot.grch38.json.gz")?;
println!("Ingested {} transcripts", count);
builder.build("transcripts.reftx")?;
pub fn build_reftx_bytes_in_memory(transcripts: &[Transcript]) -> Result<Vec<u8>>

Build a complete .reftx image in memory, with no file system. Works on every target. Pair it with ReadonlyTxStore::from_bytes.


Transcript annotation record.

pub struct Transcript {
/// Accession with version (e.g., "NM_004333.6")
pub accession: String,
/// Gene symbol (e.g., "BRAF")
pub gene: String,
/// Chromosome refget digest (24 bytes, truncated SHA-512)
pub chrom_digest: [u8; 24],
/// Strand orientation
pub strand: Strand,
/// CDS start in genomic coordinates (None if non-coding)
pub cds_start: Option<u32>,
/// CDS end in genomic coordinates (None if non-coding)
pub cds_end: Option<u32>,
/// Exons in genomic order (5' to 3' on chromosome)
pub exons: Vec<Exon>,
/// MANE Select / Plus Clinical status
pub mane: ManeStatus,
}

Methods:

MethodReturn TypeDescription
transcript_length()u32Total transcript length (sum of exon lengths)
cds_length()u32CDS length in bases (0 if non-coding)
is_coding()boolReturns true if transcript has CDS
accession_base()&strAccession without version (e.g., "NM_004333")

A single exon with genomic coordinates.

pub struct Exon {
/// Genomic start (0-based, inclusive)
pub start: u32,
/// Genomic end (0-based, exclusive)
pub end: u32,
}

Methods:

MethodReturn TypeDescription
len()u32Length in bases
is_empty()boolReturns true if zero-length

Strand orientation.

pub enum Strand {
Forward = 1,
Reverse = -1,
}

Strand::from_i8(1) and Strand::from_i8(-1) parse a strand; any other value gives None.

MANE flags for a transcript. The default is both flags false.

pub struct ManeStatus {
/// True if this is the MANE Select transcript for its gene
pub mane_select: bool,
/// True if this is MANE Plus Clinical
pub mane_clinical: bool,
}

is_mane() returns true if either flag is set.


Maps HGVS transcript coordinates to 0-based genomic positions, using a ReadonlyTxStore.

use gtars_refget::transcripts::CoordinateMapper;
let mapper = CoordinateMapper::new(&store);
let result = mapper.c_to_g("NM_004333.6", 1799)?;
println!("genomic position: {}", result.position);
MethodDescription
new(store: &ReadonlyTxStore)Create a mapper
c_to_g(accession, c_pos: i64)Map c.N to genomic
n_to_g(accession, n_pos: u64)Map n.N to genomic
c_to_g_full(accession, c_pos: i64, offset: i64, is_cds_end: bool)Full c. form: negative c_pos for 5' UTR (c.-14), offset for introns (c.93+5 is offset = 5), is_cds_end = true for 3' UTR (c.*N)
n_to_g_full(accession, n_pos: i64, offset: i64)Full n. form with an intronic offset
c_to_g_by_gene(gene, c_pos, offset, is_cds_end)Resolve the gene's MANE Select transcript, then map. Returns (accession_used, MappingResult)
g_to_transcript_offset(accession, g_pos: u64)Map a genomic position to a 0-based offset on the spliced mRNA. Returns Ok(None) if the position is not in an exon

The mapping methods return Result<MappingResult, MappingError>:

pub struct MappingResult {
/// Genomic position (0-based)
pub position: u64,
/// Chromosome refget digest
pub chrom_digest: [u8; 24],
}

MappingError covers cases such as TranscriptNotFound, NoManeTranscript, OutsideCds, InvalidIntronicOffset, the 5' and 3' UTR overflows, and NonCodingTranscript.

CoordinateMapperWriter has the same new, c_to_g, and n_to_g methods, but takes &mut self and reuses its internal buffers between calls. Use it in tight loops.


These build the spliced (mature) mRNA reference sequence for a transcript by reading exon sequences from a ReadonlyRefgetStore. Reverse-strand transcripts are reverse-complemented. The result is the reference sequence; variants are not applied.

pub fn mature_mrna(
store: &ReadonlyRefgetStore,
tx_store: &ReadonlyTxStore,
accession: &str,
) -> Result<String>
pub fn mature_mrna_for_transcript(
store: &ReadonlyRefgetStore,
tx: &Transcript,
) -> Result<String>
pub fn concat_regions(
store: &ReadonlyRefgetStore,
chrom_digest: &[u8; 24],
regions: &[(u32, u32)],
strand: Strand,
) -> Result<String>
  • mature_mrna looks up the accession, then builds its sequence.
  • mature_mrna_for_transcript does the same for a transcript you already have.
  • concat_regions is the building block: it joins any list of 0-based, half-open regions (in genomic order) from one chromosome.

They return an error if the transcript is missing, the chromosome is not in the sequence store, or an exon runs past the end of the chromosome (a sign that the transcripts and genome do not match).

Example:

use gtars_refget::store::RefgetStore;
use gtars_refget::transcripts::{mature_mrna, ReadonlyTxStore};
let seqs = RefgetStore::open_local("/data/refget")?.into_readonly();
let tx_store = ReadonlyTxStore::open_pread("transcripts.reftx")?;
let mrna = mature_mrna(&seqs, &tx_store, "NM_004333.6")?;

HGVS-to-VRS code in gtars-vrs reads transcripts through the TranscriptProvider trait (in gtars_vrs::provider, also re-exported at the gtars_vrs root):

pub trait TranscriptProvider {
fn c_to_genomic(&self, accession: &str, c_pos: i64) -> Result<SequenceLocation, ProviderError>;
fn n_to_genomic(&self, accession: &str, n_pos: u64) -> Result<SequenceLocation, ProviderError>;
fn get_chrom_accession(&self, accession: &str) -> Result<String, ProviderError>;
fn get_strand(&self, accession: &str) -> Result<i8, ProviderError>;
fn c_to_genomic_full(&self, accession: &str, c_pos: i64, offset: i64, is_cds_end: bool)
-> Result<SequenceLocation, ProviderError>; // has a default
fn n_to_genomic_full(&self, accession: &str, n_pos: i64, offset: i64)
-> Result<SequenceLocation, ProviderError>; // has a default
fn gene_to_mane_accession(&self, gene: &str) -> Option<String>; // default: None
}

With the transcripts feature of gtars-vrs, the trait is implemented for ReadonlyTxStore and for TxProvider, a cheap-to-clone wrapper around Arc<ReadonlyTxStore> for sharing one store across workers. NoTranscriptProvider is a stand-in that rejects all transcript lookups, for when you only expect g. variants.

use std::sync::Arc;
use gtars_refget::transcripts::ReadonlyTxStore;
use gtars_vrs::TxProvider;
let store = ReadonlyTxStore::open_pread("transcripts.reftx")?;
let provider = TxProvider::new(Arc::new(store));
let store_again = provider.store(); // &Arc<ReadonlyTxStore>

The reftx module is part of the gtars Python package (it is in the default build):

Terminal window
pip install gtars
from gtars.reftx import ReadonlyTxStore, TxStoreBuilder, CoordinateMapper
store = ReadonlyTxStore.open("transcripts.reftx") # memory-mapped
print(len(store))
tx = store.lookup("NM_004333.6")
if tx:
print(f"{tx.accession}: {tx.gene}, {len(tx.exons)} exons")
print(f"CDS: {tx.cds_start}-{tx.cds_end}")
print(f"Strand: {tx.strand}")
if store.has_mane_index():
tx = store.lookup_mane("BRAF") # case-insensitive
if tx:
print(f"MANE Select for BRAF: {tx.accession}")
MethodReturnsDescription
get_chrom_accession(accession)str or NoneThe chromosome's SQ. refget accession
get_strand(accession)Strand or NoneThe transcript's strand
builder = TxStoreBuilder()
# Map chromosome names to refget accessions ("SQ.<digest>" or the bare digest)
builder.add_chrom_mapping("NC_000007.14", "SQ.<sha512t24u digest of chr7>")
# Optionally load MANE flags. Do this before loading cdot.
builder.load_mane_summary("MANE.GRCh38.v1.3.summary.txt.gz")
# Ingest cdot JSON (.gz is detected automatically)
count = builder.load_cdot("cdot.grch38.json.gz")
print(f"Ingested {count} transcripts")
# Build the store
builder.build("transcripts.reftx")
MethodDescription
add_chrom_mapping(name, accession)Register a chromosome name and its refget accession
load_mane_summary(path)Load MANE flags; returns the count of entries loaded
load_cdot(path)Ingest a cdot JSON file; returns the count ingested. load_cdot_gz is an alias
add_transcript(value)Add one transcript, given a Transcript or a dict shaped like Transcript.to_dict()
len(builder)Number of transcripts staged
build(out_path)Write the .reftx file
mapper = CoordinateMapper(store)
pos = mapper.c_to_g("NM_004333.6", 1799) # 0-based genomic position (int)
info = mapper.c_to_g_full("NM_004333.6", 1799)
# {"chrom": "SQ...", "chrom_accession": "SQ...", "genomic_pos": ..., "strand": Strand.Minus}
by_gene = mapper.c_to_g_by_gene("BRAF", 1799) # same dict plus "accession"
MethodReturnsDescription
c_to_g(accession, c_pos, datum=None)intMap c. to genomic. Pass datum=1 for a 3' UTR c.*N position
n_to_g(accession, n_pos)intMap n. to genomic
c_to_g_full(accession, c_pos, datum=None)dictLike c_to_g, plus chromosome and strand
n_to_g_full(accession, n_pos)dictLike n_to_g, plus chromosome and strand
c_to_g_by_gene(gene, c_pos, datum=None)dictMap through the gene's MANE Select transcript

The Python mapper does not take intronic offsets. Mapping failures raise gtars.reftx.MappingError; store and builder failures raise gtars.reftx.TxStoreError.

ReftxProvider(store) wraps a ReadonlyTxStore for the HGVS functions in gtars.vrs.hgvs:

from gtars.reftx import ReadonlyTxStore, ReftxProvider
from gtars.vrs.hgvs import hgvs_to_vrs_id
provider = ReftxProvider(ReadonlyTxStore.open("transcripts.reftx"))
vrs_id = hgvs_to_vrs_id("NM_004333.6:c.1799T>A", provider, refget_store, collection_digest)
AttributeTypeDescription
accessionstrFull accession with version
genestr or NoneGene symbol (None if empty)
chromstrChromosome refget accession ("SQ.<digest>")
strandStrandStrand.Plus or Strand.Minus (str() gives "+" or "-")
cds_startint or NoneCDS start position (0-based)
cds_endint or NoneCDS end position (0-based, exclusive)
exonslist[Exon]Exons, each with start and end
maneManeStatus or NoneHas select and plus_clinical flags; None if neither is set

Transcript.to_dict() returns the same data as a plain dict.


The gtars-js WASM package includes a transcript store for the browser. There is no file system in the browser, so you fetch the .reftx bytes yourself and pass them in. Inside, it uses ReadonlyTxStore::from_bytes wrapped in the same TxProvider used on native.

import init, { TranscriptStore, hgvs_to_vrs_id_with_transcripts } from "gtars-js";
await init();
const reftxBytes = new Uint8Array(await (await fetch(reftxUrl)).arrayBuffer());
const tx = new TranscriptStore(reftxBytes); // throws if the bytes are not a valid .reftx
console.log(tx.transcriptCount());
const id = hgvs_to_vrs_id_with_transcripts(
"NM_004333.6:c.1799T>A", "chr7", chr7Bases, tx);
// -> "ga4gh:VA.<digest>"
APIDescription
new TranscriptStore(bytes)Load a store from a Uint8Array holding an uncompressed .reftx file
transcriptCount()Number of transcripts in the store
hgvs_to_vrs_id_with_transcripts(hgvs, sequenceName, sequenceBases, tx)HGVS to VRS ID, resolving c./n. and gene symbols. The bases must be for the chromosome the transcript lies on
RefgetStore.hgvs_to_vrs_id_with_transcripts(hgvs, tx)Same, but reads bases from a RefgetStore that already holds that chromosome

The .reftx file format is a compact binary format built for O(log n) lookups. It is the same for all three backends (memory map, pread, and in-memory bytes).

+------------------------------------------------------------------------------+
| HEADER (40 bytes, fixed) |
+------------------------------------------------------------------------------+
| RECORDS (variable length, starts at byte 40, sorted by accession hash) |
+------------------------------------------------------------------------------+
| ACCESSION INDEX (16 bytes per entry, starts at index_offset) |
+------------------------------------------------------------------------------+
| MANE GENE INDEX (optional, starts at mane_index_offset) |
+------------------------------------------------------------------------------+
OffsetSizeTypeNameDescription
04[u8; 4]magicb"RFTX" (0x52, 0x46, 0x54, 0x58)
44u32 LEversionFormat version (currently 2)
88u64 LErecord_countNumber of transcript records
168u64 LEindex_offsetByte offset to the accession index
248u64 LEmane_index_offsetByte offset to the MANE gene index, or 0 if there is none
328[u8; 8]reservedZero-filled for future use

Each transcript record has the following structure:

OffsetSizeTypeNameDescription
+01u8accession_lenLength of accession string (max 255)
+1N[u8; N]accessionUTF-8 accession string
+N+11u8gene_lenLength of gene symbol (max 255)
+N+2M[u8; M]geneUTF-8 gene symbol
...24[u8; 24]chrom_digestTruncated refget digest
...1i8strand+1 forward, -1 reverse
...1u8mane_flagsbit 0 = MANE Select, bit 1 = MANE Plus Clinical
...4u32 LEcds_start0xFFFFFFFF if None
...4u32 LEcds_end0xFFFFFFFF if None
...2u16 LEexon_countNumber of exons
...8*exons[(u32, u32)]exons(start, end) pairs, LE

Accession Index Format (16 bytes per entry)

Section titled “Accession Index Format (16 bytes per entry)”

The index is sorted by accession_hash in ascending order to enable binary search.

OffsetSizeTypeNameDescription
+08u64 LEaccession_hashFNV-1a hash of accession bytes
+88u64 LErecord_offsetByte offset of record in file

Present only if at least one transcript is MANE Select. It starts with a u64 LE entry count, followed by 16-byte entries sorted by hash:

OffsetSizeTypeNameDescription
+08u64 LEgene_hashFNV-1a hash of the upper-cased gene symbol
+88u64 LErecord_offsetByte offset of the MANE Select record

Both indexes use FNV-1a 64-bit hashing:

const FNV_OFFSET: u64 = 0xcbf29ce484222325;
const FNV_PRIME: u64 = 0x100000001b3;
fn fnv1a_64(data: &[u8]) -> u64 {
let mut hash = FNV_OFFSET;
for &byte in data {
hash ^= byte as u64;
hash = hash.wrapping_mul(FNV_PRIME);
}
hash
}
  • 0xFFFFFFFF (u32 max) indicates None for cds_start and cds_end
  • mane_index_offset = 0 means the file has no MANE gene index
VersionChanges
1Initial format
2Header grows to 40 bytes with mane_index_offset; each record gains a mane_flags byte; optional MANE gene index. Readers accept only version 2

cdot JSON files must be fully parsed and held in memory before any lookup. The binary format avoids that:

  • Read only what you need: With mmap or pread, only the parts of the file you touch are read
  • O(log n) lookup: Binary search on a sorted index
  • Few allocations on hot paths: Small stores are decoded once, and CoordinateMapperWriter reuses its buffers

FNV-1a is simple, fast, and deterministic. Hash collisions are handled by linear probing with full accession string comparison.

A refget sequence digest (sha512t24u) is the first 24 bytes of a SHA-512 hash. The familiar SQ. form is those 24 bytes written as 32 base64url characters. Storing the raw 24 bytes saves space, and encoding them again gives back the exact refget key.

Storing exons directly in each record avoids pointer chasing and keeps related data contiguous for better cache locality.

The lookup code is the same for all of them; only the way bytes are read changes. Positioned reads are the safe default. Memory mapping lets many processes share one copy of a large store in the OS page cache. In-memory bytes need no file system, which is what makes the store work in WASM.