-
Notifications
You must be signed in to change notification settings - Fork 1
/
lazyList.js
108 lines (91 loc) · 2.62 KB
/
lazyList.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
* @author Derrick Burns
*/
/*
* LazyList - a list that supports insertion, deletion, contains, and deleteAll in constant time per operation and
* constant space per object on the list
*
* N.B. - LazyList adds properties to the objects that it manages in order to give the constant time behavior
*
* We could replace this with a hash table, if the requestor were to provide a hash function on objects.
* I haven't seen that used very much in Javascript yet.
*/
LazyList = function( name ) {
this.seqNo = 0;
this.lastGoodSeqNo = 0;
this.list = [];
this.name = name;
this.indexProp = "__LL_" + this.name + "_index";
this.seqNoProp = "__LL_" + this.name + "_seqNo";
};
LazyList.prototype = {
/*
* PUBLIC methods
*/
push: function( obj ) {
this.setIndex( obj, this.list.length );
this.setSeqNo( obj, this.seqNo++ );
this.list.push( obj );
return obj;
},
remove: function( obj ) {
if( this.contains( obj ) ) {
var index = this.getIndex( obj );
if( index !== this.list.length-1 ) {
this.list[index] = this.list.pop();
this.setIndex( this.list[index], index );
} else {
this.list.pop();
}
this.setIndex( obj, -1 );
return obj;
}
return null;
},
removeAll: function() {
this.list.length = 0;
this.lastGoodSeqNo = this.seqNo;
},
contains: function ( obj ) {
if( this.indexProp in obj ) {
var index = this.getIndex( obj );
if( index === -1 ) {
return false;
}
var seqNo = this.getSeqNo( obj );
return seqNo >= this.lastGoodSeqNo;
} else {
return false;
}
},
isEmpty: function() {
return this.list.length === 0;
},
pop: function() {
return this.isEmpty() ? null : this.remove( this.list[this.list.length-1] );
},
toArray: function() {
return this.list;
},
toString: function() {
return this.list.toString();
},
/*
* PRIVATE methods - these could be replaced with a hash table lookup, followed by a property lookup
*/
getSeqNo : function ( obj ) {
return obj[this.seqNoProp];
},
setSeqNo : function ( obj, seqNo ) {
obj[this.seqNoProp] = seqNo;
},
getIndex : function ( obj ) {
return obj[this.indexProp];
},
setIndex : function ( obj, index ) {
obj[this.indexProp] = index;
}
};
exports = {
LazyList: LazyList
};