macula_hyparview_view (macula v10.14.0)
View SourceHyParView active + passive partial-view data structure (Leitão, Pereira, Rodrigues 2007 — implementation of Part 3 §7.1).
Each realm member holds two bounded views of other members:
- Active view — symmetric, TCP-like. Default cap 5 (per Part 3 §7.1:
max(5, ceil(log₂(N)))capped at 15). Plumtree gossip eager-pushes along active-view edges. - Passive view — candidate pool. Default cap is
4 × active. Promoted into the active view on active-peer failure; refreshed via periodic shuffles with active neighbours.
This module is pure. Mutating ops return a new view; the wire-protocol orchestration (JOIN / FORWARD_JOIN / NEIGHBOR / SHUFFLE / SHUFFLE_REPLY) lands in Session 5.2 on top of this.
Eviction policy
Whenever a add_active/2 or promote/2 would push the active view past active_cap, a uniformly-random current active peer is demoted to the passive view to make room. Symmetric removal on the other side is the protocol layer's responsibility.
Whenever add_passive/2 or merge_shuffle/2 would push the passive view past passive_cap, a uniformly-random current passive peer is dropped to make room.
Reference: plans/PLAN_MACULA_V2_PART3_DISCOVERY.md §7.1; plans/PLAN_PHASE_5_BREAKDOWN.md Session 5.1.
Summary
Functions
Move a peer from active to passive (e.g. on graceful peer disconnect that should be retained as a candidate).
Move a peer from passive to active. The peer must already be in the passive view; otherwise this is equivalent to add_active/2.
Types
-type counts() :: #{active := non_neg_integer(), passive := non_neg_integer()}.
-type eligibility() :: self | already_active | was_passive | fresh.
-type opts() :: #{active_cap => pos_integer(), passive_cap => pos_integer()}.
-type peer() :: macula_identity:pubkey().
-type view() :: #{self_id := peer(), active_cap := pos_integer(), passive_cap := pos_integer(), active := sets:set(peer()), passive := sets:set(peer())}.
Functions
Move a peer from active to passive (e.g. on graceful peer disconnect that should be retained as a candidate).
Move a peer from passive to active. The peer must already be in the passive view; otherwise this is equivalent to add_active/2.
-spec random_active_subset(view(), non_neg_integer()) -> [peer()].
-spec random_passive_subset(view(), non_neg_integer()) -> [peer()].