1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Copyright (c) 2025-2026 Anton Kundenko <singaraiona@gmail.com>
* All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* sym.h -- Global symbol intern table.
*
* Sequential mode: simple hash map + array. wyhash (truncated to 32-bit),
* open addressing with linear probing. Stores (hash32 << 32) | (id + 1)
* so that 0 means empty bucket.
*/
/* Symbol width encoding (lower 2 bits of attrs when type == RAY_SYM).
* RAY_SYM_W{8,16,32,64} are now declared in <rayforce.h> for embedders. */
/* Helper macros */
/* Determine optimal SYM width for a given dictionary size */
static inline uint8_t
/* SYM-aware element size: returns adaptive width for RAY_SYM columns */
static inline uint8_t
/* Read a dictionary index from a RAY_SYM column (adaptive width) */
static inline int64_t
/* Write a dictionary index into a RAY_SYM column (adaptive width) */
static inline void
/* Intern with pre-computed wyhash, no lock.
* Caller must guarantee single-threaded access. */
int64_t ;
/* ---- Dotted name resolution (namespace paths) ---------------------------
* A symbol whose name contains one or more '.' is a *dotted* sym. At intern
* time we memchr once, split the name on '.', intern each segment, and cache
* the resulting segment sym_ids. `ray_sym_is_dotted` is cheap (one bitmap
* load) and gates the slow path in env lookup/set. */
bool ;
/* Returns segment count (>=2 if dotted, 0 otherwise). *out_segs is set to
* an interned sym_id array of length `nsegs` (valid for the lifetime of the
* sym table). */
int ;
/* Bulk-intern variant that does NOT sub-intern segments. Used only by
* persistence paths (ray_sym_load, ray_sym_save merge phase) where the
* disk-position==sym_id invariant would be broken by segment sub-interning
* appending entries mid-sequence. Callers MUST follow a batch of these
* with ray_sym_rebuild_segments to populate the dotted cache. */
int64_t ;
/* Walk the intern table and cache segment sym_ids for any dotted name
* that hasn't been cached yet. Idempotent — safe to call multiple times.
* Needed after bulk loads that used ray_sym_intern_no_split. Returns
* RAY_ERR_OOM on the first allocation/sub-intern failure so persistence
* paths can abort instead of leaving dotted names silently un-cached. */
ray_err_t ;
/* Upper bound on the arena bytes that sym_str_arena consumes for a name
* of the given length. Used by the three-phase atomic intern to pre-
* reserve arena capacity, so the commit phase cannot fail partway.
*
* Short path (<7 bytes): ray_arena_alloc(_, 0) charges ARENA_ALIGN_UP(32)
* = 32 bytes. Long path: sym_str_arena computes chars_block =
* ALIGN(32 + len + 1) and calls ray_arena_alloc(_, chars_block), which
* charges ARENA_ALIGN_UP(32 + chars_block) = 32 + chars_block because
* chars_block is 32-aligned. The +32 term is the crucial one — omitting
* it under-reserves by exactly 32 bytes per long sym.
*
* Exposed as inline so tests can verify the bound against actual arena
* consumption for every length in a range. */
static inline size_t
/* RAY_SYM_H */