-
Notifications
You must be signed in to change notification settings - Fork 16
/
keystore.js
81 lines (74 loc) · 2.48 KB
/
keystore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// keystore.js
//
// a quick git-inspired anti-db hashtable, like memcached
//
// Keystore("dir") returns a keystore object where everything is stored inside
// "dir". (Note! this is expensive)
//
// Keystore.prototype.set("key", value, function callback(error){})
// will store the JSON-serialized value into the string key.
//
// Keystore.prototype.get("key", function callback(data){})
// will JSON-unserialize the object and call callback with either the data or
// undefined.
//
// The database is pretty simple. Just like git, we sha1 the key and store it in
// 01/23456789abcdef; that is, the first two digits of the sha1 is the folder
// and the rest is the file.
//
// Note that this is just stupid. No checking is done to ensure you don't
// overwrite things at the same time from two different times in the event loop,
// and no caching or anything is done (the OS might be better at it anyway).
//
// Also note that because objects are stored by sha1 hash, it's impossible to
// get at the keys (if I implemented it right that is ;) )
// This is kinda the point.
var sha1 = require('./sha1').hex_sha1,
fs = require('fs'),
path = require('path');
function Keystore(directory) {
// WARNING! expensive!
this.dir = directory;
// initialize subdirs
for (var i=0; i<256; i++) {
try {
var hexdigit = i.toString(16).toLowerCase();
fs.mkdirSync(path.join(this.dir, "00".substr(hexdigit.length)+hexdigit), 0700);
} catch (e) {}
}
}
Keystore.prototype.set = function(key, value, cb) {
// Set the key to the value and call cb(error).
cb = cb || function(){};
key = sha1(key);
var base = key.substr(0,2),
rest = key.substr(2), self = this;
try {
fs.writeFile(path.join(self.dir, base, rest),
JSON.stringify(value),
cb);
} catch (e) {
cb(e);
}
};
Keystore.prototype.get = function(key, cb) {
// call cb on the value stored in the key.
// arg is 'undefined' if the object is not set.
cb = cb || function(){};
key = sha1(key);
var base = key.substr(0,2),
rest = key.substr(2), self = this;
fs.readFile(path.join(self.dir, base, rest), function(err, data) {
if (err) {
return cb(); // cb will have undefined
}
try {
cb(JSON.parse(data.toString().trim()));
} catch(e) {
cb();
// we should handle this better because this means that the object was
// corrupt.
}
});
};
exports.Keystore = Keystore;