Skip to content

refactor(ssz): review tree views - #245

Merged
twoeths merged 2 commits into
te/refactor_treeview_2from
cayman/tree-view-state
Mar 17, 2026
Merged

refactor(ssz): review tree views#245
twoeths merged 2 commits into
te/refactor_treeview_2from
cayman/tree-view-state

Conversation

@wemeetagain

Copy link
Copy Markdown
Member

Summary

The tree view refactor in #139 correctly killed the heap-allocated BaseTreeView indirection, but it overcorrected — it scattered five fields (allocator, pool, root, children_nodes, changed) into every view type and recovered sharing through ChildNodes, a set of free functions that take anytype and duck-type their way to the right field names.

This PR fixes the abstraction:

  • TreeViewState — a concrete struct embedded by value in each chunk-based view (BasicPackedChunks, CompositeChunks, BitArray). Not a pointer, not a trait — just a struct with typed methods. When you see state: TreeViewState, you know what state it carries and what operations exist. The compiler gives real errors at the call site, not inside a generic utility that reconstructs the interface from field names.

  • StaticBitSet for ContainerTreeView.changed — the field count is comptime-known, so the dirty-tracking hashmap (AutoArrayHashMapUnmanaged(usize, void)) becomes a zero-allocation bitset. No hashmap init, no hashmap deinit, no allocator needed for dirty tracking.

ContainerTreeView does not use TreeViewState — its comptime tuple + fixed arrays are a genuinely different storage shape, and the bitset is the right dirty tracker for it. The split is now explicit in the type system rather than implicit in "which types happen to have the right field names."

What changed

Before After
ChildNodes.getChildNode(self, gindex) — anytype dispatch self.state.getChildNode(gindex) — concrete method on TreeViewState
ChildNodes.Change.commit(self) — anytype dispatch self.state.commitNodes() — concrete method
CompositeChunks.commit() duplicated sort/setNodesGrouped/ref/unref Flushes child views into children_nodes, delegates to commitNodes()
getLength/setLength on generic TreeViewState Inlined into BasicPackedChunks/CompositeChunks (list-specific)
changed: AutoArrayHashMapUnmanaged(usize, void) in ContainerTreeView changed: StaticBitSet(N) — zero allocation

Test plan

  • zig build test:ssz — all 194 tests pass
  • zig build test:spec_tests -Dpreset=minimal

🤖 Generated with Claude Code

wemeetagain and others added 2 commits March 16, 2026 16:22
Add TreeViewState struct with concrete typed methods for the common
state (allocator, pool, root, children_nodes, changed) shared by all
chunk-based tree views. Replaces duck-typed ChildNodes anytype dispatch.

- BasicPackedChunks, CompositeChunks, BitArray embed TreeViewState
- Update all callers (list/array/bit views) to access via .state.*
- Delete child_nodes.zig utility

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces AutoArrayHashMapUnmanaged(usize, void) with zero-allocation
StaticBitSet(N). Field count is comptime-known, so no hashmap needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wemeetagain
wemeetagain requested a review from a team as a code owner March 16, 2026 20:31
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the internal architecture of tree views within the SSZ library. The primary goal was to improve abstraction and efficiency by centralizing common state management and optimizing dirty-tracking mechanisms. This change enhances type safety, reduces boilerplate, and eliminates unnecessary heap allocations, leading to a more robust and performant implementation of tree view operations.

