- deque, object_pool, and graph data structures + PrettyPrinters

This commit is contained in:
2025-08-16 07:56:25 -04:00
parent 8bfb59cd20
commit 38b7221fa0
16 changed files with 867 additions and 146 deletions

View File

@@ -108,6 +108,7 @@ class ListPrinter:
self.list = val
self.node = self.list['_root']
self.index = 0
self.table = self.list['_table']['_data']
def __iter__(self):
return self
@@ -118,8 +119,8 @@ class ListPrinter:
i = self.index
self.index = self.index + 1
value = self.list['_table']['_data'][self.node]['value']['_val']
self.node = self.list['_table']['_data'][self.node]['next']
value = self.table[self.node]['value']['_val']
self.node = self.table[self.node]['next']
return '[{}]'.format(i), value
@@ -137,79 +138,6 @@ class ListPrinter:
return 'array'
# RDTREE ===============================================================================================================
class RDTreePrinter:
"""Print a fennec::rdtree"""
class Iterator:
def __init__(self, tree, node, capacity):
self.tree = tree
self.capacity = capacity
self.visit = deque()
self.visit.append((node, 0, 0))
def __iter__(self):
return self
def __next__(self):
if len(self.visit) == 0:
raise StopIteration
node = self.visit[0][0]
i = self.visit[0][1]
depth = self.visit[0][2]
self.visit.popleft()
opt = self.tree[node]['value']
value = None
if opt['_set']:
value = opt['_val']
nnext = self.tree[node]['next']
nprev = self.tree[node]['prev']
nprevc = self.tree[nprev]['child'] if nprev != 18446744073709551615 else 18446744073709551615
child = self.tree[node]['child']
n_chld = self.tree[node]['num_children']
index = '' * depth * 2 # Uses Braille Space, otherwise it would get eaten as whitespace by parsers
if nnext < self.capacity:
self.visit.appendleft((nnext, i + 1, depth))
if child < self.capacity:
self.visit.appendleft((child, 0, depth + 1))
# ┌ ─ ├ └
if nnext != 18446744073709551615:
index += ''
else:
index += ''
index += ''
index += '[{}, {}, {}, {}]'.format(i, node, depth, n_chld)
print(index)
if value is None:
return index, '{ empty }'
return index, value
def __init__(self, val):
self.tree = val['_table']['_data']
self.size = val['_size']
self.capacity = val['_table']['_capacity']
def to_string(self):
if self.size == 0:
return "{ empty }"
return "{ size = " + str(self.size) + " }"
def children(self):
return self.Iterator(self.tree, 0, self.capacity)
# SET ==================================================================================================================
class SetPrinter:
@@ -310,20 +238,204 @@ class MapPrinter:
return 'map'
# OBJECT_POOL ==========================================================================================================
class ObjectPoolPrinter:
"""Print a fennec::object_pool"""
class Iterator:
def __init__(self, val):
self.list = val
self.index = 0
self.capacity = self.list['_table']['_alloc']['_capacity']
self.table = self.list['_table']['_alloc']['_data']
def __iter__(self):
return self
def __next__(self):
i = self.index
while True:
i = self.index
self.index = self.index + 1
if self.index >= self.capacity:
raise StopIteration
if bool(self.table[i]['_set']):
value = self.table[i]['_val']
break
return '[{}]'.format(i), value
def __init__(self, val):
self.val = val
def to_string(self):
return "{ length " + str(self.val['_size']) + ", capacity " + str(self.val['_table']['_alloc']['_capacity']) + " }"
def children(self):
return self.Iterator(self.val)
def display_hint(self):
return 'array'
# RDTREE ===============================================================================================================
class RDTreePrinter:
"""Print a fennec::rdtree"""
class Iterator:
def __init__(self, tree, node, capacity):
self.tree = tree
self.capacity = capacity
self.visit = deque()
self.visit.append((node, 0, 0))
def __iter__(self):
return self
def __next__(self):
if len(self.visit) == 0:
raise StopIteration
node = self.visit[0][0]
i = self.visit[0][1]
depth = self.visit[0][2]
self.visit.popleft()
value = self.tree[node]['value']
nnext = self.tree[node]['next']
nprev = self.tree[node]['prev']
nprevc = self.tree[nprev]['child'] if nprev != 18446744073709551615 else 18446744073709551615
child = self.tree[node]['child']
n_chld = self.tree[node]['num_children']
index = '' * depth * 2 # Uses Braille Space, otherwise it would get eaten as whitespace by parsers
if nnext < self.capacity:
self.visit.appendleft((nnext, i + 1, depth))
if child < self.capacity:
self.visit.appendleft((child, 0, depth + 1))
# ┌ ─ ├ └
if nnext != 18446744073709551615:
index += ''
else:
index += ''
index += ''
index += '[{}, {}]'.format(node, i)
return index, value
def __init__(self, val):
self.tree = val['_table']['_data']
self.size = val['_size']
self.capacity = val['_table']['_capacity']
def to_string(self):
if self.size == 0:
return "{ empty }"
return "{ size = " + str(self.size) + " }"
def children(self):
return self.Iterator(self.tree, 0, self.capacity)
# Graph ================================================================================================================
class GraphPrinter:
"""Print a fennec::graph"""
class Iterator:
def __init__(self, val):
self.node_pool = val['_node_pool']['_table']['_alloc']['_data']
self.max_nodes = val['_node_pool']['_table']['_alloc']['_capacity']
self.conn_map = val['_conn_map']['_alloc']['_data']
self.max_conn = val['_conn_map']['_size']
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= self.max_nodes:
raise StopIteration
i = self.index
self.index = self.index + 1
while not bool(self.node_pool[i]['_set']):
i = self.index
self.index = self.index + 1
conns = self.get_conns(i)
value = self.node_pool[i]['_val']
return '[{} -> {{{}}}]'.format(i, str(conns)), value
def get_conns(self, index):
indices = []
if index >= self.max_conn:
return indices
map = self.conn_map[index]['_set']
max_conns = map['_alloc']['_capacity']
conns = map['_alloc']['_data']
print(max_conns)
if max_conns == 0:
return indices
for i in range(0, max_conns):
if bool(conns[i]['value']['_set']):
conn = conns[i]['value']['_val']
indices.append(str(int(conn['first'])))
return indices
def __init__(self, val):
self.val = val
self.size = val['_node_pool']['_size']
def to_string(self):
if self.size == 0:
return "{ empty }"
return "{ size = " + str(self.size) + " }"
def children(self):
return self.Iterator(self.val)
# GDB Code =============================================================================================================
def register_printers():
print("registering containers")
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennec::containers")
pp.add_printer('fennec::optional', '^fennec::optional<.*>$', OptionalPrinter)
pp.add_printer('fennec::pair', '^fennec::pair<.*>$', PairPrinter)
pp.add_printer('fennec::tuple', '^fennec::tuple<.*>$', TuplePrinter)
pp.add_printer('fennec::array', '^fennec::array<.*>$', ArrayPrinter)
pp.add_printer('fennec::dynarray', '^fennec::dynarray<.*>$', DynArrayPrinter)
pp.add_printer('fennec::list', '^fennec::list<.*>$', ListPrinter)
pp.add_printer('fennec::rdtree', '^fennec::rdtree<.*>$', RDTreePrinter)
pp.add_printer('fennec::set', '^fennec::set<.*>$', SetPrinter)
pp.add_printer('fennec::map', '^fennec::map<.*>$', MapPrinter)
pp.add_printer('fennec::array', '^fennec::array<.*>$', ArrayPrinter)
pp.add_printer('fennec::dynarray', '^fennec::dynarray<.*>$', DynArrayPrinter)
pp.add_printer('fennec::graph', '^fennec::graph<.*>$', GraphPrinter)
pp.add_printer('fennec::list', '^fennec::list<.*>$', ListPrinter)
pp.add_printer('fennec::map', '^fennec::map<.*>$', MapPrinter)
pp.add_printer('fennec::object_pool', '^fennec::object_pool<.*>$', ObjectPoolPrinter)
pp.add_printer('fennec::optional', '^fennec::optional<.*>$', OptionalPrinter)
pp.add_printer('fennec::pair', '^fennec::pair<.*>$', PairPrinter)
pp.add_printer('fennec::set', '^fennec::set<.*>$', SetPrinter)
pp.add_printer('fennec::rdtree', '^fennec::rdtree<.*>$', RDTreePrinter)
pp.add_printer('fennec::tuple', '^fennec::tuple<.*>$', TuplePrinter)
return pp
printer = register_printers()