Skip to content

Commit 14f0b48

Browse files
authored
Improve performance of LongObjectPagedHashMap#removeAndAdd and ObjectObjectPagedHashMap#removeAndAdd (#114280)
1 parent 388d24f commit 14f0b48

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

server/src/main/java/org/elasticsearch/common/util/LongObjectPagedHashMap.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public T get(long key) {
6363
* an insertion.
6464
*/
6565
public T put(long key, T value) {
66+
assert value != null : "Null values are not supported";
6667
if (size >= maxSize) {
6768
assert size == maxSize;
6869
grow();
@@ -94,9 +95,6 @@ public T remove(long key) {
9495
}
9596

9697
private T set(long key, T value) {
97-
if (value == null) {
98-
throw new IllegalArgumentException("Null values are not supported");
99-
}
10098
for (long i = slot(hash(key), mask);; i = nextSlot(i, mask)) {
10199
final T previous = values.getAndSet(i, value);
102100
if (previous == null) {
@@ -116,7 +114,7 @@ private T set(long key, T value) {
116114

117115
@Override
118116
public Iterator<Cursor<T>> iterator() {
119-
return new Iterator<Cursor<T>>() {
117+
return new Iterator<>() {
120118

121119
boolean cached;
122120
final Cursor<T> cursor;
@@ -181,9 +179,21 @@ protected boolean used(long bucket) {
181179
protected void removeAndAdd(long index) {
182180
final long key = keys.get(index);
183181
final T value = values.getAndSet(index, null);
184-
--size;
185-
final T removed = set(key, value);
186-
assert removed == null;
182+
reset(key, value);
183+
}
184+
185+
private void reset(long key, T value) {
186+
final ObjectArray<T> values = this.values;
187+
final long mask = this.mask;
188+
for (long i = slot(hash(key), mask);; i = nextSlot(i, mask)) {
189+
final T previous = values.get(i);
190+
if (previous == null) {
191+
// slot was free
192+
keys.set(i, key);
193+
values.set(i, value);
194+
break;
195+
}
196+
}
187197
}
188198

189199
public static final class Cursor<T> {

server/src/main/java/org/elasticsearch/common/util/ObjectObjectPagedHashMap.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public V get(K key) {
6767
* an insertion.
6868
*/
6969
public V put(K key, V value) {
70+
assert value != null : "Null values are not supported";
7071
if (size >= maxSize) {
7172
assert size == maxSize;
7273
grow();
@@ -100,7 +101,6 @@ public V remove(K key) {
100101

101102
private V set(K key, int code, V value) {
102103
assert key.hashCode() == code;
103-
assert value != null;
104104
assert size < maxSize;
105105
final long slot = slot(code, mask);
106106
for (long index = slot;; index = nextSlot(index, mask)) {
@@ -187,9 +187,22 @@ protected boolean used(long bucket) {
187187
protected void removeAndAdd(long index) {
188188
final K key = keys.get(index);
189189
final V value = values.getAndSet(index, null);
190-
--size;
191-
final V removed = set(key, key.hashCode(), value);
192-
assert removed == null;
190+
reset(key, value);
191+
}
192+
193+
private void reset(K key, V value) {
194+
final ObjectArray<V> values = this.values;
195+
final long mask = this.mask;
196+
final long slot = slot(key.hashCode(), mask);
197+
for (long index = slot;; index = nextSlot(index, mask)) {
198+
final V previous = values.get(index);
199+
if (previous == null) {
200+
// slot was free
201+
values.set(index, value);
202+
keys.set(index, key);
203+
break;
204+
}
205+
}
193206
}
194207

195208
public static final class Cursor<K, V> {

0 commit comments

Comments
 (0)