1
- import os
2
- import threading
3
1
from ethereum .compress import compress , decompress
4
- from hashlib import md5
5
2
from ethereum import utils
6
3
from ethereum .slogging import get_logger
7
4
from rlp .utils import str_to_bytes
11
8
databases = {}
12
9
13
10
14
- try :
15
- from CodernityDB .database import Database , DatabasePathException , \
16
- RecordNotFound
17
- from CodernityDB .hash_index import HashIndex
18
- except ImportError :
19
- _CodernityDB = None
20
- else :
21
- class MD5Index (HashIndex ):
22
-
23
- def __init__ (self , * args , ** kwargs ):
24
- kwargs ['key_format' ] = '16s'
25
- super (MD5Index , self ).__init__ (* args , ** kwargs )
26
-
27
- def make_key_value (self , data ):
28
- return md5 (data ['key' ]).digest (), None
29
-
30
- def make_key (self , key ):
31
- return md5 (key ).digest ()
32
-
33
- class _CodernityDB (object ):
34
-
35
- def __init__ (self , dbfile ):
36
- self .dbfile = os .path .abspath (dbfile )
37
- if dbfile in databases :
38
- self .db = databases [dbfile ]
39
- assert isinstance (self .db , self .db .__class__ )
40
- else :
41
- self .db = Database (dbfile )
42
- try :
43
- self .db .open ()
44
- except DatabasePathException :
45
- self .db .create ()
46
- self .db .add_index (MD5Index (dbfile , 'key' ))
47
- databases [dbfile ] = self .db
48
- self .uncommitted = dict ()
49
- self .uncommitted_lock = threading .Lock ()
50
-
51
- def get (self , key ):
52
- if key in self .uncommitted :
53
- if self .uncommitted [key ] is None :
54
- raise KeyError ("key not in db" )
55
- return self .uncommitted [key ]
56
- try :
57
- value = self .db .get ('key' , key , with_doc = True )['doc' ]['value' ]
58
- except RecordNotFound :
59
- raise KeyError ("key not in db" )
60
- return decompress (str_to_bytes (value ))
61
-
62
- def put (self , key , value ):
63
- with self .uncommitted_lock :
64
- self .uncommitted [key ] = value
65
-
66
- def commit (self ):
67
- log .debug ('commit' , db = self )
68
- with self .uncommitted_lock :
69
- for k , v in self .uncommitted .items ():
70
- if v is None :
71
- doc = self .db .get ('key' , k , with_doc = True )['doc' ]
72
- self .db .delete (doc )
73
- else :
74
- self .db .insert ({'key' : k , 'value' : compress (v )})
75
- self .uncommitted .clear ()
76
-
77
- def delete (self , key ):
78
- with self .uncommitted_lock :
79
- self .uncommitted [key ] = None
80
-
81
- def __contains__ (self , key ):
82
- try :
83
- self .get (key )
84
- except KeyError :
85
- return False
86
- return True
87
-
88
- def __eq__ (self , other ):
89
- return isinstance (other , self .__class__ ) and self .db == other .db
90
-
91
- def __hash__ (self ):
92
- return utils .big_endian_to_int (str_to_bytes (self .__repr__ ()))
93
-
94
- def __repr__ (self ):
95
- return '<DB at %d uncommitted=%d>' % (id (self .db ), len (self .uncommitted ))
96
-
97
- def delete_db (self ):
98
- del databases [self .dbfile ]
99
-
100
- try :
101
- import leveldb
102
- except ImportError :
103
- _LevelDB = None
104
- else :
105
- class _LevelDB (object ):
106
-
107
- def __init__ (self , dbfile ):
108
- self .dbfile = os .path .abspath (dbfile )
109
- if dbfile in databases :
110
- self .db = databases [dbfile ]
111
- assert isinstance (self .db , leveldb .LevelDB )
112
- else :
113
- self .db = leveldb .LevelDB (dbfile )
114
- databases [dbfile ] = self .db
115
- self .uncommitted = dict ()
116
- self .lock = threading .Lock ()
117
-
118
- def get (self , key ):
119
- if key in self .uncommitted :
120
- if self .uncommitted [key ] is None :
121
- raise KeyError ("key not in db" )
122
- return self .uncommitted [key ]
123
- o = decompress (str_to_bytes (self .db .Get (key )))
124
- self .uncommitted [key ] = o
125
- return o
126
-
127
- def put (self , key , value ):
128
- with self .lock :
129
- self .uncommitted [key ] = value
130
-
131
- def commit (self ):
132
- log .debug ('commit' , db = self )
133
- with self .lock :
134
- batch = leveldb .WriteBatch ()
135
- for k , v in self .uncommitted .items ():
136
- if v is None :
137
- batch .Delete (k )
138
- else :
139
- batch .Put (k , compress (v ))
140
- self .db .Write (batch , sync = False )
141
- self .uncommitted .clear ()
142
-
143
- def delete (self , key ):
144
- with self .lock :
145
- self .uncommitted [key ] = None
146
-
147
- def _has_key (self , key ):
148
- try :
149
- self .get (key )
150
- return True
151
- except KeyError :
152
- return False
153
-
154
- def __contains__ (self , key ):
155
- return self ._has_key (key )
156
-
157
- def __eq__ (self , other ):
158
- return isinstance (other , self .__class__ ) and self .db == other .db
159
-
160
- def __hash__ (self ):
161
- return utils .big_endian_to_int (str_to_bytes (self .__repr__ ()))
162
-
163
- def __repr__ (self ):
164
- return '<DB at %d uncommitted=%d>' % (id (self .db ), len (self .uncommitted ))
165
-
166
- def delete_db (self ):
167
- del databases [self .dbfile ]
168
-
169
-
170
11
class _EphemDB (object ):
171
12
172
13
def __init__ (self ):
173
14
self .db = {}
174
15
175
16
def get (self , key ):
176
- return self .db [key ]
17
+ return decompress ( self .db [key ])
177
18
178
19
def put (self , key , value ):
179
- self .db [key ] = value
20
+ self .db [key ] = compress ( value )
180
21
181
22
def delete (self , key ):
182
23
del self .db [key ]
@@ -197,6 +38,4 @@ def __hash__(self):
197
38
return utils .big_endian_to_int (str_to_bytes (self .__repr__ ()))
198
39
199
40
200
- DB = _LevelDB or _CodernityDB
201
- assert DB is not None
202
- EphemDB = _EphemDB
41
+ DB = EphemDB = _EphemDB
0 commit comments