Commit 4b3f04c6 authored by Michael Anthony Knyszek's avatar Michael Anthony Knyszek Committed by Michael Knyszek

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/156918Reviewed-by: 's avatarAustin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 44cf595a
...@@ -337,7 +337,7 @@ func ReadMemStatsSlow() (base, slow MemStats) { ...@@ -337,7 +337,7 @@ func ReadMemStatsSlow() (base, slow MemStats) {
slow.BySize[i].Frees = bySize[i].Frees slow.BySize[i].Frees = bySize[i].Frees
} }
for i := mheap_.scav.iter(); i.valid(); i = i.next() { for i := mheap_.scav.start(); i.valid(); i = i.next() {
slow.HeapReleased += uint64(i.span().released()) slow.HeapReleased += uint64(i.span().released())
} }
......
...@@ -153,15 +153,14 @@ func checkTreapNode(t *treapNode) { ...@@ -153,15 +153,14 @@ func checkTreapNode(t *treapNode) {
} }
} }
// treapIter is a unidirectional iterator type which may be used to iterate over a // treapIter is a bidirectional iterator type which may be used to iterate over a
// an mTreap in-order forwards (increasing order) or backwards (decreasing order). // an mTreap in-order forwards (increasing order) or backwards (decreasing order).
// Its purpose is to hide details about the treap from users when trying to iterate // Its purpose is to hide details about the treap from users when trying to iterate
// over it. // over it.
// //
// To create iterators over the treap, call iter or rev on an mTreap. // To create iterators over the treap, call start or end on an mTreap.
type treapIter struct { type treapIter struct {
t *treapNode t *treapNode
inc bool // if true, iterate in increasing order, otherwise decreasing order.
} }
// span returns the span at the current position in the treap. // span returns the span at the current position in the treap.
...@@ -179,42 +178,41 @@ func (i *treapIter) valid() bool { ...@@ -179,42 +178,41 @@ func (i *treapIter) valid() bool {
// next moves the iterator forward by one. Once the iterator // next moves the iterator forward by one. Once the iterator
// ceases to be valid, calling next will panic. // ceases to be valid, calling next will panic.
func (i treapIter) next() treapIter { func (i treapIter) next() treapIter {
if i.inc { i.t = i.t.succ()
i.t = i.t.succ()
} else {
i.t = i.t.pred()
}
return i return i
} }
// iter returns an iterator which may be used to iterate over the treap // prev moves the iterator backwards by one. Once the iterator
// in increasing order of span size ("forwards"). // ceases to be valid, calling prev will panic.
func (root *mTreap) iter() treapIter { func (i treapIter) prev() treapIter {
i := treapIter{inc: true} i.t = i.t.pred()
return i
}
// start returns an iterator which points to the start of the treap (the
// left-most node in the treap).
func (root *mTreap) start() treapIter {
t := root.treap t := root.treap
if t == nil { if t == nil {
return i return treapIter{}
} }
for t.left != nil { for t.left != nil {
t = t.left t = t.left
} }
i.t = t return treapIter{t: t}
return i
} }
// rev returns an iterator which may be used to iterate over the treap // end returns an iterator which points to the end of the treap (the
// in decreasing order of span size ("reverse"). // right-most node in the treap).
func (root *mTreap) rev() treapIter { func (root *mTreap) end() treapIter {
i := treapIter{inc: false}
t := root.treap t := root.treap
if t == nil { if t == nil {
return i return treapIter{}
} }
for t.right != nil { for t.right != nil {
t = t.right t = t.right
} }
i.t = t return treapIter{t: t}
return i
} }
// insert adds span to the large span treap. // insert adds span to the large span treap.
...@@ -342,13 +340,11 @@ func (root *mTreap) removeSpan(span *mspan) { ...@@ -342,13 +340,11 @@ func (root *mTreap) removeSpan(span *mspan) {
} }
// erase removes the element referred to by the current position of the // erase removes the element referred to by the current position of the
// iterator and returns i.next(). This operation consumes the given // iterator. This operation consumes the given iterator, so it should no
// iterator, so it should no longer be used and iteration should continue // longer be used. It is up to the caller to get the next or previous
// from the returned iterator. // iterator before calling erase, if need be.
func (root *mTreap) erase(i treapIter) treapIter { func (root *mTreap) erase(i treapIter) {
n := i.next()
root.removeNode(i.t) root.removeNode(i.t)
return n
} }
// rotateLeft rotates the tree rooted at node x. // rotateLeft rotates the tree rooted at node x.
......
...@@ -1287,7 +1287,7 @@ func (h *mheap) scavengeLargest(nbytes uintptr) { ...@@ -1287,7 +1287,7 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
// Iterate over the treap backwards (from largest to smallest) scavenging spans // Iterate over the treap backwards (from largest to smallest) scavenging spans
// until we've reached our quota of nbytes. // until we've reached our quota of nbytes.
released := uintptr(0) released := uintptr(0)
for t := h.free.rev(); released < nbytes && t.valid(); { for t := h.free.end(); released < nbytes && t.valid(); {
s := t.span() s := t.span()
r := s.scavenge() r := s.scavenge()
if r == 0 { if r == 0 {
...@@ -1302,7 +1302,9 @@ func (h *mheap) scavengeLargest(nbytes uintptr) { ...@@ -1302,7 +1302,9 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
// those which have it unset are only in the `free` treap. // those which have it unset are only in the `free` treap.
return return
} }
t = h.free.erase(t) n := t.prev()
h.free.erase(t)
t = n
h.scav.insert(s) h.scav.insert(s)
released += r released += r
} }
...@@ -1314,18 +1316,18 @@ func (h *mheap) scavengeLargest(nbytes uintptr) { ...@@ -1314,18 +1316,18 @@ func (h *mheap) scavengeLargest(nbytes uintptr) {
func (h *mheap) scavengeAll(now, limit uint64) uintptr { func (h *mheap) scavengeAll(now, limit uint64) uintptr {
// Iterate over the treap scavenging spans if unused for at least limit time. // Iterate over the treap scavenging spans if unused for at least limit time.
released := uintptr(0) released := uintptr(0)
for t := h.free.iter(); t.valid(); { for t := h.free.start(); t.valid(); {
s := t.span() s := t.span()
n := t.next()
if (now - uint64(s.unusedsince)) > limit { if (now - uint64(s.unusedsince)) > limit {
r := s.scavenge() r := s.scavenge()
if r != 0 { if r != 0 {
t = h.free.erase(t) h.free.erase(t)
h.scav.insert(s) h.scav.insert(s)
released += r released += r
continue
} }
} }
t = t.next() t = n
} }
return released return released
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment