1 import 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. 5 type LogicalKey is Data: 6 Make{namespace_name: String, record_identifier: String} 7 8 # Renders a key as "namespace/record". 9 def 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. 15 def build_object_storage_key(content_hash: String) -> String: 16 "object/" ++ content_hash 17 18 # Addresses a persisted state tree by its hash. 19 def build_tree_storage_key(tree_hash_value: String) -> String: 20 "tree/" ++ tree_hash_value 21 22 # Addresses a persisted commit by its identifier. 23 def build_commit_storage_key(commit_identifier: String) -> String: 24 "commit/" ++ commit_identifier 25 26 # Addresses one versioned index entry: value hash or TOMBSTONE. 27 def 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. 31 def 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. 35 def 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. 39 def 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. 43 def 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 "/". 55 def split_combined_key(combined_key: String) -> LogicalKey: 56 split_scan(combined_key, "")