# GLX specification changelog

> Changes to the .glx version 1 specification, release by release.

> Generated from `spec/v1/CHANGELOG.md` in the geolith/glx repository at commit `561a984`.

## 1.0.3

A routing part may hold a customizable contraction hierarchy per costing
profile (10.5). Routing parts without one are unchanged.

- Feature bit `0` (`CCH`): the routing header grows to 80 bytes with the
  CCH directory's (offset, length); the directory ends the boot span.
- Per profile, three blocked sections after the tiles: the vertex map
  (edge to ranks and ancestor runs), the records (kept up and down
  directions with weights in 0.1 cost units) and the road lists.

The routing part's layout changes; this is still version 1 (magic
`GLX0`, version `1`). Routing parts written to 1.0.2 do not read:
rebuild them. Search parts are unchanged.

- Graph tiles are stored as fixed-size blocks, each its own zstd frame,
  behind a per-tile block directory, so a reader fetches and holds only
  the blocks a route touches (10.2, 10.3).
- The routing header's former reserved field at offset `4` is the block
  size, a power of two from 4 KiB to 16 MiB; the reference writer uses
  64 KiB (10.4).
- Tile index entries grow to 16 bytes: key, tile length, first frame
  length, stored length.
- Chapter 10.4 records the Berlin measurements behind the block size.

## 1.0.2

The file layout changes; this is still version 1 (magic `GLX0`, version
`1`). Files written to 1.0 or 1.0.1 do not read: rebuild them. A reader
for 1.0.2 refuses them, because their old header does not hold a valid
part table.

- Every file starts with a 256-byte file header with a part table of up to
  seven entries: kind, offset, length and XXH3-64 checksum (2.6).
- The search data is the search part, kind `SRCH`. Its 256-byte header and
  sections are the former file layout; every offset in it now counts from
  the start of the part (Chapter 3).
- A routing part, kind `ROUT`, holds road graph tiles as separate zstd
  frames with a tile index and an optional dictionary (Chapter 10).
- A reader for one kind of part refuses a file that holds no part of that
  kind, and ignores parts of other kinds.
- A tool that copies a part between files checks its checksum; the parts of
  several files merge into one file by copying each part's bytes unchanged.

## 1.0.1

The file layout is unchanged: header version `1`, magic `GLX0`, and every
file written to 1.0 reads the same.

- Readers MUST refuse a file that sets a reserved feature bit (`17` to
  `31`), rather than MAY ignore it. A bit a later revision adds is thus
  refused by older readers, required or optional.
- Readers MUST refuse a term entry of a reserved kind (above `2`), rather
  than SHOULD.
- Readers MUST refuse a header whose document count exceeds `2^32 - 1`.
- Latitudes clamp to ±90 degrees in the fixed-point encoding; longitudes
  still clamp to ±180. Real latitudes lie within ±90, so written files
  do not change.
- The magic and the version field are explained: the magic names the
  format and stays `GLX0`; the version field names the specification.
- Feature bits `8` and `9` are stated to be set even when their sections
  are empty.

## 1.0

Initial version of the GLX format: header version `1`, magic `GLX0`.

- A 256-byte header with thirteen sections: term index, spatial directory,
  document index, chunks, dictionary, postings, documents, spatial, id
  directory, ids, shape directory, shapes and record dictionary.
- Required feature bits `0` to `14` (`0x7FFF`): `NAME_TEXT`,
  `DISTINCT_WORDS`, `SCRIPT_FOLD`, `WRITTEN_LENGTH`, `UNPLACED_POSTINGS`,
  `UNSIGNED_POSTINGS`, `COLUMNAR_RECORDS`, `DELTA_SPATIAL`, `SHAPES`,
  `RECORD_DICTIONARY`, `ID_FINGERPRINTS`, `MICRODEGREES`, `PLACE_DETAILS`,
  `APOSTROPHE_WORDS`, `CJK_PAIRS`.
- Optional feature bits:
  - bit `15` (`0x08000`) `SHORT_PREFIX_LISTS`: prefixes of 2 to 6
    characters all have posting lists and dictionary blocks are cut at
    32 KiB. Clear: prefixes of 2 and 3 characters have head lists only.
  - bit `16` (`0x10000`) `COMPACT_DOC_INDEX`: the document index keeps an
    offset every 64 blocks and a 16-bit length per block. Clear: one `u64`
    offset per block.
