|
118 | 118 | addrs |
119 | 119 | (let [na (arrays/make-array (arrays/alength addrs))] |
120 | 120 | (arrays/acopy addrs 0 (arrays/alength addrs) na 0) |
| 121 | + ;; Mark old child address as freed before clearing |
| 122 | + (when (and storage (aget addrs idx)) |
| 123 | + (storage/markFreed storage (aget addrs idx))) |
121 | 124 | (aset na idx nil) |
122 | 125 | na))) |
123 | | - (util/splice addrs idx (inc idx) (arrays/array nil nil))))] |
| 126 | + (let [old-addr (aget addrs idx)] |
| 127 | + ;; Mark old child address as freed before clearing |
| 128 | + (when (and storage old-addr) |
| 129 | + (storage/markFreed storage old-addr)) |
| 130 | + (util/splice addrs idx (inc idx) (arrays/array nil nil)))))] |
124 | 131 | (arrays/array (Branch. (.-level this) new-keys new-children new-addrs (.-settings this)))) |
125 | 132 | (let [middle (arrays/half (arrays/alength new-children)) |
126 | 133 | tmp-addrs (when addrs |
127 | | - (util/splice addrs idx (inc idx) (arrays/array nil nil))) |
| 134 | + (let [old-addr (aget addrs idx)] |
| 135 | + ;; Mark old child address as freed before clearing |
| 136 | + (when (and storage old-addr) |
| 137 | + (storage/markFreed storage old-addr)) |
| 138 | + (util/splice addrs idx (inc idx) (arrays/array nil nil)))) |
128 | 139 | left-addrs (when tmp-addrs (.slice tmp-addrs 0 middle)) |
129 | 140 | right-addrs (when tmp-addrs (.slice tmp-addrs middle))] |
130 | 141 | (arrays/array |
|
166 | 177 | (let [alen (arrays/alength disjoined) |
167 | 178 | repl (arrays/make-array alen) |
168 | 179 | laddr (when left-child (arrays/aget addrs left-idx)) |
169 | | - raddr (when right-child (arrays/aget addrs (dec right-idx)))] |
170 | | - (when (and left-child (> alen 1) |
171 | | - (identical? (arrays/aget disjoined 0) left-child)) |
| 180 | + raddr (when right-child (arrays/aget addrs (dec right-idx))) |
| 181 | + left-unchanged (and left-child (> alen 1) |
| 182 | + (identical? (arrays/aget disjoined 0) left-child)) |
| 183 | + right-unchanged (and right-child (> alen 1) |
| 184 | + (identical? (arrays/aget disjoined (dec alen)) right-child))] |
| 185 | + ;; Mark freed addresses before clearing |
| 186 | + (when storage |
| 187 | + (dotimes [i (- right-idx left-idx)] |
| 188 | + (let [addr-idx (+ left-idx i) |
| 189 | + old-addr (arrays/aget addrs addr-idx)] |
| 190 | + (when (and old-addr |
| 191 | + (not (and (= addr-idx left-idx) left-unchanged)) |
| 192 | + (not (and (= addr-idx (dec right-idx)) right-unchanged))) |
| 193 | + (storage/markFreed storage old-addr))))) |
| 194 | + (when left-unchanged |
172 | 195 | (aset repl 0 laddr)) |
173 | | - (when (and right-child (> alen 1) |
174 | | - (identical? (arrays/aget disjoined (dec alen)) right-child)) |
| 196 | + (when right-unchanged |
175 | 197 | (aset repl (dec alen) raddr)) |
176 | 198 | (util/splice addrs left-idx right-idx repl)))] |
177 | 199 | (util/rotate (Branch. (.-level this) new-keys new-kids new-addrs (.-settings this)) |
|
218 | 240 | (do |
219 | 241 | (aset keys idx new-max-key) |
220 | 242 | (aset children idx new-node) |
221 | | - (when addrs (aset addrs idx nil)) |
| 243 | + (when addrs |
| 244 | + ;; Mark old child address as freed before clearing |
| 245 | + (when (and storage (aget addrs idx)) |
| 246 | + (storage/markFreed storage (aget addrs idx))) |
| 247 | + (aset addrs idx nil)) |
222 | 248 | (arrays/array this)) |
223 | 249 | ;; Persistent: clone arrays |
224 | 250 | (let [new-keys (arrays/aclone keys) |
225 | 251 | new-children (arrays/aclone children) |
226 | 252 | new-addrs (when addrs |
227 | 253 | (let [na (arrays/aclone addrs)] |
| 254 | + ;; Mark old child address as freed before clearing |
| 255 | + (when (and storage (aget addrs idx)) |
| 256 | + (storage/markFreed storage (aget addrs idx))) |
228 | 257 | (aset na idx nil) |
229 | 258 | na))] |
230 | 259 | (aset new-keys idx new-max-key) |
|
235 | 264 | ;; Transient: mutate in place |
236 | 265 | (do |
237 | 266 | (aset children idx new-node) |
238 | | - (when addrs (aset addrs idx nil)) |
| 267 | + (when addrs |
| 268 | + ;; Mark old child address as freed before clearing |
| 269 | + (when (and storage (aget addrs idx)) |
| 270 | + (storage/markFreed storage (aget addrs idx))) |
| 271 | + (aset addrs idx nil)) |
239 | 272 | (if last-child? |
240 | 273 | (arrays/array this) ; Last child, need to propagate |
241 | 274 | :early-exit)) ; Not last child, early exit |
242 | 275 | ;; Persistent: clone children array |
243 | 276 | (let [new-children (arrays/aclone children) |
244 | 277 | new-addrs (when addrs |
245 | 278 | (let [na (arrays/aclone addrs)] |
| 279 | + ;; Mark old child address as freed before clearing |
| 280 | + (when (and storage (aget addrs idx)) |
| 281 | + (storage/markFreed storage (aget addrs idx))) |
246 | 282 | (aset na idx nil) |
247 | 283 | na))] |
248 | 284 | (aset new-children idx new-node) |
|
0 commit comments