mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-04 22:13:19 +00:00
scylla-gdb.py: fix disagreement between std_deque len() and iter()
std_deque implementation was broken, with __len__() and __iter__() disagreeing about the size of the container. Turns out both are wrong in certain situations. Fix the iteration logic and re-base both __len__() and __iter__() on the same node iteration code to prevent future disagreements.
This commit is contained in:
@@ -562,39 +562,6 @@ class std_deque:
|
||||
# should reflect the value of _GLIBCXX_DEQUE_BUF_SIZE
|
||||
DEQUE_BUF_SIZE = 512
|
||||
|
||||
class iterator:
|
||||
def __init__(self, ref, buf_size):
|
||||
self.cur = ref['_M_cur']
|
||||
self.first = ref['_M_first']
|
||||
self.last = ref['_M_last']
|
||||
self.node = ref['_M_node']
|
||||
self.buf_size = buf_size
|
||||
|
||||
def _set_node(self, node):
|
||||
self.first = node.dereference()
|
||||
self.last = self.first + self.buf_size
|
||||
self.node = node
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.node == other.node and self.cur == other.cur
|
||||
|
||||
def __str__(self):
|
||||
return "{{node=0x{:x}, first=0x{:x}, last=0x{:x}, cur=0x{:x}}}".format(
|
||||
int(self.node),
|
||||
int(self.first),
|
||||
int(self.last),
|
||||
int(self.cur))
|
||||
|
||||
def next(self):
|
||||
self.cur += 1
|
||||
if self.cur == self.last:
|
||||
self._set_node(self.node + 1)
|
||||
self.cur = self.first
|
||||
|
||||
def get(self):
|
||||
return self.cur.dereference()
|
||||
|
||||
|
||||
def __init__(self, ref):
|
||||
self.ref = ref
|
||||
self.value_type = self.ref.type.strip_typedefs().template_argument(0)
|
||||
@@ -603,12 +570,29 @@ class std_deque:
|
||||
else:
|
||||
self.buf_size = 1
|
||||
|
||||
def _foreach_node(self):
|
||||
node_it = self.ref['_M_impl']['_M_start']
|
||||
node_end = self.ref['_M_impl']['_M_finish']
|
||||
node = node_it['_M_node']
|
||||
it = node_it['_M_first']
|
||||
end = node_it['_M_last']
|
||||
|
||||
if not bool(node):
|
||||
return
|
||||
|
||||
while node != node_end['_M_node']:
|
||||
yield it, end
|
||||
node = node + 1
|
||||
it = node.dereference()
|
||||
end = it + self.buf_size
|
||||
|
||||
yield node_end['_M_first'], node_end['_M_cur']
|
||||
|
||||
def __len__(self):
|
||||
start = self.ref['_M_impl']['_M_start']
|
||||
finish = self.ref['_M_impl']['_M_finish']
|
||||
return (self.buf_size * (max(1, finish['_M_node'] - start['_M_node']) - 1) +
|
||||
start['_M_last'] - start['_M_cur'] +
|
||||
finish['_M_cur'] - finish['_M_first'])
|
||||
l = 0
|
||||
for start, end in self._foreach_node():
|
||||
l += (end - start)
|
||||
return l
|
||||
|
||||
def __nonzero__(self):
|
||||
return self.__len__() > 0
|
||||
@@ -617,12 +601,10 @@ class std_deque:
|
||||
return self.__len__() > 0
|
||||
|
||||
def __iter__(self):
|
||||
it = std_deque.iterator(self.ref['_M_impl']['_M_start'], self.buf_size)
|
||||
finish = std_deque.iterator(self.ref['_M_impl']['_M_finish'], self.buf_size)
|
||||
|
||||
while it != finish:
|
||||
yield it.get()
|
||||
it.next()
|
||||
for it, end in self._foreach_node():
|
||||
while it != end:
|
||||
yield it.dereference()
|
||||
it += 1
|
||||
|
||||
def __str__(self):
|
||||
items = [str(item) for item in self]
|
||||
|
||||
Reference in New Issue
Block a user