@@ -1737,41 +1737,32 @@ async def _get_one_ancestor_multiple_hashes(
17371737 return [InternalNode .from_row (row = row ) for row in rows ]
17381738
17391739 async def build_ancestor_table_for_latest_root (self , store_id : bytes32 ) -> None :
1740- async with self .db_wrapper .writer () as writer :
1740+ async with self .db_wrapper .writer ():
17411741 root = await self .get_tree_root (store_id = store_id )
17421742 if root .node_hash is None :
17431743 return
1744+ previous_root = await self .get_tree_root (
1745+ store_id = store_id ,
1746+ generation = max (root .generation - 1 , 0 ),
1747+ )
17441748
1745- await writer .execute (
1746- """
1747- WITH RECURSIVE tree_from_root_hash AS (
1748- SELECT
1749- node.hash,
1750- node.left,
1751- node.right,
1752- NULL AS ancestor
1753- FROM node
1754- WHERE node.hash = :root_hash
1755- UNION ALL
1756- SELECT
1757- node.hash,
1758- node.left,
1759- node.right,
1760- tree_from_root_hash.hash AS ancestor
1761- FROM node
1762- JOIN tree_from_root_hash ON node.hash = tree_from_root_hash.left
1763- OR node.hash = tree_from_root_hash.right
1749+ if previous_root .node_hash is not None :
1750+ previous_internal_nodes : List [InternalNode ] = await self .get_internal_nodes (
1751+ store_id = store_id ,
1752+ root_hash = previous_root .node_hash ,
17641753 )
1765- INSERT OR REPLACE INTO ancestors (hash, ancestor, tree_id, generation)
1766- SELECT
1767- tree_from_root_hash.hash,
1768- tree_from_root_hash.ancestor,
1769- :tree_id,
1770- :generation
1771- FROM tree_from_root_hash
1772- """ ,
1773- {"root_hash" : root .node_hash , "tree_id" : store_id , "generation" : root .generation },
1754+ known_hashes : Set [bytes32 ] = {node .hash for node in previous_internal_nodes }
1755+ else :
1756+ known_hashes = set ()
1757+ internal_nodes : List [InternalNode ] = await self .get_internal_nodes (
1758+ store_id = store_id ,
1759+ root_hash = root .node_hash ,
17741760 )
1761+ for node in internal_nodes :
1762+ # We already have the same values in ancestor tables, if we have the same internal node.
1763+ # Don't reinsert it so we can save DB space.
1764+ if node .hash not in known_hashes :
1765+ await self ._insert_ancestor_table (node .left_hash , node .right_hash , store_id , root .generation )
17751766
17761767 async def insert_root_with_ancestor_table (
17771768 self , store_id : bytes32 , node_hash : Optional [bytes32 ], status : Status = Status .PENDING
0 commit comments