Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed LookupMetadata hit/miss counts #100

Merged
merged 22 commits into from
Aug 8, 2019
Merged
Changes from 5 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
85013ac
Added the ability to use an existing LookupMetadata instance to
jeffrey-a-meunier Jul 31, 2019
bb24512
Fixed a bunch of stuff. Passing around more "previous" values now.
jeffrey-a-meunier Aug 1, 2019
569ad50
Removed `else` in unnecessary `else` clause.
jeffrey-a-meunier Aug 1, 2019
7f805a3
Added a "default" `generateMetaData` method to keep existsing tests
jeffrey-a-meunier Aug 1, 2019
535fd3c
Fixed accidental unbounded recursion. <smh>
jeffrey-a-meunier Aug 1, 2019
fd15f76
Wrapped calls to findKey with a timeFindKey method to ensure
jeffrey-a-meunier Aug 2, 2019
dc806b0
Using currentMetadata to get missCount and hitCount.
jeffrey-a-meunier Aug 2, 2019
eb3fbb7
Removed some debugging code that ended up not showing anything
jeffrey-a-meunier Aug 2, 2019
98e09ac
Add internal metrics objects and adders
dstuebe Aug 6, 2019
8dc0ee9
Use Builder objects to pass metrics adders
dstuebe Aug 6, 2019
a04c3b8
Add metrics to blob stores
dstuebe Aug 6, 2019
9d2484b
Add metrics to lookupdata. Fix reload. Add hash check when loading keys.
dstuebe Aug 6, 2019
c58ecfd
Add metrics. Move blocked long pos from separate file into mapped hea…
dstuebe Aug 6, 2019
d5844db
Use new metrics in benchmark
dstuebe Aug 6, 2019
695882f
Modified LookupData to support unit testing, and added unit tests
jeffrey-a-meunier Aug 6, 2019
0b76f8f
Modified unit tests to compare object identities instead of using
jeffrey-a-meunier Aug 6, 2019
37decb8
Added a few more unit tests for the LookupData.getMetadata method.
jeffrey-a-meunier Aug 7, 2019
08d5727
Fixed a unit test.
jeffrey-a-meunier Aug 7, 2019
7546c7d
Improved and corrected some unit & integration tests.
jeffrey-a-meunier Aug 7, 2019
3c616a7
Add more comments in getMetadata tests
dstuebe Aug 7, 2019
14ee603
Add todo to fix parallel test
dstuebe Aug 7, 2019
9e15002
cleanup formatting and fix access levels
dstuebe Aug 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 31 additions & 42 deletions src/main/java/com/upserve/uppend/lookup/LookupData.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class LookupData implements Flushable, Trimmable {

private final int flushThreshold;
private final int firstFlushThreshold;
private final int reloadInterval;
private final int reloadInterval; // Reload interval is specified in seconds

// The container for stuff we need to write - Only new keys can be in the write cache
final ConcurrentHashMap<LookupKey, Long> writeCache;
Expand Down Expand Up @@ -65,7 +65,6 @@ public static LookupData lookupReader(VirtualLongBlobStore keyLongBlobs, Virtual
}

private LookupData(VirtualLongBlobStore keyLongBlobs, VirtualMutableBlobStore metadataBlobs, int flushThreshold, int reloadInterval, boolean readOnly) {

this.keyLongBlobs = keyLongBlobs;
this.metadataBlobs = metadataBlobs;

Expand Down Expand Up @@ -367,40 +366,34 @@ private Long findValueFor(LookupKey key) {
}

LookupMetadata loadMetadata() {
if (readOnly) {
try {
return LookupMetadata.open(
getMetadataBlobs(),
getMetaDataGeneration(),
getMetaMissCount(),
getMetaHitCount()
);
} catch (IllegalStateException e) {
// Try again and let the exception bubble if it fails
return loadMetadata(new LongAdder(), new LongAdder());
}

LookupMetadata loadMetadata(LongAdder prevMissCount, LongAdder prevHitCount) {
try {
return LookupMetadata.open(
getMetadataBlobs(),
getMetaDataGeneration(),
prevMissCount,
prevHitCount
);
} catch (IllegalStateException e) {
if (readOnly) {
log.warn("getMetaData failed for read only store - attempting to reload!", e);
// Try again and let the exception bubble if it fails
return LookupMetadata.open(
getMetadataBlobs(),
getMetaDataGeneration(),
getMetaMissCount(),
getMetaHitCount()
);
}
} else {
try {
return LookupMetadata.open(
getMetadataBlobs(),
getMetaDataGeneration(),
getMetaMissCount(),
getMetaHitCount()
prevMissCount,
prevHitCount
);
} catch (IllegalStateException e) {
log.warn("getMetaData failed for read write store - attempting to repair it!", e);
return repairMetadata();
}
log.warn("getMetaData failed for read write store - attempting to repair it!", e);
return repairMetadata(prevMissCount, prevHitCount);
jeffrey-a-meunier marked this conversation as resolved.
Show resolved Hide resolved
}
}

private synchronized LookupMetadata repairMetadata() {
private synchronized LookupMetadata repairMetadata(LongAdder prevMissCount, LongAdder prevHitCount) {
int[] sortedPositions = keyLongBlobs.positionBlobStream()
.sorted(Comparator.comparing(entry -> new LookupKey(entry.getValue())))
.mapToInt(entry -> entry.getKey().intValue())
Expand All @@ -409,7 +402,7 @@ private synchronized LookupMetadata repairMetadata() {
int sortedPositionsSize = sortedPositions.length;
LookupKey minKey = sortedPositionsSize > 0 ? readKey((long) sortedPositions[0]) : null;
LookupKey maxKey = sortedPositionsSize > 0 ? readKey((long) sortedPositions[sortedPositionsSize - 1]) : null;
return LookupMetadata.generateMetadata(minKey, maxKey, sortedPositions, metadataBlobs, metaDataGeneration.incrementAndGet(), getMetaMissCount(), getMetaHitCount());
return LookupMetadata.generateMetadata(minKey, maxKey, sortedPositions, metadataBlobs, metaDataGeneration.incrementAndGet(), prevMissCount, prevHitCount);
} catch (IOException e) {
throw new UncheckedIOException("Unable to write repaired metadata!", e);
}
Expand All @@ -419,14 +412,6 @@ private int getMetaDataGeneration() {
return metaDataGeneration.get();
}

private LongAdder getMetaHitCount() {
return Optional.ofNullable(atomicMetadataRef.get()).map(md -> md.hitCount).orElse(new LongAdder());
}

private LongAdder getMetaMissCount() {
return Optional.ofNullable(atomicMetadataRef.get()).map(md -> md.missCount).orElse(new LongAdder());
}

/**
* Create a copy of the keys currently in the write cache
*
Expand Down Expand Up @@ -508,6 +493,10 @@ void flushWriteCache(LookupMetadata currentMetadata) {
}

void generateMetaData(LookupMetadata currentMetadata) {
generateMetaData(currentMetadata, new LongAdder(), new LongAdder());
}

void generateMetaData(LookupMetadata currentMetadata, LongAdder prevMissCount, LongAdder prevHitCount) {
jeffrey-a-meunier marked this conversation as resolved.
Show resolved Hide resolved
int[] currentKeySortOrder = currentMetadata.getKeyStorageOrder();

int flushSize = flushCache.size();
Expand Down Expand Up @@ -564,8 +553,8 @@ void generateMetaData(LookupMetadata currentMetadata) {
newKeySortOrder,
metadataBlobs,
metaDataGeneration.incrementAndGet(),
getMetaMissCount(),
getMetaHitCount())
prevMissCount,
prevHitCount)
);
} catch (IOException e) {
throw new UncheckedIOException("Failed to write new metadata!", e);
Expand All @@ -579,10 +568,10 @@ protected LookupMetadata getMetadata() {

// Convert millis to seconds
if (((System.currentTimeMillis() - startTime) / 1000) > stamp[0]){
boolean luckyMe = reloadStamp.compareAndSet(stamp[0], stamp[0] + reloadInterval);

if (luckyMe) {
result = loadMetadata();
// a reloadInterval of 0 prevents reloading of the metadata
boolean reloadMetadata = !reloadStamp.compareAndSet(stamp[0], stamp[0] + reloadInterval);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's test this a bunch.
We need to figure out how to hit both the elapsed time condition and the first thread to compare and set...

if (reloadMetadata) {
result = loadMetadata(result.missCount, result.hitCount);
timeStampedMetadata.set(result, stamp[0] + reloadInterval);
jeffrey-a-meunier marked this conversation as resolved.
Show resolved Hide resolved
}
}
Expand Down