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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
* SPDX-FileCopyrightText: 2025 Sebastiano Vigna
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/
use Borrow;
use FuseLge3Shards;
use crateBitFieldVec;
use crateShardEdge;
use crate*;
use crate*;
use *;
use SliceByValue;
/// Static functions with low space overhead, fast parallel construction, and
/// fast queries.
///
/// *Static functions* map keys to values, but they do not store the keys:
/// querying a static function with a key outside of the original set will lead
/// to an arbitrary result. Another name for static functions is *retrieval data
/// structure*. Values are retrieved using the [`get`](VFunc::get) method. On
/// some architectures, and with some constraints,
/// [`get_unaligned`](VFunc::get_unaligned) might be faster.
///
/// In exchange, static functions have a very low space overhead, and make it
/// possible to store the association between keys and values just in the space
/// required by the values (with a small overhead).
///
/// This structure is based on “[ε-Cost Sharding: Scaling Hypergraph-Based
/// Static Functions and Filters to Trillions of
/// Keys](https://arxiv.org/abs/2503.18397)”. Space overhead with respect to the
/// optimum depends on the [`ShardEdge`] type. The default is
/// [`FuseLge3Shards`], which provides 10.5% space overhead for large key sets
/// (above a few million keys), which grow up to 12% going towards smaller key
/// sets. Details on other possible [`ShardEdge`] implementations can be found
/// in the [`shard_edge`](crate::func::shard_edge) module documentation.
///
/// Instances of this structure are immutable; they are built
/// using a [`VBuilder`](crate::func::VBuilder) and can be serialized using
/// [ε-serde](https://crates.io/crates/epserde). Please see the documentation of
/// [`VBuilder`](crate::func::VBuilder) for examples.
///
/// # Generics
///
/// * `T`: The type of the keys.
/// * `W`: The word used to store the data, which is also the output type. It
/// can be any unsigned type.
/// * `D`: The backend storing the function data. It can be a
/// [`BitFieldVec<W>`](crate::bits::BitFieldVec) or a `Box<[W]>`. In the first
/// case, the data is stored using exactly the number of bits needed, but
/// access is slightly slower, while in the second case the data is stored in
/// a boxed slice of `W`, thus forcing the number of bits to the number of
/// bits of `W`, but access will be faster. Note that for most bit sizes in
/// the first case on some architectures you can use [unaligned
/// reads](VFunc::get_unaligned) to get faster queries.
/// * `S`: The signature type. The default is `[u64; 2]`. You can switch to
/// `[u64; 1]` (and possibly
/// [`FuseLge3NoShards`](crate::func::shard_edge::FuseLge3NoShards)) for
/// slightly faster construction and queries, but the construction will not
/// scale beyond 3.8 billion keys.
/// * `E`: The sharding and edge logic type. The default is [`FuseLge3Shards`].
/// For small sets of keys you might try
/// [`FuseLge3NoShards`](crate::func::shard_edge::FuseLge3NoShards), possibly
/// coupled with `[u64; 1]` signatures. For functions with more than a few
/// dozen billion keys, you might try
/// [`FuseLge3FullSigs`](crate::func::shard_edge::FuseLge3FullSigs).
; 2],
E: = FuseLge3Shards,
>