-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintersect.js
91 lines (80 loc) · 2.18 KB
/
intersect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
var Cursor = require('./cursor')
var CursorStream = require('./stream')
var cmp = require('./cmp')
function Intersect (blocks, cursors, reverse, limit, query) {
this.cursors = cursors
this.value = 0
this.ended = false
this.matched = false
this.reverse = !!reverse
CursorStream.call(this, limit)
this._blocks = blocks
this.max = this.reverse ? Infinity : 0
this.query = query
}
Intersect.prototype = new CursorStream()
Intersect.prototype.ready = function () {
// if(this.ended) return false
this.max = 0 //this.reverse ? -Infinity : Infinity
for(var i = 0; i < this.cursors.length; i++) {
this.ended = this.ended || this.cursors[i].isEnded()
if(!this.cursors[i].ready()) {
return false
}
var value = this.cursors[i].value
this.max = cmp.lt(value, this.max, this.reverse) ? value : this.max
}
var max = this.max, cursors = this.cursors
var loop = true
while(loop) {
loop = false
for(var i = 0; i < cursors.length; i++) {
//TODO: skip forward, rather than just step forward.
while(cmp.lt(cursors[i].value, max, this.reverse)) {
cursors[i].next()
this.ended = this.ended || cursors[i].isEnded()
if(!cursors[i].ready()) return 0
}
if(cmp.gt(cursors[i].value, max, this.reverse)) {
max = cursors[i].value
loop = true
break;
}
}
this.value = max
}
return !this.ended
}
Intersect.prototype.next = function () {
const cursors = this.cursors
if(!this.ready()) throw new Error('next called when not ready')
var value = this.value //cursors[0].value
for(var i = 0; i < cursors.length; i++) {
cursors[i].next()
this.ended = this.ended || cursors[i].isEnded()
}
return this.value = value
}
Intersect.prototype.update = function (cb) {
const self = this
const cursors = this.cursors
var c = 1
for(var i = 0; i < cursors.length; i++) {
var cursor = cursors[i]
if(cursor.isEnded()) {
this.ended = true
}
if(!cursor.ready()) {
c++; cursor.update(done)
}
}
done()
function done (_, block) {
if(--c) return
cb()
}
}
Intersect.prototype.isEnded = function () {
return this.ended
}
module.exports = Intersect