File Storage System
Ye problem COMPOSITE pattern ke liye poochi jaati hai. Ek abstract FileSystemNode ho, jise File (leaf) aur Directory (composite) extend karein. Directory ke andar FileSystemNode ki list hoti hai — isliye nesting apne aap kaam karti hai aur getSize() recursively chalta hai.
Google Drive/Dropbox waala version poocha jaaye to teen cheezein add karo: PERMISSIONS (owner/editor/viewer, inheritance ke saath), VERSIONING (har save ek nayi version, purani milti rahe), aur SHARING (link-based access with expiry). Chunked upload aur deduplication (content hash se) bhi mention karne layak hain.
abstract class FileSystemNode {
protected String name;
protected FileSystemNode parent;
abstract long getSize();
}
class FileNode extends FileSystemNode {
private byte[] content;
long getSize() { return content.length; }
}
class DirectoryNode extends FileSystemNode {
private final List<FileSystemNode> children = new ArrayList<>();
long getSize() { // recursion apne aap
return children.stream().mapToLong(FileSystemNode::getSize).sum();
}
}- Composite pattern: File (leaf) + Directory (composite) ek hi abstraction se
- getSize() recursively chalta hai — nesting free mein mil jaati hai
- Permissions inherit hoti hain, explicit child permission override karti hai
Composite ka fayda ye hai ki operations RECURSIVELY free milte hain — getSize(), delete(), search(), copy() sab directory par chalein to apne aap children par chal jaate hain.
Delete karte waqt dhyaan rakho: directory delete karne se saare children delete hote hain. Isliye confirmation aur (production mein) soft delete/trash chahiye — permanent delete turant nahi hona chahiye.
// Directory par operation apne aap poore subtree par chalta hai
class DirectoryNode extends FileSystemNode {
void delete() {
children.forEach(FileSystemNode::delete); // recursion
parent.removeChild(this);
}
List<FileSystemNode> search(String pattern) {
var result = new ArrayList<FileSystemNode>();
for (var c : children) {
if (c.name.matches(pattern)) result.add(c);
if (c instanceof DirectoryNode d) result.addAll(d.search(pattern));
}
return result;
}
}Har save par nayi version banao (versionId, timestamp, author, content pointer). Purani versions restore ho sakein. Har version ki poori copy rakhna mehnga hai — isliye DELTA storage ya content-addressed storage use hota hai.
DEDUPLICATION: file ka SHA-256 hash nikaalo. Same hash wali file pehle se ho to naya blob mat likho, bas reference badhao. Google Drive/Dropbox exactly yahi karte hain aur ye storage bahut bachata hai.
class FileVersion {
String versionId;
String contentHash; // SHA-256 — same hash = same blob, dobara store nahi
Instant createdAt;
String createdBy;
}