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, "")