Skip to content

Commit 4bd71f7

Browse files
committed
refactor(client): replace query queue array with Deque for O(1) operations
1 parent ecff60d commit 4bd71f7

2 files changed

Lines changed: 55 additions & 6 deletions

File tree

packages/pg/lib/client.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const Query = require('./query')
1111
const defaults = require('./defaults')
1212
const Connection = require('./connection')
1313
const crypto = require('./crypto/utils')
14+
const Deque = require('./deque')
1415

1516
const activeQueryDeprecationNotice = nodeUtils.deprecate(
1617
() => {},
@@ -79,7 +80,7 @@ class Client extends EventEmitter {
7980
keepAliveInitialDelayMillis: c.keepAliveInitialDelayMillis || 0,
8081
encoding: this.connectionParameters.client_encoding || 'utf8',
8182
})
82-
this._queryQueue = []
83+
this._queryQueue = new Deque()
8384
this.binary = c.binary || defaults.binary
8485
this.processID = null
8586
this.secretKey = null
@@ -124,7 +125,7 @@ class Client extends EventEmitter {
124125
}
125126

126127
this._queryQueue.forEach(enqueueError)
127-
this._queryQueue.length = 0
128+
this._queryQueue.clear()
128129
}
129130

130131
_connect(callback) {
@@ -608,10 +609,7 @@ class Client extends EventEmitter {
608609
query.callback = () => {}
609610

610611
// Remove from queue
611-
const index = this._queryQueue.indexOf(query)
612-
if (index > -1) {
613-
this._queryQueue.splice(index, 1)
614-
}
612+
this._queryQueue.remove(query)
615613

616614
this._pulseQueryQueue()
617615
}, readTimeout)

packages/pg/lib/deque.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
class Deque {
2+
constructor() {
3+
this._store = Object.create(null)
4+
this._head = 0
5+
this._tail = 0
6+
}
7+
8+
push(item) {
9+
this._store[this._tail++] = item
10+
}
11+
12+
shift() {
13+
if (this._head === this._tail) return undefined
14+
const item = this._store[this._head]
15+
delete this._store[this._head++]
16+
return item
17+
}
18+
19+
get length() {
20+
return this._tail - this._head
21+
}
22+
23+
clear() {
24+
this._store = Object.create(null)
25+
this._head = 0
26+
this._tail = 0
27+
}
28+
29+
remove(item) {
30+
const newStore = Object.create(null)
31+
const newHead = 0
32+
let newTail = 0
33+
for (let i = this._head; i < this._tail; i++) {
34+
const current = this._store[i]
35+
if (current !== item) {
36+
newStore[newTail++] = current
37+
}
38+
}
39+
this._store = newStore
40+
this._head = newHead
41+
this._tail = newTail
42+
}
43+
44+
forEach(fn) {
45+
for (let i = this._head; i < this._tail; i++) {
46+
fn(this._store[i], i)
47+
}
48+
}
49+
}
50+
51+
module.exports = Deque

0 commit comments

Comments
 (0)