Monday, July 21, 2014

Design an in-memory file system



http://www.careercup.com/question?id=13618661
1> Use Structure with n children, on parent pointer , one data field and one name field. 
2> Use this Structure to make N ary Tree with parent Child relationship. We can use inheritance feature of OOPs here. 
3> Now we can use this structure to make Files/Folder accourdingly. 
if Files that it parent pointer points to the Folder where it belongs with all its child pointer pointing to NULL and struct->data is the File Content. 
else if Folder . point it parent point to it Parent Folder while Child still pointing to NULL but its Struct->data as NULL. 
that way we can differentiate between file /folder and maintain its relationship. 

Main Class
AbstractFile
File
Folder
Permission
Singleton FileSystem Manager Object
maybe command line desgin pattern
class TPermission
{
public:
  string    name;
  enum {full_access, read_only, write, read};
};
https://tianrunhe.wordpress.com/2012/03/24/design-an-in-memory-file-system/
Command Interpreter: translate shell command to API call.

MetaData, FileSystem(root class, facada).
struct DataBlock { char data[DATA_BLOCK_SIZE]; };
DataBlock dataBlocks[NUM_DATA_BLOCKS];
struct INode { std::vector<int> datablocks; };
struct MetaData {
    int size;
    Date last_modifed, created;
    char extra_attributes;
};
std::vector<bool> dataBlockUsed(NUM_DATA_BLOCKS);
std::map<string, INode *> mapFromName;
struct FSBase;
struct File : public FSBase {
    private:
        std::vector<INode> * nodes;
        MetaData metaData;
};
struct Directory : pubic FSBase { std::vector<FSBase* > content; };
struct FileSystem {
    init();
    mount(FileSystem*);
    unmount(FileSystem*);
    File createFile(cosnt char* name) { ... }
    Directory createDirectory(const char* name) { ... }
    // mapFromName to find INode corresponding to file
    void openFile(File * file, FileMode mode) { ... }
    void closeFile(File * file) { ... }
    void writeToFile(File * file, void * data, int num) { ... }
    void readFromFile(File* file, void* res, int numbutes,
            int position) { ... }
};
http://www.shuatiblog.com/blog/2014/08/25/design-in-memory-file-system/
A file system consists of Files and Directories. Each Directory contains a set of Files and Directories.

Since Files and Directories share so many characteristics, we’ve implemented them such that they inherit from the same class — Entry.
UML diagram -> composite pattern.
public abstract class Entry {
    protected Directory parent;
    protected long created;
    protected long lastUpdated;
    protected long lastAccessed;
    protected String name;

    public Entry(String n, Directory p) {
        name = n;
        parent = p;
        created = System.currentTimeMillis();
    }
    public boolean delete() {
        if (parent == null) {
            return false;
        }
        return parent.deleteEntry(this);
    }
    public abstract int size();

    public String getFullPath() {
        if (parent == null) {
            return name;
        } else {
            return parent.getFullPath() + "/" + name;
        }
    }
}
public class File extends Entry {
    private String content;
    private int size;

    public File(String n, Directory p, int sz) {
        super(n, p);
        size = sz;
    }
}
public class Directory extends Entry {
    protected ArrayList<Entry> contents;

    public Directory(String n, Directory p) {
        super(n, p);
        contents = new ArrayList<Entry>();
    }

    protected ArrayList<Entry> getContents() {
        return contents;
    }

    public int size() {
        int size = 0;
        for (Entry e : contents) {
            size += e.size();
        }
        return size;
    }

    public int numberOfFiles() {
        int count = 0;
        for (Entry e : contents) {
            if (e instanceof Directory) {
                count++; // Directory counts as a file
                Directory d = (Directory) e;
                count += d.numberOfFiles();
            } else if (e instanceof File) {
                count++;
            }
        }
        return count;
    }

    public boolean deleteEntry(Entry entry) {
        return contents.remove(entry);
    }

    public void addEntry(Entry entry) {
        contents.add(entry);
    }
}

http://www.cs.cornell.edu/slk/jk-0.91/doc/jkernel/tutorial/tutorial-4.html
public class MemFileSystemImpl implements MemFileSystem
{
    Hashtable files = new Hashtable(); // maps Strings to byte arrays

    public void writeFile(String name, byte[] contents)
    {
        files.put(name, contents);
    }

    public byte[] readFile(String name)
        throws FileNotFoundException
    {
        byte[] contents = (byte[]) files.get(name);
        if(contents == null) throw new FileNotFoundException(name);
        else return contents;
    }
}
public class MemFileInputStream extends InputStream
{
    private ByteArrayInputStream bStream;
    
    public MemFileInputStream(String name)
        throws FileNotFoundException
    {
        byte[] b;

        try
        {
            b = MemFileSystemAdaptor.fileSystem.readFile(name);
        }
        catch(RemoteException e) {throw new FileNotFoundException(e.toString());}

        bStream = new ByteArrayInputStream(b);
    }

    public int available() {return bStream.available();}
    public void close() {}
    public int read() {return bStream.read();}
    public int read(byte[] b) {return bStream.read(b, 0, b.length);}
    public int read(byte[] b, int off, int len) {return bStream.read(b, off, len);}
    public long skip(long n) {return bStream.skip(n);}
}

public class MemFileOutputStream extends OutputStream
{
    private ByteArrayOutputStream bStream = new ByteArrayOutputStream();
    private String name;

    public MemFileOutputStream(String name)
    {
        this.name = name;
    }

    public void close()
        throws IOException
    {
        try
        {
            MemFileSystemAdaptor.fileSystem.writeFile(name, bStream.toByteArray());
        }
        catch(RemoteException e) {throw new IOException(e.toString());}
    }

    public void write(byte[] b) {bStream.write(b, 0, b.length);}
    public void write(byte[] b, int start, int len) {bStream.write(b, start, len);}
    public void write(int i) {bStream.write(i);}
}

http://stackoverflow.com/questions/5629116/simple-in-memory-file-system
http://www.flipcode.com/archives/Programming_a_Virtual_File_System-Part_I.shtml
Java code: https://github.com/marschall/memoryfilesystem
Read full article from Design an in-memory file system | Runhe Tian Coding Practice

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts