add support for supernode, which contains metadata about the file system itself (currently only the location of the root node); updated refactoring-test

This commit is contained in:
Alan Kligman 2013-12-14 14:42:00 -05:00
parent 778464cf7b
commit 8510e4a712
4 changed files with 62 additions and 47 deletions

View File

@ -6,50 +6,26 @@
<body> <body>
<div id="stdout"></div> <div id="stdout"></div>
</body> </body>
<script src="../lib/require.js"></script> <script src="../dist/idbfs.js"></script>
<script> <script>
require.config({ window.IDBFS = IDBFS;
baseUrl: "../lib", var fs = new IDBFS.FileSystem({
paths: { name: 'local',
"src": "../src" flags: ['FORMAT']
} });
});
require(["src/fs"], function(IDBFS) { //var buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
//console.log('buffer', buffer);
var flags = 'FORMAT'; //var data = new Uint8Array(buffer.length);
//var flags;
var fs = new IDBFS.FileSystem('local', flags);
var buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
console.log('buffer', buffer);
var data = new Uint8Array(buffer.length);
try { try {
fs.open('/tmp', 'w+', function(error, fd) { fs.stat('/', function(error, stats) {
if(error) throw error;
console.log('descriptor:', fd);
fs.lseek(fd, 2, 'END', function(error, pos) {
if(error) throw error;
console.log('pos:', pos);
fs.close(fd, function(error) {
if(error) throw error;
console.log('closed');
fs.stat('/tmp', function(error, stats) {
if(error) throw error; if(error) throw error;
console.log('stats:', stats); console.log('stats:', stats);
fs.rename('/tmp', '/tmp1', function(error) {
if(error) throw error;
console.log('done');
});
});
});
});
}); });
} catch(e) { } catch(e) {
console.error(e); console.error(e);
} }
});
</script> </script>
</html> </html>

View File

@ -22,6 +22,7 @@ define(function(require) {
MODE_FILE: 'FILE', MODE_FILE: 'FILE',
MODE_DIRECTORY: 'DIRECTORY', MODE_DIRECTORY: 'DIRECTORY',
MODE_SYMBOLIC_LINK: 'SYMLINK', MODE_SYMBOLIC_LINK: 'SYMLINK',
MODE_META: 'META',
SYMLOOP_MAX: 10, SYMLOOP_MAX: 10,
@ -29,7 +30,6 @@ define(function(require) {
JSON_MIME_TYPE: 'application/json', JSON_MIME_TYPE: 'application/json',
ROOT_DIRECTORY_NAME: '/', // basename(normalize(path)) ROOT_DIRECTORY_NAME: '/', // basename(normalize(path))
ROOT_NODE_ID: '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1', // sha256(ROOT_DIRECTORY_NAME)
FS_FORMAT: 'FORMAT', FS_FORMAT: 'FORMAT',
@ -55,7 +55,9 @@ define(function(require) {
FS_READY: 'READY', FS_READY: 'READY',
FS_PENDING: 'PENDING', FS_PENDING: 'PENDING',
FS_ERROR: 'ERROR' FS_ERROR: 'ERROR',
SUPER_NODE_ID: '00000000-0000-0000-0000-000000000000'
}; };
}); });

View File

@ -117,7 +117,8 @@ define(function(require) {
ENotMounted: ENotMounted, ENotMounted: ENotMounted,
EInvalid: EInvalid, EInvalid: EInvalid,
EIO: EIO, EIO: EIO,
ELoop: ELoop ELoop: ELoop,
EFileSystemError: EFileSystemError
}; };
}); });

View File

@ -33,8 +33,9 @@ define(function(require) {
var MODE_FILE = require('src/constants').MODE_FILE; var MODE_FILE = require('src/constants').MODE_FILE;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY; var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
var MODE_SYMBOLIC_LINK = require('src/constants').MODE_SYMBOLIC_LINK; var MODE_SYMBOLIC_LINK = require('src/constants').MODE_SYMBOLIC_LINK;
var MODE_META = require('src/constants').MODE_META;
var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME; var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME;
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID; var SUPER_NODE_ID = require('src/constants').SUPER_NODE_ID;
var SYMLOOP_MAX = require('src/constants').SYMLOOP_MAX; var SYMLOOP_MAX = require('src/constants').SYMLOOP_MAX;
var FS_READY = require('src/constants').FS_READY; var FS_READY = require('src/constants').FS_READY;
var FS_PENDING = require('src/constants').FS_PENDING; var FS_PENDING = require('src/constants').FS_PENDING;
@ -69,6 +70,21 @@ define(function(require) {
this.position = position; this.position = position;
} }
/*
* SuperNode
*/
function SuperNode(atime, ctime, mtime) {
var now = Date.now();
this.id = SUPER_NODE_ID;
this.mode = MODE_META;
this.atime = atime || now;
this.ctime = ctime || now;
this.mtime = mtime || now;
this.rnode = guid(); // root node id (randomly generated)
}
/* /*
* Node * Node
*/ */
@ -76,7 +92,7 @@ define(function(require) {
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, nlinks, version) { function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, nlinks, version) {
var now = Date.now(); var now = Date.now();
this.id = id || hash(guid()); this.id = id || guid();
this.mode = mode || MODE_FILE; // node type (file, directory, etc) this.mode = mode || MODE_FILE; // node type (file, directory, etc)
this.size = size || 0; // size (bytes for files, entries for directories) this.size = size || 0; // size (bytes for files, entries for directories)
this.atime = atime || now; // access time this.atime = atime || now; // access time
@ -88,7 +104,7 @@ define(function(require) {
this.version = version || 0; // node version this.version = version || 0; // node version
this.blksize = undefined; // block size this.blksize = undefined; // block size
this.nblocks = 1; // blocks count this.nblocks = 1; // blocks count
this.data = hash(guid()); // id for data object this.data = guid(); // id for data object
} }
/* /*
@ -121,6 +137,16 @@ define(function(require) {
var parentPath = dirname(path); var parentPath = dirname(path);
var followedCount = 0; var followedCount = 0;
function read_root_directory_node(error, superNode) {
if(error) {
callback(error);
} else if(!superNode || superNode.mode !== MODE_META || !superNode.rnode) {
callback(new EFileSystemError('missing super node'));
} else {
context.get(superNode.rnode, check_root_directory_node);
}
}
function check_root_directory_node(error, rootDirectoryNode) { function check_root_directory_node(error, rootDirectoryNode) {
if(error) { if(error) {
callback(error); callback(error);
@ -180,14 +206,14 @@ define(function(require) {
parentPath = dirname(data); parentPath = dirname(data);
name = basename(data); name = basename(data);
if(ROOT_DIRECTORY_NAME == name) { if(ROOT_DIRECTORY_NAME == name) {
context.get(ROOT_NODE_ID, check_root_directory_node); context.get(SUPER_NODE_ID, read_root_directory_node);
} else { } else {
find_node(context, parentPath, read_parent_directory_data); find_node(context, parentPath, read_parent_directory_data);
} }
} }
if(ROOT_DIRECTORY_NAME == name) { if(ROOT_DIRECTORY_NAME == name) {
context.get(ROOT_NODE_ID, check_root_directory_node); context.get(SUPER_NODE_ID, read_root_directory_node);
} else { } else {
find_node(context, parentPath, read_parent_directory_data); find_node(context, parentPath, read_parent_directory_data);
} }
@ -199,16 +225,26 @@ define(function(require) {
// Note: this should only be invoked when formatting a new file system // Note: this should only be invoked when formatting a new file system
function make_root_directory(context, callback) { function make_root_directory(context, callback) {
var superNode;
var directoryNode; var directoryNode;
var directoryData; var directoryData;
function write_directory_node(error, existingNode) { function write_super_node(error, existingNode) {
if(!error && existingNode) { if(!error && existingNode) {
callback(new EExists()); callback(new EExists());
} else if(error && !error instanceof ENoEntry) { } else if(error && !error instanceof ENoEntry) {
callback(error); callback(error);
} else { } else {
directoryNode = new Node(ROOT_NODE_ID, MODE_DIRECTORY); superNode = new SuperNode();
context.put(superNode.id, superNode, write_directory_node);
}
}
function write_directory_node(error) {
if(error) {
callback(error);
} else {
directoryNode = new Node(superNode.rnode, MODE_DIRECTORY);
directoryNode.nlinks += 1; directoryNode.nlinks += 1;
context.put(directoryNode.id, directoryNode, write_directory_data); context.put(directoryNode.id, directoryNode, write_directory_data);
} }
@ -223,7 +259,7 @@ define(function(require) {
} }
} }
find_node(context, ROOT_DIRECTORY_NAME, write_directory_node); context.get(SUPER_NODE_ID, write_super_node);
} }
/* /*
@ -632,7 +668,7 @@ define(function(require) {
var directoryData; var directoryData;
if(ROOT_DIRECTORY_NAME == name) { if(ROOT_DIRECTORY_NAME == name) {
context.get(ROOT_NODE_ID, check_file); find_node(context, path, check_file);
} else { } else {
find_node(context, parentPath, read_directory_data); find_node(context, parentPath, read_directory_data);
} }