@@ -301,27 +301,30 @@ func (root *mTreap) removeNode(t *treapNode) {
301
301
// find searches for, finds, and returns the treap iterator representing
302
302
// the position of the smallest span that can hold npages. If no span has
303
303
// at least npages it returns an invalid iterator.
304
- // This is slightly more complicated than a simple binary tree search
305
- // since if an exact match is not found the next larger node is
306
- // returned.
307
- // TODO(mknyszek): It turns out this routine does not actually find the
308
- // best-fit span, so either fix that or move to something else first, and
309
- // evaluate the performance implications of doing so.
304
+ // This is a simple binary tree search that tracks the best-fit node found
305
+ // so far. The best-fit node is guaranteed to be on the path to a
306
+ // (maybe non-existent) lowest-base exact match.
310
307
func (root * mTreap ) find (npages uintptr ) treapIter {
308
+ var best * treapNode
311
309
t := root .treap
312
310
for t != nil {
313
311
if t .spanKey == nil {
314
312
throw ("treap node with nil spanKey found" )
315
313
}
316
- if t .npagesKey < npages {
317
- t = t .right
318
- } else if t .left != nil && t .left .npagesKey >= npages {
314
+ // If we found an exact match, try to go left anyway. There could be
315
+ // a span there with a lower base address.
316
+ //
317
+ // Don't bother checking nil-ness of left and right here; even if t
318
+ // becomes nil, we already know the other path had nothing better for
319
+ // us anyway.
320
+ if t .npagesKey >= npages {
321
+ best = t
319
322
t = t .left
320
323
} else {
321
- return treapIter { t }
324
+ t = t . right
322
325
}
323
326
}
324
- return treapIter {}
327
+ return treapIter {best }
325
328
}
326
329
327
330
// removeSpan searches for, finds, deletes span along with
0 commit comments