Durable String Key-Value Store
Learn this problemProblem statement
Implement a durable string key-value store by processing an ordered array of commands. The store starts with an empty in-memory map and an empty durable log file.
Each command produces exactly one string result:
["PUT", key, value]: atomically storevalueunderkey, overwriting any earlier value, and append one durable log record for this write. ReturnOK.["GET", key]: returnVALUE:followed by the current value, orNOT_FOUNDwhen the key is absent.["SERIALIZE"]: return one deterministic snapshot of the current map.["DESERIALIZE", snapshot]: replace the current map withsnapshot, rewrite the durable log to represent exactly that loaded state, and returnOK.["RECOVER"]: discard the in-memory map, replay the complete durable log in order, and returnOK.
Record and Snapshot Format
Encode one key/value pair as <keyLength>:<key><valueLength>:<value>, where each length is a base-10 integer and the key and value follow their lengths without extra separators. For example, key user with value bob becomes 4:user3:bob. Length prefixes allow keys and values to contain digits and colons.
Every PUT appends one record in that format to the log. Recovery replays records from first to last, so later records for the same key win. A snapshot concatenates one record for each current key in lexicographic key order; the empty map serializes to the empty string. Every DESERIALIZE input is a valid snapshot produced by this format. Deserialization replaces both memory and the log, recording the decoded pairs in snapshot order so a later recovery reconstructs the loaded state.
Return the result of every command in the same order as operations.
Function
processStore(operations: String[][]) → String[]Examples
Example 1
operations = [["PUT","user","alice"],["GET","user"],["PUT","user","bob"],["RECOVER"],["GET","user"],["SERIALIZE"]]return = ["OK","VALUE:alice","OK","OK","VALUE:bob","4:user3:bob"]The second PUT overwrites the in-memory value and appends a later log record. Recovery replays both records, so the later value bob wins. The final snapshot contains the one current pair.
Example 2
operations = [["PUT","b","two"],["PUT","a","one"],["SERIALIZE"],["DESERIALIZE","1:a3:one1:c5:three"],["GET","b"],["GET","c"],["RECOVER"],["SERIALIZE"]]return = ["OK","OK","1:a3:one1:b3:two","OK","NOT_FOUND","VALUE:three","OK","1:a3:one1:c5:three"]Serialization sorts keys, so a precedes b. Deserialization replaces the old state, making b absent, and rewrites the log so recovery preserves exactly the loaded a and c pairs.
Example 3
operations = [["PUT","x:y",""],["SERIALIZE"],["RECOVER"],["GET","x:y"],["GET","missing"]]return = ["OK","3:x:y0:","OK","VALUE:","NOT_FOUND"]The length-prefixed format safely stores a colon in the key and an empty value. The tagged VALUE: result distinguishes that stored empty value from a missing key.
Constraints
1 <= operations.length <= 2000- Each command has exactly the fields described above.
1 <= key.length <= 100.0 <= value.length <= 1000.- Keys and values contain printable ASCII characters.
- Every
snapshotpassed toDESERIALIZEis a valid output of the specified snapshot format. - The total number of characters across all commands is at most
2 * 10^5.