Highlights

  • TreeViewState Introduction: Introduced a concrete TreeViewState struct to encapsulate common fields (allocator, pool, root, children_nodes, changed) for chunk-based tree views, replacing scattered fields and ChildNodes utility functions with typed methods.
  • StaticBitSet for ContainerTreeView: Replaced the heap-allocated AutoArrayHashMapUnmanaged(usize, void) for dirty tracking in ContainerTreeView.changed with a zero-allocation StaticBitSet(N), leveraging comptime-known field counts.
  • Method Dispatch Refactor: Converted ChildNodes.getChildNode(self, gindex) and ChildNodes.Change.commit(self) to concrete methods like self.state.getChildNode(gindex) and self.state.commitNodes().
  • List-Specific Length Management: Inlined getLength and setLength methods, previously generic on TreeViewState, directly into BasicPackedChunks and CompositeChunks as they are list-specific operations.
  • CompositeChunks Commit Logic Streamlined: Refactored CompositeChunks.commit() to flush child views into children_nodes and delegate to commitNodes(), removing duplicated sort/setNodesGrouped/ref/unref logic.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/ssz/tree_view/array_basic.zig
    • Updated references to self.chunks.root, self.chunks.pool, and self.chunks.children_nodes to use the new self.chunks.state member for accessing tree view state.
  • src/ssz/tree_view/array_composite.zig
    • Adjusted access paths for root, pool, and children_nodes to point to the state field within self.chunks.
  • src/ssz/tree_view/bit_array.zig
    • Replaced direct fields (allocator, pool, root, children_nodes, changed) with a single state: TreeViewState member.
    • Migrated init, clone, deinit, commit, and clearCache logic to delegate to the new state struct.
    • Updated getChildNode and setChildNode calls to use self.state.
  • src/ssz/tree_view/bit_list.zig
    • Modified references to self.data.root, self.data.pool, and self.data.children_nodes to correctly access them via self.data.state.
  • src/ssz/tree_view/bit_vector.zig
    • Changed property access from self.data.root, self.data.pool, and self.data.children_nodes to self.data.state.
  • src/ssz/tree_view/chunks.zig
    • Replaced direct fields (allocator, pool, root, children_nodes, changed) with state: TreeViewState in BasicPackedChunks and CompositeChunks.
    • Updated init, clone, deinit, commit, and clearCache methods to use the state struct.
    • Moved getLength and setLength implementations from generic ChildNodes into BasicPackedChunks and CompositeChunks.
    • Refactored CompositeChunks.commit to iterate over self.state.changed keys and update self.state.children_nodes before calling self.state.commitNodes().
  • src/ssz/tree_view/container.zig
    • Replaced changed: std.AutoArrayHashMapUnmanaged(usize, void) with changed: std.StaticBitSet(ST.chunk_count).
    • Updated initialization of changed from .empty to std.StaticBitSet(ST.chunk_count).initEmpty().
    • Modified changed.contains(i) to changed.isSet(i) and changed.put(allocator, field_index, {}) to changed.set(field_index).
    • Changed changed.clearRetainingCapacity() to changed = std.StaticBitSet(ST.chunk_count).initEmpty().
  • src/ssz/tree_view/list_basic.zig
    • Adjusted property access for root, pool, and children_nodes to use self.chunks.state.
  • src/ssz/tree_view/list_composite.zig
    • Updated references to root, pool, and children_nodes to use self.chunks.state.
  • src/ssz/tree_view/utils/child_nodes.zig
    • Removed the child_nodes.zig utility file, as its functionality has been absorbed into TreeViewState.
  • src/ssz/tree_view/utils/tree_view_state.zig
    • Added a new file defining the TreeViewState struct, which centralizes common state and methods for tree views.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@wemeetagain wemeetagain changed the title refactor(ssz): TreeViewState + StaticBitSet for tree views refactor(ssz): TreeViewState and StaticBitSet for tree views Mar 16, 2026
@wemeetagain wemeetagain changed the title refactor(ssz): TreeViewState and StaticBitSet for tree views refactor(ssz): review tree views Mar 16, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant refactoring that improves the abstraction and type safety of the tree view implementations. The introduction of TreeViewState successfully encapsulates common state and logic, removing the need for anytype and duck-typing, which makes the code easier to understand and maintain. The switch to StaticBitSet for ContainerTreeView is also a great performance optimization, eliminating heap allocations for dirty tracking. The changes are well-structured and align with the stated goals. I've added a few suggestions to further improve safety by adding assertions, in line with the repository's style guide.

Comment thread src/ssz/tree_view/chunks.zig
Comment thread src/ssz/tree_view/utils/tree_view_state.zig
Comment thread src/ssz/tree_view/utils/tree_view_state.zig

@twoeths twoeths left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me
the use of std.StaticBitSet is awesome!

@twoeths
twoeths merged commit fdab8c6 into te/refactor_treeview_2 Mar 17, 2026
1 of 3 checks passed
@twoeths
twoeths deleted the cayman/tree-view-state branch March 17, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants