Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_shmem_h
2 : #define HEADER_fd_src_flamenco_accdb_fd_accdb_shmem_h
3 :
4 : #include "fd_accdb_cache.h"
5 :
6 8424 : #define FD_ACCDB_SHMEM_ALIGN (128UL)
7 :
8 4083 : #define FD_ACCDB_SHMEM_MAGIC (0xF17EDA2CE7ACCDB0UL) /* FIREDANCE ACCDB V0 */
9 :
10 : typedef struct fd_accdb_shmem_private fd_accdb_shmem_t;
11 :
12 : struct fd_accdb_shmem_metrics {
13 : ulong accounts_total;
14 : ulong accounts_capacity;
15 : ulong disk_allocated_bytes;
16 : ulong disk_current_bytes;
17 : ulong disk_used_bytes;
18 : int in_compaction;
19 : ulong compactions_requested;
20 : ulong compactions_completed;
21 : ulong accounts_relocated;
22 : ulong accounts_relocated_bytes;
23 : ulong partitions_freed;
24 : };
25 :
26 : typedef struct fd_accdb_shmem_metrics fd_accdb_shmem_metrics_t;
27 :
28 : struct fd_accdb_metrics {
29 : ulong acquire_calls;
30 : ulong accounts_acquired_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
31 : ulong writable_accounts_acquired_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
32 : ulong accounts_evicted;
33 : ulong accounts_evicted_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
34 : ulong accounts_preevicted;
35 : ulong accounts_preevicted_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
36 : ulong accounts_committed_new_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
37 : ulong accounts_committed_overwrite_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
38 : ulong accounts_not_found_per_class[ FD_ACCDB_CACHE_CLASS_CNT ];
39 : ulong accounts_waited;
40 : ulong accounts_deleted;
41 :
42 : ulong acquire_failed;
43 :
44 : ulong bytes_read;
45 : ulong read_ops;
46 : ulong bytes_written;
47 : ulong write_ops;
48 : ulong copy_ops;
49 :
50 : ulong bytes_copied;
51 : };
52 :
53 : typedef struct fd_accdb_metrics fd_accdb_metrics_t;
54 :
55 : FD_PROTOTYPES_BEGIN
56 :
57 : FD_FN_CONST ulong
58 : fd_accdb_shmem_align( void );
59 :
60 : ulong
61 : fd_accdb_shmem_footprint( ulong max_accounts,
62 : ulong max_live_slots,
63 : ulong max_account_writes_per_slot,
64 : ulong partition_cnt,
65 : ulong cache_footprint,
66 : ulong cache_min_reserved,
67 : ulong joiner_cnt,
68 : ulong max_incremental_accounts );
69 :
70 : void *
71 : fd_accdb_shmem_new( void * shmem,
72 : ulong max_accounts,
73 : ulong max_live_slots,
74 : ulong max_account_writes_per_slot,
75 : ulong partition_cnt,
76 : ulong partition_sz,
77 : ulong cache_footprint,
78 : ulong cache_min_reserved,
79 : int bundle_enabled,
80 : ulong seed,
81 : ulong joiner_cnt,
82 : ulong max_incremental_accounts );
83 :
84 : fd_accdb_shmem_t *
85 : fd_accdb_shmem_join( void * shtc );
86 :
87 : void
88 : fd_accdb_shmem_bytes_freed( fd_accdb_shmem_t * accdb,
89 : ulong offset,
90 : ulong sz );
91 :
92 : /* fd_accdb_shmem_try_enqueue_compaction checks whether the partition
93 : at partition_idx has crossed the compaction threshold and, if so,
94 : enqueues it for compaction. The caller MUST hold partition_lock.
95 : This is factored out of fd_accdb_shmem_bytes_freed so that
96 : change_partition (which already holds the lock) can call it after
97 : updating the write head, avoiding a race where the old write head
98 : is skipped for enqueue. */
99 :
100 : void
101 : fd_accdb_shmem_try_enqueue_compaction( fd_accdb_shmem_t * accdb,
102 : ulong partition_idx );
103 :
104 : /* Per-partition snapshot for read-only consumers (GUI tile). The
105 : underlying per-partition state is updated with relaxed atomics by
106 : writers, so the snapshot is best-effort consistent. compaction_state
107 : is 0=idle, 1=queued, 2=compacting. */
108 :
109 : struct fd_accdb_shmem_partition_info {
110 : ulong file_offset; /* byte offset of partition start in the accdb file */
111 : ulong write_offset; /* current write head within the partition */
112 : ulong bytes_freed; /* bytes marked freed within the partition */
113 : ulong compaction_offset; /* current compaction read offset within partition */
114 : ulong read_ops;
115 : ulong bytes_read;
116 : ulong write_ops;
117 : ulong bytes_written;
118 : long created_ticks; /* fd_tickcount when the partition was opened */
119 : long filled_ticks; /* fd_tickcount when partition closed (0 if active) */
120 : uchar layer; /* compaction tier this partition belongs to */
121 : uchar compaction_state; /* 0=idle, 1=queued, 2=compacting */
122 : uchar is_write_head; /* non-zero if this partition is the active write */
123 : /* head for any layer at the time of the snapshot */
124 : };
125 :
126 : typedef struct fd_accdb_shmem_partition_info fd_accdb_shmem_partition_info_t;
127 :
128 : ulong
129 : fd_accdb_shmem_partition_max( fd_accdb_shmem_t const * accdb );
130 :
131 : ulong
132 : fd_accdb_shmem_partition_sz( fd_accdb_shmem_t const * accdb );
133 :
134 : void
135 : fd_accdb_shmem_partition_info( fd_accdb_shmem_t const * accdb,
136 : ulong partition_idx,
137 : fd_accdb_shmem_partition_info_t * out );
138 :
139 : FD_PROTOTYPES_END
140 :
141 : /* fd_accdb_delta tracks account addresses changed since a full snap.
142 : This is used to determine which accounts should be packed into a full
143 : snapshot (including tombstones for accounts no longer present in
144 : accdb, but present in the full snapshot). */
145 :
146 : struct fd_accdb_delta {
147 : uchar pubkey[ 32UL ];
148 : uint next;
149 : };
150 : typedef struct fd_accdb_delta fd_accdb_delta_t;
151 :
152 : FD_STATIC_ASSERT( sizeof(fd_accdb_delta_t)==36UL, delta_ele_sz );
153 : FD_STATIC_ASSERT( __builtin_offsetof(fd_accdb_delta_t, next)==32UL, delta_ele_next_off );
154 :
155 : /* Snapshot sync API */
156 :
157 : /* fd_accdb_shmem_private_t::snapshot_sync values
158 : Legal transitions:
159 : - IDLE -> {START_FULL,START_INCR}
160 : - START_FULL -> RUNNING
161 : - START_INCR -> {RUNNING,FAIL}
162 : - RUNNING -> DONE
163 : - FAIL -> DONE
164 : - DONE -> IDLE */
165 4083 : #define FD_ACCDB_SNAPSHOT_SYNC_IDLE (0UL) /* accdb: steady state */
166 0 : #define FD_ACCDB_SNAPSHOT_SYNC_START_FULL (1UL) /* client: i want to create a full snapshot */
167 0 : #define FD_ACCDB_SNAPSHOT_SYNC_START_INCR (2UL) /* client: i want to create an incremental snapshot */
168 0 : #define FD_ACCDB_SNAPSHOT_SYNC_RUNNING (3UL) /* accdb: ack, snapshot creation active */
169 0 : #define FD_ACCDB_SNAPSHOT_SYNC_DONE (4UL) /* client: i am done snapshotting */
170 0 : #define FD_ACCDB_SNAPSHOT_SYNC_FAIL (5UL) /* accdb: error during incremental creation */
171 :
172 : static inline ulong
173 3469390 : fd_accdb_snapshot_sync_state( ulong const * sync ) {
174 3469390 : return __atomic_load_n( sync, __ATOMIC_ACQUIRE );
175 3469390 : }
176 :
177 : static inline void
178 : fd_accdb_snapshot_sync_advance( ulong * sync,
179 0 : ulong next ) {
180 0 : ulong old = __atomic_load_n( sync, __ATOMIC_RELAXED );
181 0 : for(;;) {
182 0 : if( FD_LIKELY( __atomic_compare_exchange_n( sync, &old, next, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED ) ) ) return;
183 0 : FD_SPIN_PAUSE();
184 0 : }
185 0 : }
186 :
187 : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_shmem_h */
|