mirror of https://github.com/ConsenSys/mythril
parent
8338b85c4d
commit
c44923c75a
@ -0,0 +1,112 @@ |
|||||||
|
from ethereum.db import BaseDB |
||||||
|
import leveldb |
||||||
|
from ethereum import slogging |
||||||
|
|
||||||
|
slogging.set_level('db', 'debug') |
||||||
|
log = slogging.get_logger('db') |
||||||
|
|
||||||
|
compress = decompress = lambda x: x |
||||||
|
|
||||||
|
|
||||||
|
class LevelDB(BaseDB): |
||||||
|
""" |
||||||
|
filename the database directory |
||||||
|
block_cache_size (default: 8 * (2 << 20)) maximum allowed size for the block cache in bytes |
||||||
|
write_buffer_size (default 2 * (2 << 20)) |
||||||
|
block_size (default: 4096) unit of transfer for the block cache in bytes |
||||||
|
max_open_files: (default: 1000) |
||||||
|
create_if_missing (default: True) if True, creates a new database if none exists |
||||||
|
error_if_exists (default: False) if True, raises and error if the database exists |
||||||
|
paranoid_checks (default: False) if True, raises an error as soon as an internal |
||||||
|
corruption is detected |
||||||
|
""" |
||||||
|
|
||||||
|
max_open_files = 32000 |
||||||
|
block_cache_size = 8 * 1024**2 |
||||||
|
write_buffer_size = 4 * 1024**2 |
||||||
|
|
||||||
|
def __init__(self, dbfile): |
||||||
|
self.uncommitted = dict() |
||||||
|
log.info('opening LevelDB', |
||||||
|
path=dbfile, |
||||||
|
block_cache_size=self.block_cache_size, |
||||||
|
write_buffer_size=self.write_buffer_size, |
||||||
|
max_open_files=self.max_open_files) |
||||||
|
self.dbfile = dbfile |
||||||
|
self.db = leveldb.LevelDB(dbfile, max_open_files=self.max_open_files) |
||||||
|
self.commit_counter = 0 |
||||||
|
|
||||||
|
def reopen(self): |
||||||
|
del self.db |
||||||
|
self.db = leveldb.LevelDB(self.dbfile) |
||||||
|
|
||||||
|
def get(self, key): |
||||||
|
log.trace('getting entry', key=key.encode('hex')[:8]) |
||||||
|
if key in self.uncommitted: |
||||||
|
if self.uncommitted[key] is None: |
||||||
|
raise KeyError("key not in db") |
||||||
|
log.trace('from uncommitted') |
||||||
|
return self.uncommitted[key] |
||||||
|
log.trace('from db') |
||||||
|
o = decompress(self.db.Get(key)) |
||||||
|
self.uncommitted[key] = o |
||||||
|
return o |
||||||
|
|
||||||
|
def put(self, key, value): |
||||||
|
log.trace('putting entry', key=key.encode('hex')[:8], len=len(value)) |
||||||
|
self.uncommitted[key] = value |
||||||
|
|
||||||
|
def commit(self): |
||||||
|
log.debug('committing', db=self) |
||||||
|
batch = leveldb.WriteBatch() |
||||||
|
for k, v in self.uncommitted.items(): |
||||||
|
if v is None: |
||||||
|
batch.Delete(k) |
||||||
|
else: |
||||||
|
batch.Put(k, compress(v)) |
||||||
|
self.db.Write(batch, sync=False) |
||||||
|
self.uncommitted.clear() |
||||||
|
log.debug('committed', db=self, num=len(self.uncommitted)) |
||||||
|
# self.commit_counter += 1 |
||||||
|
# if self.commit_counter % 100 == 0: |
||||||
|
# self.reopen() |
||||||
|
|
||||||
|
def delete(self, key): |
||||||
|
log.trace('deleting entry', key=key) |
||||||
|
self.uncommitted[key] = None |
||||||
|
|
||||||
|
def _has_key(self, key): |
||||||
|
try: |
||||||
|
self.get(key) |
||||||
|
return True |
||||||
|
except KeyError: |
||||||
|
return False |
||||||
|
|
||||||
|
def __contains__(self, key): |
||||||
|
return self._has_key(key) |
||||||
|
|
||||||
|
def __eq__(self, other): |
||||||
|
return isinstance(other, self.__class__) and self.db == other.db |
||||||
|
|
||||||
|
def __repr__(self): |
||||||
|
return '<DB at %d uncommitted=%d>' % (id(self.db), len(self.uncommitted)) |
||||||
|
|
||||||
|
def inc_refcount(self, key, value): |
||||||
|
self.put(key, value) |
||||||
|
|
||||||
|
def dec_refcount(self, key): |
||||||
|
pass |
||||||
|
|
||||||
|
def revert_refcount_changes(self, epoch): |
||||||
|
pass |
||||||
|
|
||||||
|
def commit_refcount_changes(self, epoch): |
||||||
|
pass |
||||||
|
|
||||||
|
def cleanup(self, epoch): |
||||||
|
pass |
||||||
|
|
||||||
|
def put_temporarily(self, key, value): |
||||||
|
self.inc_refcount(key, value) |
||||||
|
self.dec_refcount(key) |
||||||
|
|
Loading…
Reference in new issue