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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
use wide::*;
/// SIMD-accelerated data parsing utilities
pub struct SimdUtils;
impl SimdUtils {
/// SIMD-accelerated byte array comparison
/// For arrays with length >= 16, uses SIMD instructions for fast comparison
#[inline(always)]
pub fn fast_bytes_equal(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
let len = a.len();
// For small arrays, use standard comparison directly
if len < 16 {
return a == b;
}
// Use SIMD to process 16-byte chunks
let chunks = len / 16;
let remainder = len % 16;
// Process complete 16-byte chunks
for i in 0..chunks {
let offset = i * 16;
let chunk_a = u8x16::from(&a[offset..offset + 16]);
let chunk_b = u8x16::from(&b[offset..offset + 16]);
if !chunk_a.cmp_eq(chunk_b).all() {
return false;
}
}
// Process remaining bytes
if remainder > 0 {
let start = chunks * 16;
return &a[start..] == &b[start..];
}
true
}
/// Fast discriminator matching, specifically for instruction discriminator comparison
#[inline(always)]
pub fn fast_discriminator_match(data: &[u8], discriminator: &[u8]) -> bool {
if data.len() < discriminator.len() {
return false;
}
let disc_len = discriminator.len();
// Optimize for common discriminator lengths
match disc_len {
1 => data[0] == discriminator[0],
2 => {
let data_u16 = u16::from_le_bytes([data[0], data[1]]);
let disc_u16 = u16::from_le_bytes([discriminator[0], discriminator[1]]);
data_u16 == disc_u16
}
4 => {
let data_u32 = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
let disc_u32 = u32::from_le_bytes([
discriminator[0],
discriminator[1],
discriminator[2],
discriminator[3],
]);
data_u32 == disc_u32
}
8 => {
let data_u64 = u64::from_le_bytes([
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
]);
let disc_u64 = u64::from_le_bytes([
discriminator[0],
discriminator[1],
discriminator[2],
discriminator[3],
discriminator[4],
discriminator[5],
discriminator[6],
discriminator[7],
]);
data_u64 == disc_u64
}
16 => {
// Use SIMD to process 16-byte discriminators
let data_chunk = u8x16::from(&data[..16]);
let disc_chunk = u8x16::from(discriminator);
data_chunk.cmp_eq(disc_chunk).all()
}
_ => {
// For other lengths, use generic SIMD comparison
Self::fast_bytes_equal(&data[..disc_len], discriminator)
}
}
}
/// SIMD-accelerated memory search to find specific patterns in data
#[inline(always)]
pub fn find_pattern_simd(haystack: &[u8], needle: &[u8]) -> Option<usize> {
if needle.is_empty() || haystack.len() < needle.len() {
return None;
}
let needle_len = needle.len();
let haystack_len = haystack.len();
// For single-byte search, use optimized method
if needle_len == 1 {
let target = needle[0];
return haystack.iter().position(|&b| b == target);
}
// For multi-byte search, use SIMD acceleration
if needle_len <= 16 && haystack_len >= 16 {
let first_byte = needle[0];
let chunks = (haystack_len - needle_len + 1) / 16;
for chunk_idx in 0..chunks {
let start = chunk_idx * 16;
let end = std::cmp::min(start + 16, haystack_len - needle_len + 1);
// Use SIMD to find first byte matches
let chunk = &haystack[start..start + 16];
let target_vec = u8x16::splat(first_byte);
let chunk_vec = u8x16::from(chunk);
let matches = chunk_vec.cmp_eq(target_vec);
// Check each match position
let matches_array: [u8; 16] = matches.into();
for i in 0..16 {
if start + i >= end {
break;
}
if matches_array[i] != 0 && start + i + needle_len <= haystack_len {
if Self::fast_bytes_equal(
&haystack[start + i..start + i + needle_len],
needle,
) {
return Some(start + i);
}
}
}
}
// Process remaining part
let remaining_start = chunks * 16;
for i in remaining_start..=(haystack_len - needle_len) {
if Self::fast_bytes_equal(&haystack[i..i + needle_len], needle) {
return Some(i);
}
}
} else {
// Fallback to standard search
for i in 0..=(haystack_len - needle_len) {
if Self::fast_bytes_equal(&haystack[i..i + needle_len], needle) {
return Some(i);
}
}
}
None
}
/// SIMD-accelerated data validation to check if data conforms to specific format
#[inline(always)]
pub fn validate_data_format(data: &[u8], min_length: usize) -> bool {
if data.len() < min_length {
return false;
}
true
}
/// Fast checksum calculation (maintains API consistency)
#[inline(always)]
pub fn fast_checksum(data: &[u8]) -> u32 {
// Simplified implementation, directly sum all bytes
data.iter().map(|&b| b as u32).sum()
}
/// SIMD-accelerated data copy (for large data blocks)
#[inline(always)]
pub fn fast_copy(src: &[u8], dst: &mut [u8]) {
if src.len() != dst.len() {
panic!("Source and destination must have the same length");
}
let len = src.len();
if len >= 32 {
// Use 32-byte SIMD copy
let chunks = len / 32;
for i in 0..chunks {
let start = i * 32;
let src_chunk1 = u8x16::from(&src[start..start + 16]);
let src_chunk2 = u8x16::from(&src[start + 16..start + 32]);
let chunk1_array: [u8; 16] = src_chunk1.into();
let chunk2_array: [u8; 16] = src_chunk2.into();
dst[start..start + 16].copy_from_slice(&chunk1_array);
dst[start + 16..start + 32].copy_from_slice(&chunk2_array);
}
// Process remaining bytes
let remaining_start = chunks * 32;
dst[remaining_start..].copy_from_slice(&src[remaining_start..]);
} else {
// For small data, use standard copy
dst.copy_from_slice(src);
}
}
/// SIMD-accelerated account indices validation
/// Validates that all indices in the account index array are less than the total account count
#[inline(always)]
pub fn validate_account_indices_simd(indices: &[u8], account_count: usize) -> bool {
if indices.is_empty() {
return true;
}
let max_valid_index = account_count as u8;
// For small arrays, use standard comparison directly
if indices.len() < 16 {
return indices.iter().all(|&idx| idx < max_valid_index);
}
// Use SIMD for batch loading and comparison
let chunks = indices.len() / 16;
let remainder = indices.len() % 16;
// Process complete 16-byte chunks
for i in 0..chunks {
let start = i * 16;
let indices_chunk = u8x16::from(&indices[start..start + 16]);
// Convert SIMD vector to array for fast batch checking
let indices_array: [u8; 16] = indices_chunk.into();
// Use unrolled loop for fast comparison, compiler will optimize this
if indices_array[0] >= max_valid_index
|| indices_array[1] >= max_valid_index
|| indices_array[2] >= max_valid_index
|| indices_array[3] >= max_valid_index
|| indices_array[4] >= max_valid_index
|| indices_array[5] >= max_valid_index
|| indices_array[6] >= max_valid_index
|| indices_array[7] >= max_valid_index
|| indices_array[8] >= max_valid_index
|| indices_array[9] >= max_valid_index
|| indices_array[10] >= max_valid_index
|| indices_array[11] >= max_valid_index
|| indices_array[12] >= max_valid_index
|| indices_array[13] >= max_valid_index
|| indices_array[14] >= max_valid_index
|| indices_array[15] >= max_valid_index
{
return false;
}
}
// Process remaining bytes
if remainder > 0 {
let remaining_start = chunks * 16;
return indices[remaining_start..].iter().all(|&idx| idx < max_valid_index);
}
true
}
/// SIMD-accelerated instruction data validation
/// Validates basic format and length requirements of instruction data
#[inline(always)]
pub fn validate_instruction_data_simd(
data: &[u8],
min_length: usize,
discriminator_length: usize,
) -> bool {
// Basic length check
if data.len() < min_length || data.len() < discriminator_length {
return false;
}
// Use existing data format validation
Self::validate_data_format(data, min_length)
}
}