-
Notifications
You must be signed in to change notification settings - Fork 139
/
FileTreeDb.ts
111 lines (83 loc) · 2.44 KB
/
FileTreeDb.ts
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
// Copyright 2017-2019 @polkadot/db authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseDb, ProgressCb } from '../types';
import fs from 'fs';
import mkdirp from 'mkdirp';
import { bufferToU8a, logger, u8aToBuffer, u8aToHex } from '@polkadot/util';
type FilePath = {
directory: string,
file: string
};
const DIR_DEPTH = 1;
const l = logger('db/tree');
export default class FileTreeDb implements BaseDb {
_location: string;
constructor (location: string) {
this._location = location;
}
private _getFilePath (key: Uint8Array): FilePath {
// NOTE We want to limit the number of entries in any specific directory. Split the
// key into parts and use this to construct the path and the actual filename. We want
// to limit the entries per directory, but at the same time minimize the number of
// directories we need to create (when non-existent as well as the size overhead)
const parts = u8aToHex(key).match(/.{1,6}/g) || [];
const directory = `${this._location}/${parts.slice(0, DIR_DEPTH).join('/')}`;
const file = `${directory}/${parts.slice(DIR_DEPTH).join('')}`;
return {
directory,
file
};
}
open (): void {
// noop
}
close (): void {
// noop
}
drop (): void {
l.error('drop() is not implemented');
}
empty (): void {
l.error('empty() is not implemented');
}
rename (base: string, file: string): void {
l.error('rename() is not implemented');
}
size (): number {
l.error('size() is not implemented');
return 0;
}
maintain (fn: ProgressCb): void {
fn({
isCompleted: true,
keys: 0,
percent: 100
});
}
del (key: Uint8Array): void {
l.debug(() => ['del', { key }]);
const { file } = this._getFilePath(key);
if (fs.existsSync(file)) {
fs.unlinkSync(file);
}
}
get (key: Uint8Array): Uint8Array | null {
l.debug(() => ['get', { key }]);
const { file } = this._getFilePath(key);
if (!fs.existsSync(file)) {
return null;
}
return bufferToU8a(
fs.readFileSync(file)
);
}
put (key: Uint8Array, value: Uint8Array): void {
l.debug(() => ['set', { key, value }]);
const { directory, file } = this._getFilePath(key);
if (!fs.existsSync(directory)) {
mkdirp.sync(directory);
}
fs.writeFileSync(file, u8aToBuffer(value));
}
}