Implement an in-memory database with per-key user locks.
The database stores records by key, and each record maps field names to integer values.
Supported operations:
- SET_BY_USER key field value user -> bool
- If the key is unlocked, or locked by the same user, set the field and return True.
- If the key is locked by another user, do not change anything and return False.
- If the key does not exist, create it.
- GET key field -> integer or None
- Reads are always allowed, even if the key is locked by another user.
- DELETE_BY_USER key field user -> bool
- If the key is unlocked, or locked by the same user, delete the field if it exists.
- Return True only if a field was actually deleted.
- If the key is locked by another user, return False.
- If deleting the last field removes the whole record, its lock must also be removed.
- LOCK key user -> bool
- Return False if the key does not exist.
- Return True if the key exists and is currently unlocked, and lock it for the given user.
- Return False if it is already locked.
- UNLOCK key -> bool
- Return True if the key is currently locked and the lock is removed.
- Return False otherwise.
Return the result of every query in order.
Examples
Input: ([['SET_BY_USER', 'doc', 'x', 10, 'alice'], ['LOCK', 'doc', 'alice'], ['SET_BY_USER', 'doc', 'y', 20, 'bob'], ['GET', 'doc', 'x'], ['SET_BY_USER', 'doc', 'y', 20, 'alice'], ['UNLOCK', 'doc'], ['SET_BY_USER', 'doc', 'y', 30, 'bob'], ['GET', 'doc', 'y']],)
Expected Output: [True, True, False, 10, True, True, True, 30]
Explanation: Only the lock owner may modify a locked key, but reads remain allowed.
Input: ([['SET_BY_USER', 'a', 'x', 1, 'u1'], ['LOCK', 'a', 'u1'], ['DELETE_BY_USER', 'a', 'x', 'u1'], ['UNLOCK', 'a'], ['LOCK', 'a', 'u2'], ['GET', 'a', 'x']],)
Expected Output: [True, True, True, False, False, None]
Explanation: Deleting the last field removes the record and also clears its lock.
Input: ([['LOCK', 'ghost', 'u'], ['DELETE_BY_USER', 'ghost', 'x', 'u'], ['SET_BY_USER', 'k', 'f', 7, 'u1'], ['LOCK', 'k', 'u2'], ['DELETE_BY_USER', 'k', 'f', 'u1'], ['GET', 'k', 'f']],)
Expected Output: [False, False, True, True, False, 7]
Explanation: A lock cannot be created on a missing key, and another user's lock blocks modifications.
Input: ([],)
Expected Output: []
Explanation: Edge case: no queries.