Skip to content

Commit 5ba50ea

Browse files
committed
Convert JSTable to compact binary format using jsonb
1 parent bcd2af1 commit 5ba50ea

5 files changed

Lines changed: 184 additions & 77 deletions

File tree

Cargo.lock

Lines changed: 108 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ serde = { version = "1.0", features = ["derive"] }
1010
serde_json = "1.0"
1111
uuid = { version = "1.8.0", features = ["v7", "serde"] }
1212
chrono = { version = "0.4.38", features = ["serde"] }
13+
jsonb = "0.5.5"
1314

1415
[dev-dependencies]
1516
tempfile = "3.10.1"

specs/storage.md

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,25 @@ A JSTable is like an SSTable, but stores semi-structured JSON data with an assoc
33

44
# Disk format
55

6-
Each JSTable is stored in a single file.
7-
This file must contain a JSON Schema as well as all the associated documents.
8-
9-
The format is as follows:
10-
1. A JSON object containing metadata about the table. It must include:
11-
* `timestamp`: The time the table was created, as a Unix timestamp in milliseconds.
12-
* `schema`: The JSON Schema for the documents in the table.
13-
2. A sequence of records, one per line. Each record is a JSON array `[id, document]`.
14-
15-
Example:
16-
```
17-
{"timestamp": 1686776400000, "schema": {"type":"object","properties":{"a":{"type":["integer"]}}}}
18-
["01H4J3J4J3J4J3J4J3J4J3J4J3", {"a": 1}]
19-
["01H4J3J4J3J4J3J4J3J4J3J4J4", {"a": 2}]
20-
["01H4J3J4J3J4J3J4J3J4J3J4J5", null]
21-
```
6+
Each JSTable is stored in a single binary file using the [JSONB](https://github.com/databendlabs/jsonb) format.
7+
The file consists of a sequence of entries. Each entry is encoded as:
8+
1. **Length**: A 4-byte unsigned integer (little-endian) indicating the size of the following JSONB blob.
9+
2. **Data**: A binary blob encoded using the JSONB format.
10+
11+
## Structure
12+
13+
1. **Header Entry**: The first entry in the file. It is a JSONB-encoded object containing:
14+
* `timestamp`: The time the table was created (Unix timestamp in milliseconds).
15+
* `schema`: The JSON Schema for the documents.
16+
2. **Record Entries**: All subsequent entries. Each is a JSONB-encoded array `[id, document]`:
17+
* `id`: String.
18+
* `document`: The document object (or `null` for tombstone).
2219

2320
## Compression
2421

25-
Documents are stored as full JSON objects. This means that no compression is currently applied.
22+
Documents are stored using the JSONB binary format, which is generally more compact than text JSON.
2623
A document can be `null` to indicate that it has been deleted.
27-
Future versions of the format might include schema-based compression. For example, if a field must be an integer, the type information need not be stored with each document. If a field can have multiple possible types, then the type information must be stored with each document.
24+
Future versions might include schema-based compression.
2825

2926

3027
# Compaction

src/db.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ mod tests {
136136
assert_eq!(db.jstable_count, 1);
137137

138138
let jstable_path = format!("{}/jstable-0", dir.path().to_str().unwrap());
139-
let content = std::fs::read_to_string(jstable_path).unwrap();
140-
assert!(!content.is_empty());
139+
// Verify it is a valid JSTable
140+
let table = jstable::read_jstable(&jstable_path).unwrap();
141+
assert_eq!(table.documents.len(), MEMTABLE_THRESHOLD);
141142
}
142143

143144
#[test]

0 commit comments

Comments
 (0)