implemented small lookup buffer. This heavily improves lookups for slow databases
This commit is contained in:
parent
37ac7787d0
commit
1b3f5443b3
@ -403,16 +403,12 @@ module.exports = function (Y /* :any */) {
|
||||
}
|
||||
}
|
||||
requestTransaction (makeGen/* :any */, callImmediately) {
|
||||
if (false || callImmediately) { // TODO: decide whether this is ok or not..
|
||||
this.waitingTransactions.push(makeGen)
|
||||
if (!this.transactionInProgress) {
|
||||
this.transactionInProgress = true
|
||||
this.waitingTransactions.push(makeGen)
|
||||
if (!this.transactionInProgress) {
|
||||
this.transactionInProgress = true
|
||||
if (true || callImmediately) { // TODO: decide whether this is ok or not..
|
||||
this.transact(this.getNextRequest())
|
||||
}
|
||||
} else {
|
||||
this.waitingTransactions.push(makeGen)
|
||||
if (!this.transactionInProgress) {
|
||||
this.transactionInProgress = true
|
||||
} else {
|
||||
var self = this
|
||||
setTimeout(function () {
|
||||
self.transact(self.getNextRequest())
|
||||
|
160
src/Utils.js
160
src/Utils.js
@ -225,4 +225,164 @@ module.exports = function (Y /* : any*/) {
|
||||
}
|
||||
}
|
||||
Y.utils.compareIds = compareIds
|
||||
|
||||
function createEmptyOpsArray (n) {
|
||||
var a = new Array(n)
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
a[i] = {
|
||||
id: [null, null]
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
function createSmallLookupBuffer (Store) {
|
||||
/*
|
||||
This buffer implements a very small buffer that temporarily stores operations
|
||||
after they are read / before they are written.
|
||||
The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.
|
||||
|
||||
It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.
|
||||
|
||||
Good for os and ss, bot not for ds (because it often uses methods that require a flush)
|
||||
|
||||
I tried to optimize this for performance, therefore no highlevel operations.
|
||||
*/
|
||||
class SmallLookupBuffer extends Store {
|
||||
constructor (read, write) {
|
||||
super()
|
||||
this.writeBuffer = createEmptyOpsArray(5)
|
||||
this.readBuffer = createEmptyOpsArray(10)
|
||||
}
|
||||
* find (id) {
|
||||
var i, r
|
||||
for (i = this.readBuffer.length - 1; i >= 0; i--) {
|
||||
r = this.readBuffer[i]
|
||||
// we don't have to use compareids, because id is always defined!
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
// found r
|
||||
// move r to the end of readBuffer
|
||||
for (; i < this.readBuffer.length - 1; i++) {
|
||||
this.readBuffer[i] = this.readBuffer[i + 1]
|
||||
}
|
||||
this.readBuffer[this.readBuffer.length - 1] = r
|
||||
return r
|
||||
}
|
||||
}
|
||||
var o
|
||||
for (i = this.writeBuffer.length - 1; i >= 0; i--) {
|
||||
r = this.writeBuffer[i]
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
o = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if (i < 0) {
|
||||
// did not reach break in last loop
|
||||
// read id and put it to the end of readBuffer
|
||||
o = yield* super.find(id)
|
||||
}
|
||||
if (o != null) {
|
||||
for (i = 0; i < this.readBuffer.length - 1; i++) {
|
||||
this.readBuffer[i] = this.readBuffer[i + 1]
|
||||
}
|
||||
this.readBuffer[this.readBuffer.length - 1] = o
|
||||
}
|
||||
return o
|
||||
}
|
||||
* put (o) {
|
||||
var id = o.id
|
||||
var i, r // helper variables
|
||||
for (i = this.writeBuffer.length - 1; i >= 0; i--) {
|
||||
r = this.writeBuffer[i]
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
// is already in buffer
|
||||
// forget r, and move o to the end of writeBuffer
|
||||
for (; i < this.writeBuffer.length - 1; i++) {
|
||||
this.writeBuffer[i] = this.writeBuffer[i + 1]
|
||||
}
|
||||
this.writeBuffer[this.writeBuffer.length - 1] = o
|
||||
break
|
||||
}
|
||||
}
|
||||
if (i < 0) {
|
||||
// did not reach break in last loop
|
||||
// write writeBuffer[0]
|
||||
var write = this.writeBuffer[0]
|
||||
if (write.id[0] !== null) {
|
||||
yield* super.put(write)
|
||||
}
|
||||
// put o to the end of writeBuffer
|
||||
for (i = 0; i < this.writeBuffer.length - 1; i++) {
|
||||
this.writeBuffer[i] = this.writeBuffer[i + 1]
|
||||
}
|
||||
this.writeBuffer[this.writeBuffer.length - 1] = o
|
||||
}
|
||||
// check readBuffer for every occurence of o.id, overwrite if found
|
||||
// whether found or not, we'll append o to the readbuffer
|
||||
for (i = 0; i < this.readBuffer.length - 1; i++) {
|
||||
r = this.readBuffer[i + 1]
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
this.readBuffer[i] = o
|
||||
} else {
|
||||
this.readBuffer[i] = r
|
||||
}
|
||||
}
|
||||
this.readBuffer[this.readBuffer.length - 1] = o
|
||||
}
|
||||
* delete (id) {
|
||||
var i, r
|
||||
for (i = 0; i < this.readBuffer.length; i++) {
|
||||
r = this.readBuffer[i]
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
this.readBuffer[i] = {
|
||||
id: [null, null]
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < this.writeBuffer.length; i++) {
|
||||
r = this.writeBuffer[i]
|
||||
if (r.id[1] === id[1] && r.id[0] === id[0]) {
|
||||
this.writeBuffer[i] = {
|
||||
id: [null, null]
|
||||
}
|
||||
}
|
||||
}
|
||||
yield* super.delete(id)
|
||||
}
|
||||
* findWithLowerBound () {
|
||||
yield* this.flush()
|
||||
return yield* super.findWithLowerBound.apply(this, arguments)
|
||||
}
|
||||
* findWithUpperBound () {
|
||||
yield* this.flush()
|
||||
return yield* super.findWithUpperBound.apply(this, arguments)
|
||||
}
|
||||
* findNext () {
|
||||
yield* this.flush()
|
||||
return yield* super.findNext.apply(this, arguments)
|
||||
}
|
||||
* findPrev () {
|
||||
yield* this.flush()
|
||||
return yield* super.findPrev.apply(this, arguments)
|
||||
}
|
||||
* iterate () {
|
||||
yield* this.flush()
|
||||
yield* super.iterate.apply(this, arguments)
|
||||
}
|
||||
* flush () {
|
||||
for (var i = 0; i < this.writeBuffer.length; i++) {
|
||||
var write = this.writeBuffer[i]
|
||||
if (write.id[0] !== null) {
|
||||
yield* super.put(write)
|
||||
this.writeBuffer[i] = {
|
||||
id: [null, null]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SmallLookupBuffer
|
||||
}
|
||||
Y.utils.createSmallLookupBuffer = createSmallLookupBuffer
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user