-
Notifications
You must be signed in to change notification settings - Fork 139
Expand file tree
/
Copy pathCompactLatin1CharSequenceAccess.java
More file actions
182 lines (164 loc) · 6.27 KB
/
CompactLatin1CharSequenceAccess.java
File metadata and controls
182 lines (164 loc) · 6.27 KB
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
/*
* Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0
*/
package net.openhft.hashing;
import java.nio.ByteOrder;
import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
import static net.openhft.hashing.UnsafeAccess.BYTE_BASE;
/*
* Compress Latin1 Access
*
* Explaination:
*
* compressed idx : 0 1 2 3 4 5
* compressed bytes: 12 34 56 78 9A BC
*
* compressed idx : 0 1 2 3 4 5
* expanded index : 0 1 2 3 4 5 6 7 8 9 A B
* expanded LE mem: 12 00 34 00 56 00 78 00 9A 00 BC 00
* expanded BE mem: 00 12 00 34 00 56 00 78 00 9A 00 BC
* align LE byte: [] --> 0x12
* align BE byte: [] --> 0x00
* unalign LE byte: [] --> 0x00
* unalign BE byte: [] --> 0x12
*
* compressed idx : 0 1 2 3 4 5
* expanded index : 0 1 2 3 4 5 6 7 8 9 A B
* expanded LE mem: 12 00 34 00 56 00 78 00 9A 00 BC 00
* expanded BE mem: 00 12 00 34 00 56 00 78 00 9A 00 BC
* align LE char: [___] --> 0x12
* align BE char: [___] --> 0x12
* unalign LE char: [___] --> 0x3400
* unalign BE char: [___] --> 0x1200
*
* compressed idx : 0 1 2 3 4 5
* expanded index : 0 1 2 3 4 5 6 7 8 9 A B
* expanded LE mem: 12 00 34 00 56 00 78 00 9A 00 BC 00
* expanded BE mem: 00 12 00 34 00 56 00 78 00 9A 00 BC
* align LE int : [_________] --> 0x340012
* align BE int : [_________] --> 0x120034
* unalign LE int : [_________] --> 0x56003400
* unalign BE int : [_________] --> 0x12003400
*
* compressed idx : 0 1 2 3 4 5
* expanded index : 0 1 2 3 4 5 6 7 8 9 A B
* expanded LE mem: 12 00 34 00 56 00 78 00 9A 00 BC 00
* expanded BE mem: 00 12 00 34 00 56 00 78 00 9A 00 BC
* align LE long: [_____________________] --> 0x78005600340012
* align BE long: [_____________________] --> 0x12003400560078
* unalign LE long: [_____________________] --> 0x9A00780056003400
* unalign BE long: [_____________________] --> 0x1200340056007800
*
* Parameters:
*
* Parameters must satisfy: 0 <= offset < offset + typeWidth <= input.length*2.
* When offset + typeWidth >= (input.length + 1)*2, the behavior is undefined, throwing a exception
* or returning dirty results.
* When offset + typeWidth == input.length*2 + 1,
* 1) on BE machine, the result is correct
* 2) on LE machine, the behavior is undefined, throwing a exception or returning dirty results.
*
* compressed idx : 0
* expanded index : 0 1
* expanded LE mem: 12 00
* expanded BE mem: 00 12
* align LE char: [___] --> 0x12
* align BE char: [___] --> 0x12
* unalign LE char: [_??] --> 0x??00, exception or dirty
* unalign BE char: [_00] --> 0x1200, correct
*
* Notes: This access is based on the UnsafeAccess, so only works for the native order.
*/
@ParametersAreNonnullByDefault
public class CompactLatin1CharSequenceAccess extends Access<byte[]> {
@NotNull
static final Access<byte[]> INSTANCE = new CompactLatin1CharSequenceAccess();
@NotNull
private static final Access<byte[]> INSTANCE_NON_NATIVE = Access.newDefaultReverseAccess(INSTANCE);
@NotNull
private static final UnsafeAccess UNSAFE = UnsafeAccess.INSTANCE;
private static final long UNSAFE_IDX_ADJUST
= BYTE_BASE * 2L + (ByteOrder.nativeOrder() == LITTLE_ENDIAN ? 1 : 0);
private static final long ARRAY_IDX_ADJUST
= ByteOrder.nativeOrder() == LITTLE_ENDIAN ? 1 : 0;
private CompactLatin1CharSequenceAccess() {}
@Override
public long getLong(final byte[] input, final long offset) {
final long byteIdx = (offset + UNSAFE_IDX_ADJUST) >> 1;
final long compact = UNSAFE.getUnsignedInt(input, byteIdx);
long expanded = ((compact << 16) | compact) & 0xFFFF0000FFFFL;
expanded = ((expanded << 8) | expanded) & 0xFF00FF00FF00FFL;
if (((int)offset & 1) == 1) {
return expanded << 8;
}
return expanded;
}
@Override
public int getInt(final byte[] input, final long offset) {
final long byteIdx = (offset + UNSAFE_IDX_ADJUST) >> 1;
final int compact = UNSAFE.getShort(input, byteIdx) & 0xFFFF;
final int expanded = ((compact << 8) | compact) & 0xFF00FF;
if (((int)offset & 1) == 1) {
return expanded << 8;
}
return expanded;
}
@Override
public long getUnsignedInt(final byte[] input, final long offset) {
final long byteIdx = (offset + UNSAFE_IDX_ADJUST) >> 1;
final int compact = UNSAFE.getShort(input, byteIdx) & 0xFFFF;
final long expanded = (long)(((compact << 8) | compact) & 0xFF00FF);
if (((int)offset & 1) == 1) {
return expanded << 8;
}
return expanded;
}
@Override
public int getShort(final byte[] input, final long offset) {
if (((int)offset & 1) == 0) {
final int byteIdx = (int)(offset >> 1);
return (int)input[byteIdx] & 0xFF;
} else {
final int byteIdx = (int)((offset + ARRAY_IDX_ADJUST) >> 1);
return (int)input[byteIdx] << 8;
}
}
@Override
public int getUnsignedShort(final byte[] input, final long offset) {
if (((int)offset & 1) == 0) {
final int byteIdx = (int)(offset >> 1);
return (int)input[byteIdx] & 0xFF;
} else {
final int byteIdx = (int)((offset + ARRAY_IDX_ADJUST) >> 1);
return ((int)input[byteIdx] & 0xFF) << 8;
}
}
@Override
public int getByte(final byte[] input, final long offset) {
if (ARRAY_IDX_ADJUST == ((int)offset & 1)) {
return 0;
} else {
return (int)input[(int)(offset >> 1)];
}
}
@Override
public int getUnsignedByte(final byte[] input, final long offset) {
if (ARRAY_IDX_ADJUST == ((int)offset & 1)) {
return 0;
} else {
return (int)input[(int)(offset >> 1)] & 0xFF;
}
}
@Override
@NotNull
public ByteOrder byteOrder(final byte[] input) {
return UNSAFE.byteOrder(input);
}
@Override
@NotNull
protected Access<byte[]> reverseAccess() {
return INSTANCE_NON_NATIVE;
}
}