     result
 
   clear: ->
+    @rootNode = new Leaf(Point.infinity(), new Set)
     @exclusiveIds = new Set
-    @rootNode = new Leaf(Point.infinity(), new Set)
+    @clearRangeCache()
 
   dump: ->
-    snapshot = {}
-    @rootNode.dump(Point.zero(), snapshot)
-    snapshot
+    unless @rangeCacheFresh
+      @rootNode.dump(Point.zero(), @rangeCache)
+      @rangeCacheFresh = true
+    @rangeCache
 
   ###
   Section: Private
   ###
+
+  clearRangeCache: ->
+    @rangeCache = {}
+    @rootNode.ids.forEach (id) => @rangeCache[id] = templateRange()
+    @rangeCacheFresh = false
 
   condenseIfNeeded: ->
     while @rootNode.children?.length is 1

Range = require "./range"
{addSet, subtractSet, intersectSet, setEqual} = require "./set-helpers"

BRANCHING_THRESHOLD = 3

class Node

  dump: (offset, snapshot) ->
    end = offset.traverse(@extent)
    @ids.forEach (id) ->
      snapshot[id].start ?= offset
      snapshot[id].end = end
    end

  findContaining: (point, set) ->
