Skip to content

Commit 4b3f04c

Browse files
committed
runtime: make mTreap iterator bidirectional
This change makes mTreap's iterator type, treapIter, bidirectional instead of unidirectional. This change helps support moving the find operation on a treap to return an iterator instead of a treapNode, in order to hide the details of the treap when accessing elements. For #28479. Change-Id: I5dbea4fd4fb9bede6e81bfd089f2368886f98943 Reviewed-on: https://go-review.googlesource.com/c/156918 Reviewed-by: Austin Clements <[email protected]> Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 44cf595 commit 4b3f04c

File tree

3 files changed

+34
-36
lines changed

3 files changed

+34
-36
lines changed

src/runtime/export_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ func ReadMemStatsSlow() (base, slow MemStats) {
337337
slow.BySize[i].Frees = bySize[i].Frees
338338
}
339339

340-
for i := mheap_.scav.iter(); i.valid(); i = i.next() {
340+
for i := mheap_.scav.start(); i.valid(); i = i.next() {
341341
slow.HeapReleased += uint64(i.span().released())
342342
}
343343

src/runtime/mgclarge.go

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,14 @@ func checkTreapNode(t *treapNode) {
153153
}
154154
}
155155

156-
// treapIter is a unidirectional iterator type which may be used to iterate over a
156+
// treapIter is a bidirectional iterator type which may be used to iterate over a
157157
// an mTreap in-order forwards (increasing order) or backwards (decreasing order).
158158
// Its purpose is to hide details about the treap from users when trying to iterate
159159
// over it.
160160
//
161-
// To create iterators over the treap, call iter or rev on an mTreap.
161+
// To create iterators over the treap, call start or end on an mTreap.
162162
type treapIter struct {
163-
t *treapNode
164-
inc bool // if true, iterate in increasing order, otherwise decreasing order.
163+
t *treapNode
165164
}
166165

167166
// span returns the span at the current position in the treap.
@@ -179,42 +178,41 @@ func (i *treapIter) valid() bool {
179178
// next moves the iterator forward by one. Once the iterator
180179
// ceases to be valid, calling next will panic.
181180
func (i treapIter) next() treapIter {
182-
if i.inc {
183-
i.t = i.t.succ()
184-
} else {
185-
i.t = i.t.pred()
186-
}
181+
i.t = i.t.succ()
187182
return i
188183
}
189184

190-
// iter returns an iterator which may be used to iterate over the treap
191-
// in increasing order of span size ("forwards").
192-
func (root *mTreap) iter() treapIter {
193-
i := treapIter{inc: true}
185+
// prev moves the iterator backwards by one. Once the iterator
186+
// ceases to be valid, calling prev will panic.
187+
func (i treapIter) prev() treapIter {
188+
i.t = i.t.pred()
189+
return i
190+
}
191+
192+
// start returns an iterator which points to the start of the treap (the
193+
// left-most node in the treap).
194+
func (root *mTreap) start() treapIter {
194195
t := root.treap
195196
if t == nil {
196-
return i
197+
return treapIter{}
197198
}
198199
for t.left != nil {
199200
t = t.left
200201
}
201-
i.t = t
202-
return i
202+
return treapIter{t: t}
203203
}
204204

205-
// rev returns an iterator which may be used to iterate over the treap
206-
// in decreasing order of span size ("reverse").
207-
func (root *mTreap) rev() treapIter {
208-
i := treapIter{inc: false}
205+
// end returns an iterator which points to the end of the treap (the
206+
// right-most node in the treap).
207+
func (root *mTreap) end() treapIter {
209208
t := root.treap
210209
if t == nil {
211-
return i
210+
return treapIter{}
212211
}
213212
for t.right != nil {
214213
t = t.right
215214
}
216-
i.t = t
217-
return i
215+
return treapIter{t: t}
218216
}
219217

220218
// insert adds span to the large span treap.
@@ -342,13 +340,11 @@ func (root *mTreap) removeSpan(span *mspan) {
342340
}
343341

344342
// erase removes the element referred to by the current position of the
345-
// iterator and returns i.next(). This operation consumes the given
346-
// iterator, so it should no longer be used and iteration should continue
347-
// from the returned iterator.
348-
func (root *mTreap) erase(i treapIter) treapIter {
349-
n := i.next()
343+
// iterator. This operation consumes the given iterator, so it should no
344+
// longer be used. It is up to the caller to get the next or previous
345+
// iterator before calling erase, if need be.
346+
func (root *mTreap) erase(i treapIter) {
350347
root.removeNode(i.t)
351-
return n
352348
}
353349

354350
// rotateLeft rotates the tree rooted at node x.

src/runtime/mheap.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,7 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
12871287
// Iterate over the treap backwards (from largest to smallest) scavenging spans
12881288
// until we've reached our quota of nbytes.
12891289
released := uintptr(0)
1290-
for t := h.free.rev(); released < nbytes && t.valid(); {
1290+
for t := h.free.end(); released < nbytes && t.valid(); {
12911291
s := t.span()
12921292
r := s.scavenge()
12931293
if r == 0 {
@@ -1302,7 +1302,9 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
13021302
// those which have it unset are only in the `free` treap.
13031303
return
13041304
}
1305-
t = h.free.erase(t)
1305+
n := t.prev()
1306+
h.free.erase(t)
1307+
t = n
13061308
h.scav.insert(s)
13071309
released += r
13081310
}
@@ -1314,18 +1316,18 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
13141316
func (h *mheap) scavengeAll(now, limit uint64) uintptr {
13151317
// Iterate over the treap scavenging spans if unused for at least limit time.
13161318
released := uintptr(0)
1317-
for t := h.free.iter(); t.valid(); {
1319+
for t := h.free.start(); t.valid(); {
13181320
s := t.span()
1321+
n := t.next()
13191322
if (now - uint64(s.unusedsince)) > limit {
13201323
r := s.scavenge()
13211324
if r != 0 {
1322-
t = h.free.erase(t)
1325+
h.free.erase(t)
13231326
h.scav.insert(s)
13241327
released += r
1325-
continue
13261328
}
13271329
}
1328-
t = t.next()
1330+
t = n
13291331
}
13301332
return released
13311333
}

0 commit comments

Comments
 (0)