Katkat

Implement an In-Memory File Storage System

InstacartSoftware Engineer · Online Assessment

Last updated

This question evaluates the ability to design and implement efficient in-memory data structures and algorithms for stateful file management, covering string-keyed storage, size accounting, querying and sorting, and user quota enforcement.

Implement an in-memory file storage service.

You need to support files identified by a unique full path string, such as "/docs/a.txt". Each file has an integer size and is owned either by the built-in admin user or by a normal user. Directories do not need to be stored separately; treat paths as plain strings.

Design a class that supports the following operations:

  1. addFile(name: string, size: int) -> bool
  • Adds a new admin-owned file with path name and file size size.
  • Return true if the file did not already exist and was added.
  • Return false if a file with the same name already exists.
  1. copyFile(source: string, destination: string) -> bool
  • Copies the file at source to a new path destination.
  • The copied file has the same size and owner as the source file.
  • Return true if source exists and destination does not already exist.
  • Return false otherwise.
  1. getFileSize(name: string) -> int
  • Return the size of the file named name.
  • Return -1 if the file does not exist.
  1. findFiles(prefix: string, suffix: string) -> list[string]
  • Return all files whose names start with prefix and end with suffix.
  • Each result should be formatted as "<name>(<size>)", for example "/docs/a.txt(120)".
  • Sort results by size in descending order. If two files have the same size, sort by file name in lexicographical order.
  1. addUser(userId: string, capacity: int) -> bool
  • Adds a new user with maximum storage capacity capacity.
  • Return true if the user did not already exist.
  • Return false otherwise.
  1. addFileByUser(userId: string, name: string, size: int) -> int
  • Adds a new file owned by userId.
  • The file can be added only if the user exists, the file name does not already exist, and the user's used storage plus size does not exceed their capacity.
  • Return the user's remaining capacity after the file is added.
  • Return -1 if the operation fails.
  1. updateUserCapacity(userId: string, newCapacity: int) -> int
  • Updates the capacity of an existing user.
  • If the user's current used storage exceeds newCapacity, remove that user's files until their used storage is at most newCapacity.
  • When removing files, remove the largest files first; if there is a tie, remove the lexicographically largest file name first.
  • Return the number of files removed.
  • Return -1 if the user does not exist.

Assume all operations are performed in memory. Choose appropriate data structures and implement the APIs efficiently.