Implement a Cloud Storage Service
The Trade DeskSoftware Engineer · Online AssessmentLast 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
trueif the file was added. -
Return
falseif 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
trueif the copy succeeds. -
Return
falseif 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
Noneif the file does not exist.
Level 2: File search
Implement:
find_file(prefix: str, suffix: str) -> list[str]- Return all files whose names start with
prefixand end withsuffix. - 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 examplelogs/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
trueif the user was added. -
Return
falseif 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
Noneif 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
falseif 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
Noneif 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
namewith a compressed file namedname.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
Noneif 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
.COMPRESSEDsuffix. -
The decompressed size is
2 * compressed_size. -
Return
Noneif 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.
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.