Skip to content

Commit f764d13

Browse files
committed
Simplify address + length calculation in Location.
1 parent 079f1bf commit f764d13

File tree

2 files changed

+49
-43
lines changed

2 files changed

+49
-43
lines changed

unsafe/src/main/java/org/apache/spark/unsafe/map/BytesToBytesMap.java

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@
2727
import org.apache.spark.unsafe.memory.MemoryBlock;
2828
import org.apache.spark.unsafe.memory.MemoryLocation;
2929

30-
import java.lang.IllegalStateException;import java.lang.Long;import java.lang.Object;import java.lang.Override;import java.lang.UnsupportedOperationException;import java.util.Iterator;
30+
import java.lang.IllegalStateException;
31+
import java.lang.Long;
32+
import java.lang.Object;
33+
import java.lang.Override;
34+
import java.lang.UnsupportedOperationException;
35+
import java.util.Iterator;
3136
import java.util.LinkedList;
3237
import java.util.List;
3338

@@ -198,7 +203,6 @@ public Location lookup(
198203
Object keyBaseObject,
199204
long keyBaseOffset,
200205
int keyRowLengthBytes) {
201-
202206
final int hashcode = HASHER.hashUnsafeWords(keyBaseObject, keyBaseOffset, keyRowLengthBytes);
203207
long pos = ((long) hashcode) & mask;
204208
long step = 1;
@@ -210,7 +214,7 @@ public Location lookup(
210214
long stored = longArray.get(pos * 2 + 1);
211215
if (((int) (stored & MASK_LONG_LOWER_32_BITS)) == hashcode) {
212216
// Full hash code matches. Let's compare the keys for equality.
213-
loc.with(pos, hashcode, false);
217+
loc.with(pos, hashcode, true);
214218
if (loc.getKeyLength() == keyRowLengthBytes) {
215219
final MemoryLocation keyAddress = loc.getKeyAddress();
216220
final Object storedKeyBaseObject = keyAddress.getBaseObject();
@@ -223,7 +227,7 @@ public Location lookup(
223227
keyRowLengthBytes
224228
);
225229
if (areEqual) {
226-
return loc.with(pos, hashcode, true);
230+
return loc;
227231
}
228232
}
229233
}
@@ -239,7 +243,7 @@ public Location lookup(
239243
public final class Location {
240244
/** An index into the hash map's Long array */
241245
private long pos;
242-
/** True if this location points to a position where a key is defined, felase otherwise */
246+
/** True if this location points to a position where a key is defined, false otherwise */
243247
private boolean isDefined;
244248
/**
245249
* The hashcode of the most recent key passed to
@@ -249,11 +253,36 @@ public final class Location {
249253
private int keyHashcode;
250254
private final MemoryLocation keyMemoryLocation = new MemoryLocation();
251255
private final MemoryLocation valueMemoryLocation = new MemoryLocation();
256+
private long keyLength;
257+
private long valueLength;
258+
259+
private void updateAddressesAndSizes(long fullKeyAddress, long offsetFromKeyToValue) {
260+
if (inHeap) {
261+
final Object page = getPage(fullKeyAddress);
262+
final long keyOffsetInPage = getOffsetInPage(fullKeyAddress);
263+
keyMemoryLocation.setObjAndOffset(page, keyOffsetInPage + 8);
264+
valueMemoryLocation.setObjAndOffset(page, keyOffsetInPage + 8 + offsetFromKeyToValue);
265+
keyLength = PlatformDependent.UNSAFE.getLong(page, keyOffsetInPage);
266+
valueLength =
267+
PlatformDependent.UNSAFE.getLong(page, keyOffsetInPage + offsetFromKeyToValue);
268+
} else {
269+
keyMemoryLocation.setObjAndOffset(null, fullKeyAddress + 8);
270+
valueMemoryLocation.setObjAndOffset(null, fullKeyAddress + 8 + offsetFromKeyToValue);
271+
keyLength = PlatformDependent.UNSAFE.getLong(fullKeyAddress);
272+
valueLength = PlatformDependent.UNSAFE.getLong(fullKeyAddress + offsetFromKeyToValue);
273+
}
274+
}
252275

253276
Location with(long pos, int keyHashcode, boolean isDefined) {
254277
this.pos = pos;
255278
this.isDefined = isDefined;
256279
this.keyHashcode = keyHashcode;
280+
if (isDefined) {
281+
final long fullKeyAddress = longArray.get(pos * 2);
282+
final long offsetFromKeyToValue =
283+
(longArray.get(pos * 2 + 1) & ~MASK_LONG_LOWER_32_BITS) >>> 32;
284+
updateAddressesAndSizes(fullKeyAddress, offsetFromKeyToValue);
285+
}
257286
return this;
258287
}
259288

@@ -275,6 +304,7 @@ private Object getPage(long fullKeyAddress) {
275304
}
276305

277306
private long getOffsetInPage(long fullKeyAddress) {
307+
assert (inHeap);
278308
return (fullKeyAddress & MASK_LONG_LOWER_51_BITS);
279309
}
280310

@@ -285,13 +315,7 @@ private long getOffsetInPage(long fullKeyAddress) {
285315
* For efficiency reasons, calls to this method always returns the same MemoryLocation object.
286316
*/
287317
public MemoryLocation getKeyAddress() {
288-
final long fullKeyAddress = longArray.get(pos * 2);
289-
if (inHeap) {
290-
keyMemoryLocation.setObjAndOffset(
291-
getPage(fullKeyAddress), getOffsetInPage(fullKeyAddress) + 8);
292-
} else {
293-
keyMemoryLocation.setObjAndOffset(null, fullKeyAddress + 8);
294-
}
318+
assert (isDefined);
295319
return keyMemoryLocation;
296320
}
297321

@@ -300,13 +324,8 @@ public MemoryLocation getKeyAddress() {
300324
* Unspecified behavior if the key is not defined.
301325
*/
302326
public long getKeyLength() {
303-
final long fullKeyAddress = longArray.get(pos * 2);
304-
if (inHeap) {
305-
return PlatformDependent.UNSAFE.getLong(
306-
getPage(fullKeyAddress), getOffsetInPage(fullKeyAddress));
307-
} else {
308-
return PlatformDependent.UNSAFE.getLong(fullKeyAddress);
309-
}
327+
assert (isDefined);
328+
return keyLength;
310329
}
311330

312331
/**
@@ -316,18 +335,7 @@ public long getKeyLength() {
316335
* For efficiency reasons, calls to this method always returns the same MemoryLocation object.
317336
*/
318337
public MemoryLocation getValueAddress() {
319-
// The relative offset from the key position to the value position was stored in the upper 32
320-
// bits of the value long:
321-
final long offsetFromKeyToValue = (longArray.get(pos * 2 + 1) & ~MASK_LONG_LOWER_32_BITS) >>> 32;
322-
final long fullKeyAddress = longArray.get(pos * 2);
323-
if (inHeap) {
324-
valueMemoryLocation.setObjAndOffset(
325-
getPage(fullKeyAddress),
326-
getOffsetInPage(fullKeyAddress) + 8 + offsetFromKeyToValue
327-
);
328-
} else {
329-
valueMemoryLocation.setObjAndOffset(null, fullKeyAddress + 8 + offsetFromKeyToValue);
330-
}
338+
assert (isDefined);
331339
return valueMemoryLocation;
332340
}
333341

@@ -336,18 +344,8 @@ public MemoryLocation getValueAddress() {
336344
* Unspecified behavior if the key is not defined.
337345
*/
338346
public long getValueLength() {
339-
// The relative offset from the key position to the value position was stored in the upper 32
340-
// bits of the value long:
341-
final long offsetFromKeyToValue = (longArray.get(pos * 2 + 1) & ~MASK_LONG_LOWER_32_BITS) >>> 32;
342-
final long fullKeyAddress = longArray.get(pos * 2);
343-
if (inHeap) {
344-
return PlatformDependent.UNSAFE.getLong(
345-
getPage(fullKeyAddress),
346-
getOffsetInPage(fullKeyAddress) + offsetFromKeyToValue
347-
);
348-
} else {
349-
return PlatformDependent.UNSAFE.getLong(fullKeyAddress + offsetFromKeyToValue);
350-
}
347+
assert (isDefined);
348+
return valueLength;
351349
}
352350

353351
/**
@@ -439,6 +437,8 @@ public void storeKeyAndValue(
439437
final long storedValueOffsetAndKeyHashcode =
440438
(relativeOffsetFromKeyToValue << 32) | (keyHashcode & MASK_LONG_LOWER_32_BITS);
441439
longArray.set(pos * 2 + 1, storedValueOffsetAndKeyHashcode);
440+
updateAddressesAndSizes(storedKeyAddress, relativeOffsetFromKeyToValue);
441+
isDefined = true;
442442
if (size > growthThreshold) {
443443
growAndRehash();
444444
}

unsafe/src/test/java/org/apache/spark/unsafe/map/AbstractTestBytesToBytesMap.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,13 @@ public void randomizedStressTest() {
204204
BYTE_ARRAY_OFFSET,
205205
value.length
206206
);
207+
// After calling storeKeyAndValue, the following should be true, even before calling
208+
// lookup():
207209
Assert.assertTrue(loc.isDefined());
210+
Assert.assertEquals(key.length, loc.getKeyLength());
211+
Assert.assertEquals(value.length, loc.getValueLength());
212+
Assert.assertTrue(arrayEquals(key, loc.getKeyAddress(), key.length));
213+
Assert.assertTrue(arrayEquals(value, loc.getValueAddress(), value.length));
208214
}
209215
}
210216

0 commit comments

Comments
 (0)