@@ -187,14 +187,14 @@ private void reduce() {
187
187
* Increases the input ten-fold
188
188
*/
189
189
private static final int getLargerSize (int input ) {
190
- return input * 10 ;
190
+ return input << 1 ;
191
191
}
192
192
193
193
/**
194
194
* Reduces the input to a fourth
195
195
*/
196
196
private static final int getSmallerSize (int input ) {
197
- return input / 4 ;
197
+ return input >> 1 >> 1 ;
198
198
}
199
199
200
200
/**
@@ -339,16 +339,17 @@ public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
339
339
340
340
private static class ProbingHashMap <K , V > extends HashMap <K , V > {
341
341
342
- private float loadFactor = 0.75f ;
342
+ private int hashingKey = -1 ;
343
+ private float loadFactor = 0.6f ;
343
344
private int minimumSize = 1024 ;
344
345
private Pair <K , V >[] array = null ;
345
346
private int size = 0 ;
346
347
347
348
/**
348
- * Create a hash map with K as the hashing key .
349
+ * Create a hash map with K as the hash .
349
350
*
350
351
* @param size
351
- * initial size .
352
+ * to use for the hash .
352
353
*/
353
354
public ProbingHashMap (int size ) {
354
355
initializeMap (size );
@@ -371,30 +372,31 @@ public V put(K key, V value) {
371
372
372
373
private V put (Pair <K ,V > newPair ) {
373
374
V prev = null ;
374
- int index = indexOf (newPair .key . hashCode (), array . length );
375
+ int hashedKey = hashingFunction (newPair .key );
375
376
376
377
// Check initial position
377
- Pair <K , V > pair = array [index ];
378
+ Pair <K , V > pair = array [hashedKey ];
378
379
if (pair == null ) {
379
- array [index ] = newPair ;
380
+ array [hashedKey ] = newPair ;
380
381
size ++;
381
382
382
383
// If size is greater than threshold
383
384
int maxSize = (int )(loadFactor *array .length );
384
385
if (size >= maxSize )
385
- resize ();
386
+ increase ();
386
387
387
388
return prev ;
388
389
}
390
+
389
391
if (pair .key .equals (newPair .key )) {
390
392
prev = pair .value ;
391
393
pair .value = newPair .value ;
392
394
return prev ;
393
395
}
394
396
395
397
// Probing until we get back to the starting index
396
- int start = getNextIndex (index );
397
- while (start != index ) {
398
+ int start = getNextIndex (hashedKey );
399
+ while (start != hashedKey ) {
398
400
pair = array [start ];
399
401
if (pair == null ) {
400
402
array [start ] = newPair ;
@@ -403,10 +405,11 @@ private V put(Pair<K,V> newPair) {
403
405
// If size is greater than threshold
404
406
int maxSize = (int )(loadFactor *array .length );
405
407
if (size >= maxSize )
406
- resize ();
408
+ increase ();
407
409
408
410
return prev ;
409
411
}
412
+
410
413
if (pair .key .equals (newPair .key )) {
411
414
prev = pair .value ;
412
415
pair .value = newPair .value ;
@@ -424,18 +427,20 @@ private V put(Pair<K,V> newPair) {
424
427
*/
425
428
@ Override
426
429
public V get (K key ) {
430
+ int hashedKey = hashingFunction (key );
431
+ Pair <K , V > pair = array [hashedKey ];
432
+
427
433
// Check initial position
428
- int index = indexOf (key .hashCode (), array .length );
429
- Pair <K , V > pair = array [index ];
430
434
if (pair == null )
431
435
return null ;
432
436
if (pair .key .equals (key ))
433
437
return pair .value ;
434
438
435
439
// Probing until we get back to the starting index
436
- int start = getNextIndex (index );
437
- while (start != index ) {
440
+ int start = getNextIndex (hashedKey );
441
+ while (start != hashedKey ) {
438
442
pair = array [start ];
443
+
439
444
if (pair == null )
440
445
return null ;
441
446
if (pair .key .equals (key ))
@@ -460,13 +465,14 @@ public boolean contains(K key) {
460
465
*/
461
466
@ Override
462
467
public V remove (K key ) {
463
- // Check initial position
464
- int index = indexOf (key .hashCode (), array .length );
468
+ int hashedKey = hashingFunction (key );
465
469
Pair <K , V > prev = null ;
466
- Pair <K , V > pair = array [index ];
467
- if (pair !=null && pair .key .equals (key )) {
468
- prev = array [index ];
469
- array [index ] = null ;
470
+
471
+ // Check initial position
472
+ Pair <K , V > pair = array [hashedKey ];
473
+ if (pair != null && pair .key .equals (key )) {
474
+ prev = array [hashedKey ];
475
+ array [hashedKey ] = null ;
470
476
size --;
471
477
472
478
int loadFactored = (int )(size /loadFactor );
@@ -478,10 +484,10 @@ public V remove(K key) {
478
484
}
479
485
480
486
// Probing until we get back to the starting index
481
- int start = getNextIndex (index );
482
- while (start != index ) {
487
+ int start = getNextIndex (hashedKey );
488
+ while (start != hashedKey ) {
483
489
pair = array [start ];
484
- if (pair != null && pair .key .equals (key )) {
490
+ if (pair != null && pair .key .equals (key )) {
485
491
prev = array [start ];
486
492
array [start ] = null ;
487
493
size --;
@@ -493,7 +499,6 @@ public V remove(K key) {
493
499
494
500
return prev .value ;
495
501
}
496
-
497
502
start = getNextIndex (start );
498
503
}
499
504
// If we get here, probing failed.
@@ -518,13 +523,20 @@ public int size() {
518
523
return size ;
519
524
}
520
525
521
- private void resize () {
526
+ private void initializeMap (int current ) {
527
+ int length = getLargerSize (current );
528
+ array = new Pair [length ];
529
+ size = 0 ;
530
+ hashingKey = length ;
531
+ }
532
+
533
+ private void increase () {
522
534
// Save old data
523
535
Pair <K ,V >[] temp = this .array ;
524
536
525
537
// Calculate new size and assign
526
538
int length = getLargerSize (array .length );
527
- //System.out.println("resize from "+array.length+" to "+length);
539
+ //System.out.println("increase from "+array.length+" to "+length);
528
540
initializeMap (length );
529
541
530
542
// Re-hash old data
@@ -551,51 +563,41 @@ private void reduce() {
551
563
}
552
564
553
565
/**
554
- * Returns the closest base 2 number (2^x) which is larger than the 2* input
566
+ * Returns double of the input
555
567
*/
556
568
private static final int getLargerSize (int input ) {
557
- int b = (int )((Math .log (2 *input ) / Math .log (2 )));
558
- int length = (int ) Math .pow (2 , b );
559
- return length ;
569
+ return input <<1 ;
560
570
}
561
571
562
572
/**
563
- * Returns the closest base 2 number (2^x) which is smaller than the input/3
573
+ * Returns one fourth of the input
564
574
*/
565
575
private static final int getSmallerSize (int input ) {
566
- int b = (int )((Math .log (input /3 ) / Math .log (2 )));
567
- int length = (int ) Math .pow (2 , b );
568
- return length ;
569
- }
570
-
571
- /**
572
- * Initialize the hash array.
573
- */
574
- private void initializeMap (int length ) {
575
- this .array = new Pair [length ];
576
- this .size = 0 ;
576
+ return input >>1 >>1 ;
577
577
}
578
578
579
579
/**
580
580
* Returns the next index in the probing sequence, at this point it's linear
581
581
*/
582
- private int getNextIndex (int idx ) {
583
- // Linear probing
584
- int i = idx +1 ;
582
+ private int getNextIndex (int input ) {
583
+ int i = input +1 ;
585
584
if (i >= array .length )
586
- i %= array . length ;
585
+ i = 0 ;
587
586
return i ;
588
587
}
589
588
590
589
/**
591
590
* The hashing function. Converts the key into an integer.
592
591
*
593
- * @param h
592
+ * @param key
594
593
* to create a hash for.
595
594
* @return Integer which represents the key.
596
595
*/
597
- private int indexOf (int h , int length ) {
598
- return h & (length -1 );
596
+ private int hashingFunction (K key ) {
597
+ int k = key .hashCode () % hashingKey ;
598
+ if (k >=array .length )
599
+ k = k - ((k /array .length ) * array .length );
600
+ return k ;
599
601
}
600
602
601
603
/**
0 commit comments