RobotCore
1.0
WPILib port to raspberry Pi
Toggle main menu visibility
Loading...
Searching...
No Matches
LongToObjectHashMap.java
1
// Copyright (c) FIRST and other WPILib contributors.
2
// Open Source Software; you can modify and/or share it under the terms of
3
// the WPILib BSD license file in the root directory of this project.
4
5
package
org.wpilib.units.collections;
6
7
import
java.util.ArrayList;
8
import
java.util.Arrays;
9
import
java.util.Collection;
10
import
java.util.List;
11
18
public
class
LongToObjectHashMap
<V> {
19
private
static
final
int
INITIAL_SIZE = 0;
20
private
static
final
int
INITIAL_CAPACITY = 8;
// NOTE: must be a power of two
21
27
private
static
final
double
LOAD_FACTOR = 75.00 / 100;
28
30
private
int
m_size = INITIAL_SIZE;
31
36
private
int
m_capacity = INITIAL_CAPACITY;
37
46
private
long
[] m_keys =
new
long
[m_capacity];
47
49
private
boolean
[] m_uses =
new
boolean
[m_capacity];
50
54
@SuppressWarnings(
"unchecked"
)
55
private
V[] m_values = (V[])
new
Object[m_capacity];
56
58
public
LongToObjectHashMap
() {}
59
67
public
V
put
(
long
key, V value) {
68
int
bucket = bucket(key);
69
70
// Increment the bucket until we hit an open space (there's always going to be at least one)
71
while
(m_uses[bucket]) {
72
if
(m_keys[bucket] == key) {
73
// replace the existing value
74
var oldValue = m_values[bucket];
75
m_values[bucket] = value;
76
return
oldValue;
77
}
78
bucket = safeIncrement(bucket);
79
}
80
81
m_uses[bucket] =
true
;
82
m_keys[bucket] = key;
83
m_values[bucket] = value;
84
m_size++;
85
86
if
(m_size > maxSize()) {
87
grow();
88
}
89
return
null
;
90
}
91
98
public
V
get
(
long
key) {
99
int
bucket = bucket(key);
100
while
(m_uses[bucket]) {
101
if
(m_keys[bucket] == key) {
102
// found it
103
return
m_values[bucket];
104
}
105
bucket = safeIncrement(bucket);
106
}
107
return
null
;
108
}
109
116
public
V
remove
(
long
key) {
117
int
bucket = bucket(key);
118
while
(m_uses[bucket]) {
119
if
(m_keys[bucket] == key) {
120
// found it
121
// TODO: Shrink the map when below a certain load factor
122
// Current use cases don't remove elements from the map, so there's not much use
123
// for shrinking at the moment.
124
m_size--;
125
m_keys[bucket] = 0L;
126
m_uses[bucket] =
false
;
127
128
var oldValue = m_values[bucket];
129
m_values[bucket] =
null
;
130
return
oldValue;
131
}
132
bucket = safeIncrement(bucket);
133
}
134
135
return
null
;
136
}
137
144
public
boolean
containsKey
(
long
key) {
145
int
bucket = bucket(key);
146
while
(m_uses[bucket]) {
147
if
(m_keys[bucket] == key) {
148
return
true
;
149
}
150
bucket = safeIncrement(bucket);
151
}
152
return
false
;
153
}
154
156
public
void
clear
() {
157
if
(m_size == 0) {
158
// Nothing to do
159
return
;
160
}
161
m_size = 0;
162
163
Arrays.fill(m_uses,
false
);
164
Arrays.fill(m_keys, 0L);
165
Arrays.fill(m_values,
null
);
166
}
167
173
public
int
size
() {
174
return
m_size;
175
}
176
177
// package-private for tests
178
int
capacity() {
179
return
m_capacity;
180
}
181
187
public
boolean
isEmpty
() {
188
return
m_size == 0;
189
}
190
198
public
ReadOnlyPrimitiveLongSet
keySet
() {
199
// copy the sparse key array into a compact array
200
final
long
[] keys =
new
long
[m_size];
201
int
i = 0;
202
for
(
int
bucket = 0; bucket < m_capacity; bucket++) {
203
if
(m_uses[bucket]) {
204
keys[i] = m_keys[bucket];
205
i++;
206
}
207
}
208
209
return
new
ReadOnlyPrimitiveLongSet
(keys);
210
}
211
218
public
Collection<V>
values
() {
219
Collection<V>
values
=
new
ArrayList<>();
220
for
(
int
bucket = 0; bucket < m_capacity; bucket++) {
221
if
(m_uses[bucket]) {
222
values
.add(m_values[bucket]);
223
}
224
}
225
return
List.copyOf(
values
);
// return a readonly copy
226
}
227
233
@FunctionalInterface
234
public
interface
IteratorFunction
<V> {
241
void
accept
(
long
key, V value);
242
}
243
249
public
void
forEach
(
IteratorFunction<? super V>
function
) {
250
for
(
int
bucket = 0; bucket < m_capacity; bucket++) {
251
if
(m_uses[bucket]) {
252
function
.accept(m_keys[bucket], m_values[bucket]);
253
}
254
}
255
}
256
257
private
void
grow() {
258
final
int
currentSize = m_size;
259
final
int
oldCapacity = m_capacity;
260
if
(oldCapacity * LOAD_FACTOR >= currentSize) {
261
// We're below the maximum allowed size for the current capacity
262
// Nothing to do
263
return
;
264
}
265
266
final
int
newCapacity = oldCapacity * 2;
267
final
int
newMask = newCapacity - 1;
268
269
final
boolean
[] oldUses = m_uses;
270
final
long
[] oldKeys = m_keys;
271
final
V[] oldValues = m_values;
272
273
final
boolean
[] newUses =
new
boolean
[newCapacity];
274
final
long
[] newKeys =
new
long
[newCapacity];
275
@SuppressWarnings(
"unchecked"
)
276
final V[] newValues = (V[]) new Object[newCapacity];
277
278
for (
int
oldBucket = 0; oldBucket < oldCapacity; oldBucket++) {
279
if
(!oldUses[oldBucket]) {
280
// Bucket is empty, skip
281
continue
;
282
}
283
final
long
key = oldKeys[oldBucket];
284
final
V value = oldValues[oldBucket];
285
286
int
newBucket = (int) (hash(key) & newMask);
287
while
(newUses[newBucket]) {
288
newBucket = (newBucket + 1) & newMask;
289
}
290
291
newUses[newBucket] =
true
;
292
newKeys[newBucket] = key;
293
newValues[newBucket] = value;
294
}
295
296
m_capacity = newCapacity;
297
m_uses = newUses;
298
m_keys = newKeys;
299
m_values = newValues;
300
}
301
302
private
int
maxSize() {
303
return
(
int
) (m_capacity * LOAD_FACTOR);
304
}
305
313
private
long
hash(
long
key) {
314
return
31 + (key ^ (key >>> 15) ^ (key >>> 31) ^ (key << 31));
315
}
316
321
private
int
mask() {
322
return
m_capacity - 1;
323
}
324
332
private
int
bucket(
long
key) {
333
var hash = hash(key);
334
return
(
int
) (hash & mask());
335
}
336
343
private
int
safeIncrement(
int
bucket) {
344
return
(bucket + 1) & mask();
345
}
346
}
org.wpilib.units.collections.LongToObjectHashMap.LongToObjectHashMap
LongToObjectHashMap()
Definition
LongToObjectHashMap.java:58
org.wpilib.units.collections.LongToObjectHashMap.size
int size()
Definition
LongToObjectHashMap.java:173
org.wpilib.units.collections.LongToObjectHashMap.keySet
ReadOnlyPrimitiveLongSet keySet()
Definition
LongToObjectHashMap.java:198
org.wpilib.units.collections.LongToObjectHashMap.put
V put(long key, V value)
Definition
LongToObjectHashMap.java:67
org.wpilib.units.collections.LongToObjectHashMap.values
Collection< V > values()
Definition
LongToObjectHashMap.java:218
org.wpilib.units.collections.LongToObjectHashMap.forEach
void forEach(IteratorFunction<? super V > function)
Definition
LongToObjectHashMap.java:249
org.wpilib.units.collections.LongToObjectHashMap.isEmpty
boolean isEmpty()
Definition
LongToObjectHashMap.java:187
org.wpilib.units.collections.LongToObjectHashMap.clear
void clear()
Definition
LongToObjectHashMap.java:156
org.wpilib.units.collections.LongToObjectHashMap.containsKey
boolean containsKey(long key)
Definition
LongToObjectHashMap.java:144
org.wpilib.units.collections.ReadOnlyPrimitiveLongSet
Definition
ReadOnlyPrimitiveLongSet.java:14
org.wpilib.units.collections.ReadOnlyPrimitiveLongSet.ReadOnlyPrimitiveLongSet
ReadOnlyPrimitiveLongSet(long... values)
Definition
ReadOnlyPrimitiveLongSet.java:23
org.wpilib.units.collections.LongToObjectHashMap.IteratorFunction
Definition
LongToObjectHashMap.java:234
org.wpilib.units.collections.LongToObjectHashMap.IteratorFunction.accept
void accept(long key, V value)
org
wpilib
units
collections
LongToObjectHashMap.java
Generated by
1.18.0