Cloud Storage with User Backup and Restore
Learn this problemProblem statement
Implement an in-memory cloud-storage service. The service stores file metadata only: each file has a unique name, a positive size, and an owner. It does not store file contents. Process one finite ordered batch from empty storage and return one string result per operation.
An implicit user named admin always exists and has unlimited capacity. Files added with ADD_FILE belong to admin. File and directory collision behavior is outside this task; treat every file name as an opaque string.
Each operation is one of the following:
["ADD_FILE", name, size]: add an admin-owned file if the name is unused. Return"true"on success or"false"otherwise.["GET_FILE_SIZE", name]: return the file size in decimal, or the empty string if the file does not exist.["DELETE_FILE", name]: delete the file and return its size in decimal, or the empty string if it does not exist. Deleting a user-owned file frees that user's capacity.["GET_N_LARGEST", prefix, n]: consider file names that start withprefix, sort them by size descending and then name ascending, and return at mostnentries joined by", ". Format each entry asname(size). Return the empty string when there are no matches.["ADD_USER", userId, capacity]: create a capacity-limited non-admin user. Return"true"if the user was created, or"false"if the ID isadminor already exists.["ADD_FILE_BY", userId, name, size]: add a file owned by an existing non-admin user if the name is unused and the user's used capacity plussizedoes not exceed the user's total capacity. Return the user's remaining capacity after success, or the empty string on failure.["MERGE_USER", userId1, userId2]: if both IDs name distinct existing non-admin users, transfer every file owned byuserId2touserId1, adduserId2's total capacity touserId1's total capacity, removeuserId2, and returnuserId1's remaining capacity. Otherwise return the empty string. The surviving user's prior backup is unchanged, and the removed user's backup is discarded.["BACKUP_USER", userId]: if the user exists, replace that user's prior backup with a snapshot of the names and sizes of all files currently owned by the user. The snapshot is unaffected by later storage changes. Return the number of snapshotted files. Return the empty string for a missing user.["RESTORE_USER", userId]: return the empty string for a missing user. Otherwise delete every file currently owned by that user. If the user has no backup, return"0". If a backup exists, recreate every snapshotted file whose name is not currently owned by another user; ignore conflicting names. Restored files belong touserId. Return the number of files restored.
Apply each mutation before processing the next operation. All integer results use ordinary decimal notation.
Function
processCloudStorage(operations: String[][]) → String[]Examples
Example 1
operations = [["ADD_FILE","/a.txt","10"],["ADD_FILE","/logs/z.log","7"],["ADD_FILE","/logs/a.log","7"],["GET_FILE_SIZE","/a.txt"],["GET_N_LARGEST","/","2"],["DELETE_FILE","/a.txt"],["GET_FILE_SIZE","/a.txt"]]return = ["true","true","true","10","/a.txt(10), /logs/a.log(7)","10",""]The size query sees the first file. The ranking puts the 10-unit file first and breaks the 7-unit tie by name. After deletion, querying that name returns the empty string.
Example 2
operations = [["ADD_USER","alice","20"],["ADD_USER","bob","15"],["ADD_FILE_BY","alice","/a","12"],["ADD_FILE_BY","bob","/b","10"],["ADD_FILE_BY","bob","/c","6"],["MERGE_USER","alice","bob"],["ADD_FILE_BY","alice","/c","13"],["BACKUP_USER","alice"],["DELETE_FILE","/b"],["RESTORE_USER","alice"],["GET_N_LARGEST","/","3"]]return = ["true","true","8","5","","13","0","3","10","3","/c(13), /a(12), /b(10)"]Bob cannot add a 6-unit file before the merge. Merging gives Alice 35 units of total capacity and 13 units remaining. Her backup preserves all three files, so restore recreates the deleted 10-unit file.
Example 3
operations = [["ADD_USER","u","20"],["ADD_FILE_BY","u","/keep","8"],["ADD_FILE_BY","u","/conflict","5"],["BACKUP_USER","u"],["DELETE_FILE","/conflict"],["DELETE_FILE","/keep"],["ADD_FILE","/conflict","9"],["ADD_FILE_BY","u","/new","6"],["RESTORE_USER","u"],["GET_FILE_SIZE","/new"],["GET_FILE_SIZE","/keep"],["BACKUP_USER","admin"],["DELETE_FILE","/conflict"],["ADD_FILE","/temp","3"],["RESTORE_USER","admin"],["GET_FILE_SIZE","/temp"],["ADD_USER","v","4"],["ADD_FILE_BY","v","/v","4"],["RESTORE_USER","v"],["GET_FILE_SIZE","/v"]]return = ["true","12","7","2","5","8","true","14","1","","8","1","9","true","1","","true","0","0",""]User u restores /keep but skips /conflict because admin owns that name. Admin's backup later replaces /temp with the saved conflict file. User v has no backup, so restore deletes /v and returns zero.
Constraints
1 <= operations.length <= 2000.- Each operation has exactly the arity shown in the statement and uses one of the listed operation names.
- File names and user IDs are nonempty printable ASCII strings of length at most
100. - A prefix is a printable ASCII string of length at most
100and may be empty. - Every supplied file size is an integer in
[1, 10^9]. - Every supplied capacity is an integer in
[1, 10^18]. - Every supplied
nis an integer in[1, 2000]. - At most
2000files are live after any operation. - All capacities, used-space totals, remaining-capacity values, and merged capacities fit in a signed 64-bit integer.