@@ -77,7 +77,7 @@ interface UMemoryUpdates<Key, Sort : USort> : Sequence<UUpdateNode<Key, Sort>> {
77
77
78
78
/* *
79
79
* Accepts the [visitor]. Implementations should call [UMemoryUpdatesVisitor.visitInitialValue] firstly, then call
80
- * [UMemoryUpdatesVisitor.visitUpdateNode ] in the chronological order
80
+ * [UMemoryUpdatesVisitor.visitUpdate ] in the chronological order
81
81
* (from the oldest to the newest) with accumulated [Result].
82
82
*
83
83
* Uses [lookupCache] to shortcut the traversal. The actual key is determined by the
@@ -183,6 +183,11 @@ class UFlatUpdates<Key, Sort : USort> private constructor(
183
183
val mappedNode = node.update.map(keyMapper, composer)
184
184
val mappedNext = node.next.map(keyMapper, composer)
185
185
186
+ // Doesn't apply the node, if its guard maps to `false`
187
+ if (mappedNode.guard.isFalse) {
188
+ return mappedNext
189
+ }
190
+
186
191
// If nothing changed, return this updates
187
192
if (mappedNode == = node.update && mappedNext == = node.next) {
188
193
return this
@@ -250,7 +255,7 @@ class UFlatUpdates<Key, Sort : USort> private constructor(
250
255
// region Tree memory updates
251
256
252
257
data class UTreeUpdates <Key , Reg : Region <Reg >, Sort : USort >(
253
- private val updates : RegionTree <UUpdateNode <Key , Sort >, Reg >,
258
+ private val updates : RegionTree <Reg , UUpdateNode <Key , Sort >>,
254
259
private val keyToRegion : (Key ) -> Reg ,
255
260
private val keyRangeToRegion : (Key , Key ) -> Reg ,
256
261
private val symbolicEq : (Key , Key ) -> UBoolExpr ,
@@ -259,7 +264,7 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
259
264
) : UMemoryUpdates<Key, Sort> {
260
265
override fun read (key : Key ): UTreeUpdates <Key , Reg , Sort > {
261
266
val reg = keyToRegion(key)
262
- val updates = updates.localize(reg)
267
+ val updates = updates.localize(reg) { it.includesSymbolically(key).isFalse }
263
268
if (updates == = this .updates) {
264
269
return this
265
270
}
@@ -272,7 +277,7 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
272
277
val newUpdates = updates.write(
273
278
keyToRegion(key),
274
279
update,
275
- keyFilter = { it.isIncludedByUpdateConcretely(update) }
280
+ valueFilter = { it.isIncludedByUpdateConcretely(update) }
276
281
)
277
282
278
283
return this .copy(updates = newUpdates)
@@ -290,7 +295,7 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
290
295
val newUpdates = updates.write(
291
296
region,
292
297
update,
293
- keyFilter = { it.isIncludedByUpdateConcretely(update) }
298
+ valueFilter = { it.isIncludedByUpdateConcretely(update) }
294
299
)
295
300
296
301
return this .copy(updates = newUpdates)
@@ -306,15 +311,15 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
306
311
val updatesSuffix = mutableListOf<UUpdateNode <Key , Sort >? > ()
307
312
308
313
// reconstructed region tree, including all updates unsatisfying `predicate(update.value(key))` in the same order
309
- var splitUpdates = emptyRegionTree<UUpdateNode <Key , Sort >, Reg > ()
314
+ var splitUpdates = emptyRegionTree<Reg , UUpdateNode <Key , Sort >>()
310
315
311
316
// add an update to result tree
312
317
fun applyUpdate (update : UUpdateNode <Key , Sort >) {
313
318
val region = when (update) {
314
319
is UPinpointUpdateNode <Key , Sort > -> keyToRegion(update.key)
315
320
is URangedUpdateNode <* , * , Key , Sort > -> keyRangeToRegion(update.fromKey, update.toKey)
316
321
}
317
- splitUpdates = splitUpdates.write(region, update, keyFilter = { it.isIncludedByUpdateConcretely(update) })
322
+ splitUpdates = splitUpdates.write(region, update, valueFilter = { it.isIncludedByUpdateConcretely(update) })
318
323
}
319
324
320
325
// traverse all updates one by one from the oldest one
@@ -366,31 +371,35 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
366
371
var mappedNodeFound = false
367
372
368
373
// Traverse [updates] using its iterator and fold them into a new updates tree with new mapped nodes
369
- val initialEmptyTree = emptyRegionTree<UUpdateNode <Key , Sort >, Reg > ()
374
+ val initialEmptyTree = emptyRegionTree<Reg , UUpdateNode <Key , Sort >>()
370
375
val mappedUpdates = updates.fold(initialEmptyTree) { mappedUpdatesTree, updateNodeWithRegion ->
371
376
val (updateNode, oldRegion) = updateNodeWithRegion
372
377
// Map current node
373
378
val mappedUpdateNode = updateNode.map(keyMapper, composer)
374
379
380
+
375
381
// Save information about whether something changed in the current node or not
376
382
if (mappedUpdateNode != = updateNode) {
377
383
mappedNodeFound = true
378
384
}
379
385
386
+ // Doesn't apply the node, if its guard maps to `false`
387
+ if (mappedUpdateNode.guard.isFalse) {
388
+ return @fold mappedUpdatesTree
389
+ }
390
+
380
391
// Note that following code should be executed after checking for reference equality of a mapped node.
381
392
// Otherwise, it is possible that for a tree with several impossible writes
382
393
// it will be returned as a result, instead of an empty one.
383
394
384
395
// Extract a new region by the mapped node
385
- val newRegion = when (updateNode ) {
396
+ val newRegion = when (mappedUpdateNode ) {
386
397
is UPinpointUpdateNode -> {
387
- mappedUpdateNode as UPinpointUpdateNode
388
398
val currentRegion = keyToRegion(mappedUpdateNode.key)
389
399
oldRegion.intersect(currentRegion)
390
400
}
391
401
392
402
is URangedUpdateNode <* , * , Key , Sort > -> {
393
- mappedUpdateNode as URangedUpdateNode <* , * , Key , Sort >
394
403
val currentRegion = keyRangeToRegion(mappedUpdateNode.fromKey, mappedUpdateNode.toKey)
395
404
oldRegion.intersect(currentRegion)
396
405
}
@@ -512,7 +521,7 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
512
521
* *
513
522
*```
514
523
*/
515
- private fun leftMostFold (updates : RegionTree <UUpdateNode <Key , Sort >, * >): Result {
524
+ private fun leftMostFold (updates : RegionTree <* , UUpdateNode <Key , Sort >>): Result {
516
525
var result = cache[updates]
517
526
518
527
if (result != null ) {
@@ -531,7 +540,7 @@ data class UTreeUpdates<Key, Reg : Region<Reg>, Sort : USort>(
531
540
532
541
private fun notLeftMostFold (
533
542
accumulator : Result ,
534
- iterator : Iterator <Map .Entry <Region <* >, Pair <UUpdateNode <Key , Sort >, RegionTree <UUpdateNode <Key , Sort >, * >>>>,
543
+ iterator : Iterator <Map .Entry <Region <* >, Pair <UUpdateNode <Key , Sort >, RegionTree <* , UUpdateNode <Key , Sort >>>>>,
535
544
): Result {
536
545
var accumulated = accumulator
537
546
while (iterator.hasNext()) {
0 commit comments