Problem · Hash Table

In-Memory File System

Learn this problem
HardAirbnb logoAirbnbFULLTIMEOA

Problem statement

Implement an in-memory file system that processes a finite ordered batch of operations. Each file has a unique path, a current stored size, an owner, and a compression state. Each non-admin user has a storage capacity equal to the maximum sum of the current stored sizes of files they own. The built-in user "admin" exists before processing begins and has unlimited capacity.

The input operations contains one string array per operation. Return one string for every operation, in the same order.

Supported operations
Operation rowBehaviorReturned string
["ADD_USER", userId, capacity]Add a non-admin user with the given nonnegative capacity. The operation fails if the ID is empty, is "admin", or already exists."true" on success; otherwise "false".
["ADD_FILE", userId, path, size]Add an uncompressed file owned by an existing user. The path must be absent, the size must be positive, the path must not end in ".COMPRESSED", and a non-admin owner must have enough remaining capacity."true" on success; otherwise "false".
["COPY_FILE", sourcePath, destinationPath]Copy an existing file to an absent path. The copy keeps the source owner, current size, compression state, and original size. The owner must have enough remaining capacity. The destination ends in ".COMPRESSED" exactly when the source is compressed."true" on success; otherwise "false".
["FIND_FILES", prefix, suffix]Find every current file path that starts with prefix and ends with suffix. Order matches by current size descending, then by path lexicographically ascending. Format each match as path(size) and join matches with ", ".The joined matches, or the empty string when none match.
["COMPRESS_FILE", userId, path]Compress an existing uncompressed file owned by userId. Rename it to path + ".COMPRESSED", which must be absent, and change its stored size from s to ceil(s / 2). Remember s as its original size."true" on success; otherwise "false".
["DECOMPRESS_FILE", userId, compressedPath]Decompress an existing compressed file owned by userId. Its path must end in ".COMPRESSED". Rename it by removing that final suffix and restore its original size. The restored path must be absent, and a non-admin owner must have enough capacity for the increase."true" on success; otherwise "false".

A failed mutation leaves all state unchanged. Repeating an already-applied mutation therefore fails unless the required source and destination state exists again later.

Function

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

Examples

Example 1

operations = [["ADD_USER","alice","10"],["ADD_FILE","alice","/docs/a.txt","7"],["COPY_FILE","/docs/a.txt","/docs/b.txt"],["COMPRESS_FILE","alice","/docs/a.txt"],["COPY_FILE","/docs/a.txt.COMPRESSED","/docs/b.txt.COMPRESSED"],["FIND_FILES","/docs/",".COMPRESSED"],["DECOMPRESS_FILE","alice","/docs/a.txt.COMPRESSED"]]return = ["true","true","false","true","true","/docs/a.txt.COMPRESSED(4), /docs/b.txt.COMPRESSED(4)","false"]

The first copy would exceed Alice's capacity. Compressing the 7-unit file uses 4 units, so its compressed copy fits. The two equal-size matches use path order. Decompressing either copy would raise total usage from 8 to 11, so the final operation fails without changing state.

Example 2

operations = [["ADD_FILE","admin","/odd.txt","5"],["COMPRESS_FILE","admin","/odd.txt"],["FIND_FILES","/",".COMPRESSED"],["DECOMPRESS_FILE","admin","/odd.txt.COMPRESSED"],["FIND_FILES","/",".txt"]]return = ["true","true","/odd.txt.COMPRESSED(3)","true","/odd.txt(5)"]

Compression rounds the odd size up from 5 to 3. The admin account has unlimited capacity, and decompression restores both the original path and size.

Example 3

operations = [["ADD_USER","dev","30"],["ADD_FILE","dev","/src/z.log","3"],["ADD_FILE","dev","/src/b.log","8"],["ADD_FILE","dev","/src/a.log","8"],["FIND_FILES","/src/",".log"],["FIND_FILES","/tmp/",".log"]]return = ["true","true","true","true","/src/a.log(8), /src/b.log(8), /src/z.log(3)",""]

Larger files appear first. Equal-size files use lexicographic path order, and a search with no matches returns the empty string.

Constraints

  • 1 <= operations.length <= 100000.
  • Every row uses one of the six documented operation shapes and contains valid decimal integer text where required.
  • User IDs and file paths contain between 1 and 100 characters.
  • 0 <= capacity <= 10^18.
  • 1 <= size <= 10^9.
  • The sum of all stored sizes fits in a signed 64-bit integer.

More Airbnb problems

drafts saved locally
public String[] processFileSystem(String[][] operations) {
    // Write your code here.
}
operations[["ADD_USER","alice","10"],["ADD_FILE","alice","/docs/a.txt","7"],["COPY_FILE","/docs/a.txt","/docs/b.txt"],["COMPRESS_FILE","alice","/docs/a.txt"],["COPY_FILE","/docs/a.txt.COMPRESSED","/docs/b.txt.COMPRESSED"],["FIND_FILES","/docs/",".COMPRESSED"],["DECOMPRESS_FILE","alice","/docs/a.txt.COMPRESSED"]]
expected["true", "true", "false", "true", "true", "/docs/a.txt.COMPRESSED(4)", "/docs/b.txt.COMPRESSED(4)", "false"]
checking account