-
Notifications
You must be signed in to change notification settings - Fork 29
/
main.js
executable file
·126 lines (105 loc) · 3.21 KB
/
main.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// MegaHash v1.0
// Copyright (c) 2019 Joseph Huckaby
// Based on DeepHash, (c) 2003 Joseph Huckaby
var MegaHash = require('bindings')('megahash').MegaHash;
const MH_TYPE_BUFFER = 0;
const MH_TYPE_STRING = 1;
const MH_TYPE_NUMBER = 2;
const MH_TYPE_BOOLEAN = 3;
const MH_TYPE_OBJECT = 4;
const MH_TYPE_BIGINT = 5;
const MH_TYPE_NULL = 6;
MegaHash.prototype.set = function(key, value) {
// store key/value in hash, auto-convert format to buffer
var flags = MH_TYPE_BUFFER;
var keyBuf = Buffer.isBuffer(key) ? key : Buffer.from(''+key, 'utf8');
if (!keyBuf.length) throw new Error("Key must have length");
var valueBuf = value;
if (!Buffer.isBuffer(valueBuf)) {
if (valueBuf === null) {
valueBuf = Buffer.alloc(0);
flags = MH_TYPE_NULL;
}
else if (typeof(valueBuf) == 'object') {
valueBuf = Buffer.from( JSON.stringify(value) );
flags = MH_TYPE_OBJECT;
}
else if (typeof(valueBuf) == 'number') {
valueBuf = Buffer.alloc(8);
valueBuf.writeDoubleBE( value );
flags = MH_TYPE_NUMBER;
}
else if (typeof(valueBuf) == 'bigint') {
valueBuf = Buffer.alloc(8);
valueBuf.writeBigInt64BE( value );
flags = MH_TYPE_BIGINT;
}
else if (typeof(valueBuf) == 'boolean') {
valueBuf = Buffer.alloc(1);
valueBuf.writeUInt8( value ? 1 : 0 );
flags = MH_TYPE_BOOLEAN;
}
else {
valueBuf = Buffer.from(''+value, 'utf8');
flags = MH_TYPE_STRING;
}
}
return this._set(keyBuf, valueBuf, flags);
};
MegaHash.prototype.get = function(key) {
// fetch value given key, auto-convert back to original format
var keyBuf = Buffer.isBuffer(key) ? key : Buffer.from(''+key, 'utf8');
if (!keyBuf.length) throw new Error("Key must have length");
var value = this._get( keyBuf );
if (!value || !value.flags) return value;
switch (value.flags) {
case MH_TYPE_NULL:
value = null;
break;
case MH_TYPE_OBJECT:
value = JSON.parse( value.toString() );
break;
case MH_TYPE_NUMBER:
value = value.readDoubleBE();
break;
case MH_TYPE_BIGINT:
value = value.readBigInt64BE();
break;
case MH_TYPE_BOOLEAN:
value = (value.readUInt8() == 1) ? true : false;
break;
case MH_TYPE_STRING:
value = value.toString();
break;
}
return value;
};
MegaHash.prototype.has = function(key) {
// check existence of key
var keyBuf = Buffer.isBuffer(key) ? key : Buffer.from(''+key, 'utf8');
if (!keyBuf.length) throw new Error("Key must have length");
return this._has( keyBuf );
};
MegaHash.prototype.remove = MegaHash.prototype.delete = function(key) {
// remove key/value pair given key
var keyBuf = Buffer.isBuffer(key) ? key : Buffer.from(''+key, 'utf8');
if (!keyBuf.length) throw new Error("Key must have length");
return this._remove( keyBuf );
};
MegaHash.prototype.nextKey = function(key) {
// get next key given previous (or omit for first key)
// convert all keys to strings
if (typeof(key) == 'undefined') {
var keyBuf = this._firstKey();
return keyBuf ? keyBuf.toString() : undefined;
}
else {
var keyBuf = this._nextKey( Buffer.isBuffer(key) ? key : Buffer.from(''+key, 'utf8') );
return keyBuf ? keyBuf.toString() : undefined;
}
};
MegaHash.prototype.length = function() {
// shortcut for numKeys
return this.stats().numKeys;
}
module.exports = MegaHash;