src/LogicalKey.bend
ber-core-store@0.1.1.0 · 56 lines · 0 definitions
1import Base
2
3# Logical keys and the physical MyLSM key layout. All keys are ASCII with
4# "/" separators so prefix scan stays possible at the storage layer.
5type LogicalKey is Data:
6 Make{namespace_name: String, record_identifier: String}
7
8# Renders a key as "namespace/record".
9def encode_logical_key(logical_key: LogicalKey) -> String:
10 match logical_key:
11 case Make{namespace_name, record_identifier}:
12 namespace_name ++ "/" ++ record_identifier
13
14# Addresses a content-addressed object by its hash.
15def build_object_storage_key(content_hash: String) -> String:
16 "object/" ++ content_hash
17
18# Addresses a persisted state tree by its hash.
19def build_tree_storage_key(tree_hash_value: String) -> String:
20 "tree/" ++ tree_hash_value
21
22# Addresses a persisted commit by its identifier.
23def build_commit_storage_key(commit_identifier: String) -> String:
24 "commit/" ++ commit_identifier
25
26# Addresses one versioned index entry: value hash or TOMBSTONE.
27def build_index_storage_key(namespace_name: String, record_identifier: String, commit_identifier: String) -> String:
28 "index/" ++ namespace_name ++ "/" ++ record_identifier ++ "/" ++ commit_identifier
29
30# Addresses one uncommitted staged value.
31def build_stage_storage_key(session_identifier: String, namespace_name: String, record_identifier: String) -> String:
32 "stage/" ++ session_identifier ++ "/" ++ namespace_name ++ "/" ++ record_identifier
33
34# Same version-index layout for callers holding "namespace/record" as one string.
35def build_version_index_key(combined_key: String, commit_identifier: String) -> String:
36 "index/" ++ combined_key ++ "/" ++ commit_identifier
37
38# Same stage layout for callers holding "namespace/record" as one string.
39def build_stage_storage_key_combined(session_identifier: String, combined_key: String) -> String:
40 "stage/" ++ session_identifier ++ "/" ++ combined_key
41
42# Scans for the first "/"; the head match is on a pattern-bound variable.
43def split_scan(remaining_text: String, namespace_accum: String) -> LogicalKey:
44 match remaining_text:
45 case SNil{}:
46 Make{namespace_accum, ""}
47 case SCon{head_char, remaining_chars}:
48 match head_char:
49 case '/':
50 Make{namespace_accum, remaining_chars}
51 case _:
52 split_scan(remaining_chars, String.append(namespace_accum, SCon{head_char, SNil{}}))
53
54# Inverse of encode_logical_key: splits at the FIRST "/".
55def split_combined_key(combined_key: String) -> LogicalKey:
56 split_scan(combined_key, "")