lru: better atomicity for chain and walletdb.
This commit is contained in:
parent
0ebeb1e643
commit
331daf0f6a
@ -274,8 +274,14 @@ ChainDB.prototype._close = function close() {
|
|||||||
ChainDB.prototype.start = function start() {
|
ChainDB.prototype.start = function start() {
|
||||||
assert(!this.current);
|
assert(!this.current);
|
||||||
assert(!this.pending);
|
assert(!this.pending);
|
||||||
|
|
||||||
this.current = this.db.batch();
|
this.current = this.db.batch();
|
||||||
this.pending = this.state.clone();
|
this.pending = this.state.clone();
|
||||||
|
|
||||||
|
this.coinCache.start();
|
||||||
|
this.cacheHash.start();
|
||||||
|
this.cacheHeight.start();
|
||||||
|
|
||||||
return this.current;
|
return this.current;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,11 +322,19 @@ ChainDB.prototype.batch = function batch() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ChainDB.prototype.drop = function drop() {
|
ChainDB.prototype.drop = function drop() {
|
||||||
|
var batch = this.current;
|
||||||
|
|
||||||
assert(this.current);
|
assert(this.current);
|
||||||
assert(this.pending);
|
assert(this.pending);
|
||||||
this.current.clear();
|
|
||||||
this.current = null;
|
this.current = null;
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
|
|
||||||
|
this.coinCache.drop();
|
||||||
|
this.cacheHash.drop();
|
||||||
|
this.cacheHeight.drop();
|
||||||
|
|
||||||
|
batch.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -337,11 +351,12 @@ ChainDB.prototype.commit = co(function* commit() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.current = null;
|
this.current = null;
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
|
this.coinCache.drop();
|
||||||
|
this.cacheHash.drop();
|
||||||
|
this.cacheHeight.drop();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.current = null;
|
|
||||||
|
|
||||||
// Overwrite the entire state
|
// Overwrite the entire state
|
||||||
// with our new best state
|
// with our new best state
|
||||||
// only if it is committed.
|
// only if it is committed.
|
||||||
@ -350,7 +365,12 @@ ChainDB.prototype.commit = co(function* commit() {
|
|||||||
if (this.pending.committed)
|
if (this.pending.committed)
|
||||||
this.state = this.pending;
|
this.state = this.pending;
|
||||||
|
|
||||||
|
this.current = null;
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
|
|
||||||
|
this.coinCache.commit();
|
||||||
|
this.cacheHash.commit();
|
||||||
|
this.cacheHeight.commit();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1167,14 +1187,14 @@ ChainDB.prototype._save = co(function* save(entry, block, view) {
|
|||||||
this.put(layout.h(hash), U32(entry.height));
|
this.put(layout.h(hash), U32(entry.height));
|
||||||
this.put(layout.e(hash), entry.toRaw());
|
this.put(layout.e(hash), entry.toRaw());
|
||||||
|
|
||||||
this.cacheHash.set(entry.hash, entry);
|
this.cacheHash.push(entry.hash, entry);
|
||||||
|
|
||||||
if (!view) {
|
if (!view) {
|
||||||
yield this.saveBlock(block);
|
yield this.saveBlock(block);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cacheHeight.set(entry.height, entry);
|
this.cacheHeight.push(entry.height, entry);
|
||||||
|
|
||||||
this.put(layout.n(entry.prevBlock), hash);
|
this.put(layout.n(entry.prevBlock), hash);
|
||||||
this.put(layout.H(entry.height), hash);
|
this.put(layout.H(entry.height), hash);
|
||||||
@ -1218,8 +1238,8 @@ ChainDB.prototype._reconnect = co(function* reconnect(entry, block, view) {
|
|||||||
this.put(layout.n(entry.prevBlock), hash);
|
this.put(layout.n(entry.prevBlock), hash);
|
||||||
this.put(layout.H(entry.height), hash);
|
this.put(layout.H(entry.height), hash);
|
||||||
|
|
||||||
this.cacheHash.set(entry.hash, entry);
|
this.cacheHash.push(entry.hash, entry);
|
||||||
this.cacheHeight.set(entry.height, entry);
|
this.cacheHeight.push(entry.height, entry);
|
||||||
|
|
||||||
yield this.connectBlock(block, view);
|
yield this.connectBlock(block, view);
|
||||||
|
|
||||||
@ -1262,7 +1282,7 @@ ChainDB.prototype._disconnect = co(function* disconnect(entry) {
|
|||||||
this.del(layout.n(entry.prevBlock));
|
this.del(layout.n(entry.prevBlock));
|
||||||
this.del(layout.H(entry.height));
|
this.del(layout.H(entry.height));
|
||||||
|
|
||||||
this.cacheHeight.remove(entry.height);
|
this.cacheHeight.unpush(entry.height);
|
||||||
|
|
||||||
block = yield this.getBlock(entry.hash);
|
block = yield this.getBlock(entry.hash);
|
||||||
|
|
||||||
@ -1457,10 +1477,10 @@ ChainDB.prototype.connectBlock = co(function* connectBlock(block, view) {
|
|||||||
raw = coins.toRaw();
|
raw = coins.toRaw();
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
this.del(layout.c(coins.hash));
|
this.del(layout.c(coins.hash));
|
||||||
this.coinCache.remove(coins.hash);
|
this.coinCache.unpush(coins.hash);
|
||||||
} else {
|
} else {
|
||||||
this.put(layout.c(coins.hash), raw);
|
this.put(layout.c(coins.hash), raw);
|
||||||
this.coinCache.set(coins.hash, raw);
|
this.coinCache.push(coins.hash, raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1553,10 +1573,10 @@ ChainDB.prototype.disconnectBlock = co(function* disconnectBlock(block) {
|
|||||||
raw = coins.toRaw();
|
raw = coins.toRaw();
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
this.del(layout.c(coins.hash));
|
this.del(layout.c(coins.hash));
|
||||||
this.coinCache.remove(coins.hash);
|
this.coinCache.unpush(coins.hash);
|
||||||
} else {
|
} else {
|
||||||
this.put(layout.c(coins.hash), raw);
|
this.put(layout.c(coins.hash), raw);
|
||||||
this.coinCache.set(coins.hash, raw);
|
this.coinCache.push(coins.hash, raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -262,6 +262,7 @@ TXDB.prototype.open = co(function* open() {
|
|||||||
|
|
||||||
TXDB.prototype.start = function start() {
|
TXDB.prototype.start = function start() {
|
||||||
this.pending = this.state.clone();
|
this.pending = this.state.clone();
|
||||||
|
this.coinCache.start();
|
||||||
return this.wallet.start();
|
return this.wallet.start();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -273,6 +274,7 @@ TXDB.prototype.start = function start() {
|
|||||||
TXDB.prototype.drop = function drop() {
|
TXDB.prototype.drop = function drop() {
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
this.events.length = 0;
|
this.events.length = 0;
|
||||||
|
this.coinCache.drop();
|
||||||
return this.wallet.drop();
|
return this.wallet.drop();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,6 +286,7 @@ TXDB.prototype.drop = function drop() {
|
|||||||
TXDB.prototype.clear = function clear() {
|
TXDB.prototype.clear = function clear() {
|
||||||
this.pending = this.state.clone();
|
this.pending = this.state.clone();
|
||||||
this.events.length = 0;
|
this.events.length = 0;
|
||||||
|
this.coinCache.clear();
|
||||||
return this.wallet.clear();
|
return this.wallet.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -300,6 +303,7 @@ TXDB.prototype.commit = co(function* commit() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
this.events.length = 0;
|
this.events.length = 0;
|
||||||
|
this.coinCache.drop();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +323,7 @@ TXDB.prototype.commit = co(function* commit() {
|
|||||||
|
|
||||||
this.pending = null;
|
this.pending = null;
|
||||||
this.events.length = 0;
|
this.events.length = 0;
|
||||||
|
this.coinCache.commit();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -677,7 +682,7 @@ TXDB.prototype.saveCredit = function saveCredit(credit, path) {
|
|||||||
var raw = credit.toRaw();
|
var raw = credit.toRaw();
|
||||||
this.put(layout.c(prevout.hash, prevout.index), raw);
|
this.put(layout.c(prevout.hash, prevout.index), raw);
|
||||||
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
||||||
this.coinCache.set(key, raw);
|
this.coinCache.push(key, raw);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -691,7 +696,7 @@ TXDB.prototype.removeCredit = function removeCredit(credit, path) {
|
|||||||
var key = prevout.hash + prevout.index;
|
var key = prevout.hash + prevout.index;
|
||||||
this.del(layout.c(prevout.hash, prevout.index));
|
this.del(layout.c(prevout.hash, prevout.index));
|
||||||
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
||||||
this.coinCache.remove(key);
|
this.coinCache.unpush(key);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -369,6 +369,8 @@ WalletDB.prototype.getHeight = co(function* getHeight() {
|
|||||||
WalletDB.prototype.start = function start(wallet) {
|
WalletDB.prototype.start = function start(wallet) {
|
||||||
assert(!wallet.current, 'Batch already started.');
|
assert(!wallet.current, 'Batch already started.');
|
||||||
wallet.current = this.db.batch();
|
wallet.current = this.db.batch();
|
||||||
|
wallet.accountCache.start();
|
||||||
|
wallet.pathCache.start();
|
||||||
return wallet.current;
|
return wallet.current;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -381,6 +383,8 @@ WalletDB.prototype.start = function start(wallet) {
|
|||||||
WalletDB.prototype.drop = function drop(wallet) {
|
WalletDB.prototype.drop = function drop(wallet) {
|
||||||
var batch = this.batch(wallet);
|
var batch = this.batch(wallet);
|
||||||
wallet.current = null;
|
wallet.current = null;
|
||||||
|
wallet.accountCache.drop();
|
||||||
|
wallet.pathCache.drop();
|
||||||
batch.clear();
|
batch.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -392,6 +396,8 @@ WalletDB.prototype.drop = function drop(wallet) {
|
|||||||
|
|
||||||
WalletDB.prototype.clear = function clear(wallet) {
|
WalletDB.prototype.clear = function clear(wallet) {
|
||||||
var batch = this.batch(wallet);
|
var batch = this.batch(wallet);
|
||||||
|
wallet.accountCache.clear();
|
||||||
|
wallet.pathCache.clear();
|
||||||
batch.clear();
|
batch.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -414,11 +420,13 @@ WalletDB.prototype.batch = function batch(wallet) {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype.commit = function commit(wallet) {
|
WalletDB.prototype.commit = co(function* commit(wallet) {
|
||||||
var batch = wallet.current;
|
var batch = wallet.current;
|
||||||
wallet.current = null;
|
wallet.current = null;
|
||||||
return batch.write();
|
yield batch.write();
|
||||||
};
|
wallet.accountCache.commit();
|
||||||
|
wallet.pathCache.commit();
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the bloom filter into memory.
|
* Load the bloom filter into memory.
|
||||||
@ -862,7 +870,7 @@ WalletDB.prototype.saveAccount = function saveAccount(account) {
|
|||||||
batch.put(layout.a(wid, index), account.toRaw());
|
batch.put(layout.a(wid, index), account.toRaw());
|
||||||
batch.put(layout.i(wid, name), U32(index));
|
batch.put(layout.i(wid, name), U32(index));
|
||||||
|
|
||||||
wallet.accountCache.set(index, account);
|
wallet.accountCache.push(index, account);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -947,7 +955,7 @@ WalletDB.prototype.savePath = co(function* savePath(wallet, path) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this.pathMapCache.set(hash, wids);
|
this.pathMapCache.set(hash, wids);
|
||||||
wallet.pathCache.set(hash, path);
|
wallet.pathCache.push(hash, path);
|
||||||
|
|
||||||
batch.put(layout.p(hash), serializeWallets(wids));
|
batch.put(layout.p(hash), serializeWallets(wids));
|
||||||
batch.put(layout.P(wid, hash), path.toRaw());
|
batch.put(layout.P(wid, hash), path.toRaw());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user