Segmented Durable Key-Value Store
Problem statement
Simulate an in-memory string key-value store with a durable snapshot represented by ordered byte chunks. Process operations in order and return one string per operation. Initially the store is running, its map is empty and its durable chunk list is empty.
Operations
["PUT", key, value]: while running, store or overwrite the value and returnOK.["GET", key]: while running, returnVALUE:followed by its value, orNOT_FOUND.["SHUTDOWN"]: while running, replace the durable snapshot with the current map using the byte format below, split its bytes into consecutive chunks of at mostchunkSizebytes, and stop the store. ReturnCHUNKS:followed by the lowercase hexadecimal encoding of each chunk, joined by commas. An empty snapshot returnsCHUNKS:.["RESTART"]: concatenate the durable chunks in order before parsing, replace the volatile map with the decoded snapshot, set the store to running, and returnOK. Any unsaved volatile changes are discarded. This operation also works when the store is already running.
When stopped, PUT, GET and SHUTDOWN return OFFLINE without changing either map or disk. No operation changes the durable chunks except a successful shutdown.
Byte format and chunk boundaries
Keys and values contain printable ASCII, so each character occupies one byte. Visit current keys in ascending ASCII lexical order. For each key, append its length as four unsigned bytes in big-endian order, then its key bytes, then the value length in the same format, then its value bytes. Concatenate these records without a record count or separator. The empty map has zero bytes.
Split that complete byte sequence every chunkSize bytes. A boundary may occur inside a four-byte length, key or value; no record padding is added. Hexadecimal is only the returned display representation: chunk capacity is measured in original bytes. For key a and value x, the snapshot bytes display as 00000001610000000178.
For this exercise, assume a finite sequential operation adapter, valid internally generated snapshots, printable ASCII data and the lifecycle and deterministic ordering above. Standard byte-conversion utilities may be used; the focus is reversible framing, persistence and chunk boundaries. No actual filesystem calls are required: the durable chunk list models the reported disk writes.
Supplied storage interfaces and metadata
The reports describe supplied storage interfaces and a follow-up that splits data across bounded files while maintaining a metadata file. The ordered durable chunk list models that catalog: each entry identifies one chunk and its used-byte count, and restart reads entries in order. Catalog storage is outside the data-chunk size limit and is not part of the returned snapshot bytes. A chunk size of 1024 models the earlier one-kibibyte file limit; this exercise makes the supplied limit a parameter.
Thread-safety discussion
Explain how concurrent access would affect the in-memory map, a shutdown snapshot and restart. The judged operation sequence remains sequential; concurrent execution and partial-write crash recovery are outside this practice contract.
Function
runSegmentedStore(operations: String[][], chunkSize: int) → String[]Examples
Example 1
operations = [["PUT","a","x"],["SHUTDOWN"],["GET","a"],["RESTART"],["GET","a"]]chunkSize = 5return = ["OK","CHUNKS:0000000161,0000000178","OFFLINE","OK","VALUE:x"]A five-byte boundary falls between the key and value length. Restart concatenates both chunks and recovers the saved value.
Example 2
operations = [["PUT","a",""],["PUT","a","z"],["RESTART"],["GET","a"],["SHUTDOWN"]]chunkSize = 1return = ["OK","OK","OK","NOT_FOUND","CHUNKS:"]Restart before a successful shutdown reloads the initially empty durable snapshot and discards unsaved changes.
Example 3
operations = [["PUT","b","2"],["PUT","a","1"],["SHUTDOWN"],["RESTART"],["PUT","a","9"],["RESTART"],["GET","a"]]chunkSize = 10return = ["OK","OK","CHUNKS:00000001610000000131,00000001620000000132","OK","OK","OK","VALUE:1"]The snapshot sorts keys, and a restart discards later unsaved edits.
Constraints
1 <= operations.length <= 1000.1 <= chunkSize <= 4096.- Every operation has one of the documented shapes.
- Keys contain
1to50printable ASCII characters; values contain0to500printable ASCII characters. - The total length of all key and value arguments is at most
20000. - For this exercise, assume the sum of serialized snapshot byte counts across successful shutdowns is at most
100000.