@@ -43,7 +43,7 @@ object RedBlackTree {
43
43
}
44
44
45
45
def count (tree : Tree [_, _]) = if (tree eq null ) 0 else tree.count
46
- def update [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = blacken(upd(tree, k, v))
46
+ def update [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 , overwrite : Boolean )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = blacken(upd(tree, k, v, overwrite ))
47
47
def delete [A , B ](tree : Tree [A , B ], k : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = blacken(del(tree, k))
48
48
def rangeImpl [A : Ordering , B ](tree : Tree [A , B ], from : Option [A ], until : Option [A ]): Tree [A , B ] = (from, until) match {
49
49
case (Some (from), Some (until)) => this .range(tree, from, until)
@@ -122,17 +122,18 @@ object RedBlackTree {
122
122
else
123
123
mkTree(isBlack, x, xv, a, r)
124
124
}
125
- private [this ] def upd [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = if (tree eq null ) {
125
+ private [this ] def upd [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 , overwrite : Boolean )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = if (tree eq null ) {
126
126
RedTree (k, v, null , null )
127
127
} else {
128
128
val cmp = ordering.compare(k, tree.key)
129
- if (cmp < 0 ) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v), tree.right)
130
- else if (cmp > 0 ) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v))
131
- else mkTree(isBlackTree(tree), k, v, tree.left, tree.right)
129
+ if (cmp < 0 ) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right)
130
+ else if (cmp > 0 ) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite))
131
+ else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right)
132
+ else tree
132
133
}
133
134
134
- // Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees
135
- // http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html
135
+ /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees
136
+ * http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html */
136
137
private [this ] def del [A , B ](tree : Tree [A , B ], k : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = if (tree eq null ) null else {
137
138
def balance (x : A , xv : B , tl : Tree [A , B ], tr : Tree [A , B ]) = if (isRedTree(tl)) {
138
139
if (isRedTree(tr)) {
@@ -216,23 +217,23 @@ object RedBlackTree {
216
217
if (ordering.lt(tree.key, from)) return doFrom(tree.right, from)
217
218
val newLeft = doFrom(tree.left, from)
218
219
if (newLeft eq tree.left) tree
219
- else if (newLeft eq null ) upd(tree.right, tree.key, tree.value)
220
+ else if (newLeft eq null ) upd(tree.right, tree.key, tree.value, false )
220
221
else rebalance(tree, newLeft, tree.right)
221
222
}
222
223
private [this ] def doTo [A , B ](tree : Tree [A , B ], to : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
223
224
if (tree eq null ) return null
224
225
if (ordering.lt(to, tree.key)) return doTo(tree.left, to)
225
226
val newRight = doTo(tree.right, to)
226
227
if (newRight eq tree.right) tree
227
- else if (newRight eq null ) upd(tree.left, tree.key, tree.value)
228
+ else if (newRight eq null ) upd(tree.left, tree.key, tree.value, false )
228
229
else rebalance(tree, tree.left, newRight)
229
230
}
230
231
private [this ] def doUntil [A , B ](tree : Tree [A , B ], until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
231
232
if (tree eq null ) return null
232
233
if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until)
233
234
val newRight = doUntil(tree.right, until)
234
235
if (newRight eq tree.right) tree
235
- else if (newRight eq null ) upd(tree.left, tree.key, tree.value)
236
+ else if (newRight eq null ) upd(tree.left, tree.key, tree.value, false )
236
237
else rebalance(tree, tree.left, newRight)
237
238
}
238
239
private [this ] def doRange [A , B ](tree : Tree [A , B ], from : A , until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
@@ -242,8 +243,8 @@ object RedBlackTree {
242
243
val newLeft = doFrom(tree.left, from)
243
244
val newRight = doUntil(tree.right, until)
244
245
if ((newLeft eq tree.left) && (newRight eq tree.right)) tree
245
- else if (newLeft eq null ) upd(newRight, tree.key, tree.value);
246
- else if (newRight eq null ) upd(newLeft, tree.key, tree.value);
246
+ else if (newLeft eq null ) upd(newRight, tree.key, tree.value, false );
247
+ else if (newRight eq null ) upd(newLeft, tree.key, tree.value, false );
247
248
else rebalance(tree, newLeft, newRight)
248
249
}
249
250
@@ -254,7 +255,7 @@ object RedBlackTree {
254
255
if (n > count) return doDrop(tree.right, n - count - 1 )
255
256
val newLeft = doDrop(tree.left, n)
256
257
if (newLeft eq tree.left) tree
257
- else if (newLeft eq null ) upd(tree.right, tree.key, tree.value)
258
+ else if (newLeft eq null ) upd(tree.right, tree.key, tree.value, false )
258
259
else rebalance(tree, newLeft, tree.right)
259
260
}
260
261
private [this ] def doTake [A : Ordering , B ](tree : Tree [A , B ], n : Int ): Tree [A , B ] = {
@@ -264,7 +265,7 @@ object RedBlackTree {
264
265
if (n <= count) return doTake(tree.left, n)
265
266
val newRight = doTake(tree.right, n - count - 1 )
266
267
if (newRight eq tree.right) tree
267
- else if (newRight eq null ) upd(tree.left, tree.key, tree.value)
268
+ else if (newRight eq null ) upd(tree.left, tree.key, tree.value, false )
268
269
else rebalance(tree, tree.left, newRight)
269
270
}
270
271
private [this ] def doSlice [A : Ordering , B ](tree : Tree [A , B ], from : Int , until : Int ): Tree [A , B ] = {
@@ -275,8 +276,8 @@ object RedBlackTree {
275
276
val newLeft = doDrop(tree.left, from)
276
277
val newRight = doTake(tree.right, until - count - 1 )
277
278
if ((newLeft eq tree.left) && (newRight eq tree.right)) tree
278
- else if (newLeft eq null ) upd(newRight, tree.key, tree.value)
279
- else if (newRight eq null ) upd(newLeft, tree.key, tree.value)
279
+ else if (newLeft eq null ) upd(newRight, tree.key, tree.value, false )
280
+ else if (newRight eq null ) upd(newLeft, tree.key, tree.value, false )
280
281
else rebalance(tree, newLeft, newRight)
281
282
}
282
283
0 commit comments