Katkat

Implement a Cloud Storage Service

The Trade DeskSoftware Engineer · Online Assessment

Last updated

This question evaluates a candidate's ability to implement an in-memory cloud storage system, exercising skills in data structures and stateful API design, string handling and pattern matching, sorting and eviction algorithms, and per-user resource accounting.

Implement an in-memory cloud storage system. Build the class incrementally; later levels must preserve all behavior from earlier levels. File names are globally unique strings, and file sizes are non-negative integers. If an operation cannot be completed, return the failure value specified for that method.

Level 1: Basic file operations

Implement:

  • add_file(name: str, size: int) -> bool

  • Add a new file with the given name and size.

  • Return true if the file was added.

  • Return false if a file with the same name already exists.

  • copy_file(name_from: str, name_to: str) -> bool

  • Copy an existing file to a new file name.

  • Return true if the copy succeeds.

  • Return false if the source file does not exist or the destination file already exists.

  • get_file_size(name: str) -> int | None

  • Return the file size if the file exists.

  • Return None if the file does not exist.

Implement:

  • find_file(prefix: str, suffix: str) -> list[str]
  • Return all files whose names start with prefix and end with suffix.
  • Sort results by file size in descending order.
  • If two files have the same size, sort them by file name in lexicographically ascending order.
  • Format each result as name(size), for example logs/a.txt(120).

Level 3: Users and capacity limits

The system has users. Each user has a storage capacity and current usage. There is also a built-in admin user with unlimited capacity. Calls to add_file from Level 1 should behave as if the admin user added the file.

Implement:

  • add_user(user_id: str, capacity: int) -> bool

  • Add a user with the given capacity and zero initial usage.

  • Return true if the user was added.

  • Return false if the user already exists.

  • add_file_by(user_id: str, name: str, size: int) -> int | None

  • Add a file owned by user_id.

  • Return the user's remaining capacity after adding the file.

  • Return None if the user does not exist, the file name already exists, or adding the file would exceed the user's capacity.

  • Update copy_file(name_from: str, name_to: str) -> bool

  • The copied file must have the same owner as the source file.

  • The copy consumes additional capacity from that owner.

  • Return false if the owner would exceed their capacity.

  • update_capacity(user_id: str, capacity: int) -> int | None

  • Set the user's capacity to the new value.

  • If the user's current usage exceeds the new capacity, remove that user's files until usage is less than or equal to the capacity.

  • Remove files in order of largest size first; for ties, remove lexicographically smaller file names first.

  • Return the number of removed files.

  • Return None if the user does not exist.

Level 4: Compression and decompression

Compressed files use the suffix .COMPRESSED.

Implement:

  • compress_file(user_id: str, name: str) -> int | None

  • The file must exist and be owned by user_id.

  • Replace the file named name with a compressed file named name.COMPRESSED.

  • The compressed file has size floor(original_size / 2) and the same owner.

  • Update the user's usage accordingly.

  • Return the user's remaining capacity.

  • Return None if the file does not exist, is not owned by the user, or the compressed destination name already exists.

  • decompress_file(user_id: str, name: str) -> int | None

  • The file must exist, be owned by user_id, and have the suffix .COMPRESSED.

  • Replace it with the original file name obtained by removing the .COMPRESSED suffix.

  • The decompressed size is 2 * compressed_size.

  • Return None if the original file name already exists or decompression would exceed the user's capacity.

  • Otherwise, update the user's usage and return the user's remaining capacity.