2727import org .apache .spark .unsafe .memory .MemoryBlock ;
2828import 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 ;
3136import java .util .LinkedList ;
3237import 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 }
0 commit comments