FastPrepIn-Memory Database with Historical Field Lookup
Problem · Design

In-Memory Database with Historical Field Lookup

Learn this problem
HardMeta logoMetaFULLTIMEOA
See Meta hiring insights

Problem statement

Maintain an initially empty in-memory database addressed by a pair (key, field). Process operations in their given order. Every row has string arguments, and operation timestamps t are strictly increasing.

  • ["SET", t, key, field, value, ttl]: write the nonnegative integer value. A positive TTL makes it visible on [t, t + ttl); a TTL of zero means it does not expire automatically. An overwrite immediately ends the previous version, even if the new value later expires.
  • ["DELETE", t, key, field]: remove the current value, if one exists. It is absent from t onward until another set. Deleting an absent or expired field is a no-op.
  • ["GET", t, key, field]: return the value visible at the current time t.
  • ["GET_WHEN", t, key, field, at]: return the value that was visible at historical time at, where 0 <= at <= t.

Return one string per GET or GET_WHEN, in query order: the decimal value, or the exact string "NULL" if the field was absent. Sets and deletes produce no output.

Overwriting or deleting a field does not erase its earlier history. A version ends at the earliest of its expiration, the next overwrite, or the next deletion. The start is inclusive and the end is exclusive. Once a version ends, it never reappears. Different key-and-field pairs are independent.

A historical query is read-only; it does not roll back the database or change later queries. Historical time 0 means the actual timestamp zero. All numeric strings are canonical nonnegative decimal integers with no leading zeros except "0".

Function

historicalFieldValues(operations: String[][]) → String[]

Examples

Example 1

operations = [["SET","1","a","x","10","0"],["SET","5","a","x","20","5"],["GET_WHEN","6","a","x","2"],["GET_WHEN","7","a","x","5"],["GET","10","a","x"],["GET_WHEN","11","a","x","9"],["DELETE","12","a","x"],["GET_WHEN","13","a","x","4"]]return = ["10","20","NULL","20","10"]

The first version is valid on [1,5) and the second on [5,10). The current read at time 10 is absent, while historical reads at 9 and 4 still recover their respective values.

Example 2

operations = [["SET","0","a","x","7","0"],["SET","2","a","y","8","0"],["DELETE","4","a","x"],["GET_WHEN","5","a","x","3"],["GET","6","a","x"],["GET","7","a","y"],["GET_WHEN","8","a","y","0"]]return = ["7","NULL","8","NULL"]

Deleting field x does not affect field y or erase the earlier value of x. Field y did not exist at historical time zero.

Constraints

  • 0 <= operations.length <= 200.
  • Every row has exactly the arguments specified by its operation name.
  • 0 <= t, value, ttl <= 1000000000; operation timestamps are strictly increasing.
  • Every historical time satisfies 0 <= at <= t.
  • Keys and fields each contain 1 through 10 lowercase English letters.
  • Expiration times may exceed the maximum operation timestamp, so use a sufficiently wide integer type.

More Meta problems

drafts saved locally
public String[] historicalFieldValues(String[][] operations) {
    // Write your code here
}
operations[["SET","1","a","x","10","0"],["SET","5","a","x","20","5"],["GET_WHEN","6","a","x","2"],["GET_WHEN","7","a","x","5"],["GET","10","a","x"],["GET_WHEN","11","a","x","9"],["DELETE","12","a","x"],["GET_WHEN","13","a","x","4"]]
expected["10", "20", "NULL", "20", "10"]
checking account