forked from the-qa-company/qEndpoint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
the-qa-companyGH-528 improve binary search in super blocks by keeping…
… track of the estimated location of values in the underlying long array. This assumes that the values are ordered.
- Loading branch information
1 parent
f5bb5ce
commit 5a45912
Showing
9 changed files
with
306 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
...int-core/src/main/java/com/the_qa_company/qendpoint/core/util/disk/AbstractLongArray.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.the_qa_company.qendpoint.core.util.disk; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public abstract class AbstractLongArray implements LongArray { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(getClass()); | ||
|
||
private final int ESTIMATED_LOCATION_ARRAY_SIZE = 1024 * 128; | ||
|
||
// should take about 1MB per array when PREV_FOUND_SIZE is 1024 * 128 | ||
private final long[] estimatedLocationMax = new long[ESTIMATED_LOCATION_ARRAY_SIZE]; | ||
private final long[] estimatedLocationMin = new long[ESTIMATED_LOCATION_ARRAY_SIZE]; | ||
private final long[] estimatedLocation = new long[ESTIMATED_LOCATION_ARRAY_SIZE]; | ||
|
||
private int estimatedLocationBucketSize; | ||
|
||
long maxValue = 1; | ||
|
||
@Override | ||
public int getEstimatedLocationArrayBucketSize() { | ||
return estimatedLocationBucketSize; | ||
} | ||
|
||
private void updateEstimatedLocationArrayBucketSize() { | ||
int minBucketSize = (int) (maxValue / ESTIMATED_LOCATION_ARRAY_SIZE); | ||
// we want to have the next power of 2 | ||
int next = 1; | ||
while (next < minBucketSize) { | ||
next <<= 1; | ||
} | ||
this.estimatedLocationBucketSize = next; | ||
} | ||
|
||
@Override | ||
public long[] getEstimatedLocationArray() { | ||
return estimatedLocation; | ||
} | ||
|
||
@Override | ||
public long[] getEstimatedLocationArrayMin() { | ||
return estimatedLocationMin; | ||
} | ||
|
||
@Override | ||
public long[] getEstimatedLocationArrayMax() { | ||
return estimatedLocationMax; | ||
} | ||
|
||
@Override | ||
public void recalculateEstimatedValueLocation() { | ||
updateEstimatedLocationArrayBucketSize(); | ||
int estimatedLocationBucketSize = getEstimatedLocationArrayBucketSize(); | ||
long len = length(); | ||
boolean shouldLog = len > 1024 * 1024 * 2; | ||
if (shouldLog) { | ||
logger.info("Recalculating estimated location array 0%"); | ||
} | ||
|
||
for (int i = 0; i < len; i++) { | ||
long val = get(i); | ||
if (val == 0) { | ||
continue; | ||
} | ||
|
||
int index = (int) (val / estimatedLocationBucketSize + 1); | ||
estimatedLocationMax[index] = Math.max(estimatedLocationMax[index], i); | ||
if (estimatedLocationMin[index] == 0) { | ||
estimatedLocationMin[index] = i; | ||
} else { | ||
estimatedLocationMin[index] = Math.min(estimatedLocationMin[index], i); | ||
} | ||
estimatedLocation[index] = (estimatedLocationMax[index] + estimatedLocationMin[index]) / 2; | ||
|
||
if (shouldLog && i % (1024 * 1024) == 0) { | ||
logger.info("Recalculating estimated location array {}%", (int) Math.floor(100.0 / len * i)); | ||
} | ||
} | ||
|
||
if (shouldLog) { | ||
logger.info("Recalculating estimated location array 100%"); | ||
} | ||
} | ||
|
||
@Override | ||
public final void set(long index, long value) { | ||
maxValue = Math.max(maxValue, value); | ||
innerSet(index, value); | ||
} | ||
|
||
abstract protected void innerSet(long index, long value); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.