Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored LongCache

Added tests to guarantee average lowWatermark increasing speed
  • Loading branch information...
commit dd53f237c270bd7668b393eb91213c320a0dec59 1 parent 03c676e
Daniel Gómez Ferro authored
43 src/main/java/com/yahoo/omid/tso/CommitHashMap.java
View
@@ -33,10 +33,9 @@
class CommitHashMap {
- private final int size;
private long largestDeletedTimestamp;
- private final long[] startCommitMapping;
- private final long[] rowsCommitMapping;
+ private final LongCache startCommitMapping;
+ private final LongCache rowsCommitMapping;
/**
* Constructs a new, empty hashtable with a default size of 1000
@@ -59,53 +58,27 @@ public CommitHashMap(int size) {
throw new IllegalArgumentException("Illegal size: " + size);
}
- this.size = size;
- this.startCommitMapping = new long[size * 2];
- this.rowsCommitMapping = new long[size * 2];
- }
-
- private int index(long hash) {
- return (int) (Math.abs(hash) % size);
+ this.startCommitMapping = new LongCache(size, 2);
+ this.rowsCommitMapping = new LongCache(size, 8);
}
public long getLatestWriteForRow(long hash) {
- int index = index(hash);
- return rowsCommitMapping[index];
+ return rowsCommitMapping.get(hash);
}
public void putLatestWriteForRow(long hash, long commitTimestamp) {
- int index = index(hash);
- long oldCommitTS = rowsCommitMapping[index];
-
- if (oldCommitTS == commitTimestamp)
- return;
-
- rowsCommitMapping[index] = commitTimestamp;
+ long oldCommitTS = rowsCommitMapping.set(hash, commitTimestamp);
largestDeletedTimestamp = Math
.max(oldCommitTS, largestDeletedTimestamp);
}
public long getCommittedTimestamp(long startTimestamp) {
- int indexStart = 2 * index(startTimestamp);
- int indexCommit = indexStart + 1;
-
- if (startCommitMapping[indexStart] == startTimestamp) {
- return startCommitMapping[indexCommit];
- } else {
- return 0;
- }
+ return startCommitMapping.get(startTimestamp);
}
public void setCommittedTimestamp(long startTimestamp, long commitTimestamp) {
- int indexStart = 2 * index(startTimestamp);
- int indexCommit = indexStart + 1;
-
- long oldCommitTS = startCommitMapping[indexCommit];
- if (oldCommitTS == commitTimestamp)
- return;
+ long oldCommitTS = startCommitMapping.set(startTimestamp, commitTimestamp);
- startCommitMapping[indexStart] = startTimestamp;
- startCommitMapping[indexCommit] = commitTimestamp;
largestDeletedTimestamp = Math
.max(oldCommitTS, largestDeletedTimestamp);
}
46 src/main/java/com/yahoo/omid/tso/LongCache.java
View
@@ -0,0 +1,46 @@
+package com.yahoo.omid.tso;
+
+public class LongCache {
+
+ private final long [] cache;
+ private final int size;
+ private final int associativity;
+
+ public LongCache(int size, int associativity) {
+ this.size = size;
+ this.cache = new long[2*(size + associativity)];
+ this.associativity = associativity;
+ }
+
+ public long set(long key, long value) {
+ final int index = index(key);
+ int oldestIndex = 0;
+ long oldestValue = Long.MAX_VALUE;
+ for (int i = 0; i < associativity; ++i) {
+ int currIndex = 2 * (index + i);
+ if (cache[currIndex + 1] <= oldestValue) {
+ oldestValue = cache[currIndex + 1];
+ oldestIndex = currIndex;
+ }
+ }
+ cache[oldestIndex] = key;
+ cache[oldestIndex + 1] = value;
+ return oldestValue;
+ }
+
+ public long get(long key) {
+ final int index = index(key);
+ for (int i = 0; i < associativity; ++i) {
+ int currIndex = 2 * (index + i);
+ if (cache[currIndex] == key) {
+ return cache[currIndex + 1];
+ }
+ }
+ return 0;
+ }
+
+ private int index(long hash) {
+ return (int) (Math.abs(hash) % size);
+ }
+
+}
6 src/main/java/com/yahoo/omid/tso/TSOHandler.java
View
@@ -53,6 +53,7 @@
import com.yahoo.omid.tso.messages.CommitRequest;
import com.yahoo.omid.tso.messages.CommitResponse;
import com.yahoo.omid.tso.messages.FullAbortRequest;
+import com.yahoo.omid.tso.messages.LargestDeletedTimestampReport;
import com.yahoo.omid.tso.messages.TimestampRequest;
import com.yahoo.omid.tso.messages.TimestampResponse;
import com.yahoo.omid.tso.persistence.LoggerAsyncCallback.AddRecordCallback;
@@ -226,6 +227,7 @@ public void handle(TimestampRequest msg, ChannelHandlerContext ctx) {
buffer.initializeIndexes();
}
}
+ channel.write(new LargestDeletedTimestampReport(sharedState.largestDeletedTimestamp));
for (AbortedTransaction halfAborted : sharedState.hashmap.halfAborted) {
channel.write(new AbortedTransactionReport(halfAborted.getStartTimestamp()));
}
@@ -299,8 +301,8 @@ public void handle(CommitRequest msg, ChannelHandlerContext ctx) {
if (msg.startTimestamp < timestampOracle.first()) {
reply.committed = false;
LOG.warn("Aborting transaction after restarting TSO");
- } else if (msg.startTimestamp < sharedState.largestDeletedTimestamp) {
- // Too old
+ } else if (msg.rows.length > 0 && msg.startTimestamp < sharedState.largestDeletedTimestamp) {
+ // Too old and not read only
reply.committed = false;// set as abort
LOG.warn("Too old starttimestamp: ST " + msg.startTimestamp + " MAX "
+ sharedState.largestDeletedTimestamp);
41 src/test/java/com/yahoo/omid/tso/Histogram.java
View
@@ -0,0 +1,41 @@
+package com.yahoo.omid.tso;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Histogram {
+ private static final Log LOG = LogFactory.getLog(Histogram.class);
+ final private int size;
+ final private int [] counts;
+ private int max;
+
+ public Histogram(int size) {
+ this.size = size;
+ this.counts = new int[size];
+ }
+
+ public void add(int i) {
+ if (i > size) {
+ LOG.error("Tried to add " + i + " which is bigger than size " + size);
+ return;
+ }
+ counts[i]++;
+ if (i > max) {
+ max = i;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(max).append('\n');
+ for (int i = 0; i <= max; ++i ) {
+ sb.append("[").append(i).append("]\t");
+ }
+ sb.append('\n');
+ for (int i = 0; i <= max; ++i ) {
+ sb.append(counts[i]).append("\t");
+ }
+ return sb.toString();
+ }
+}
58 src/test/java/com/yahoo/omid/tso/TestLongCache.java
View
@@ -0,0 +1,58 @@
+package com.yahoo.omid.tso;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.number.OrderingComparison.greaterThan;
+import static org.junit.Assert.assertThat;
+
+import java.util.Random;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+
+public class TestLongCache {
+
+ private static final Log LOG = LogFactory.getLog(TestLongCache.class);
+
+ @Test
+ public void testEntriesAge() {
+ final int entries = 10;
+
+ Histogram hist = new Histogram(entries * 10);
+
+ LongCache cache = new LongCache(entries, 1);
+ Random random = new Random();
+
+ long seed = random.nextLong();
+
+ LOG.info("Random seed: " + seed);
+ random.setSeed(seed);
+ int removals = 0;
+ long totalAge = 0;
+ double tempStdDev = 0;
+ double tempAvg = 0;
+
+ int i = 0;
+ for (; i < entries * 10; ++i) {
+ cache.set(random.nextLong(), i);
+ }
+
+ for (; i < entries * 100; ++i) {
+ long removed = cache.set(random.nextLong(), i);
+ int age = i - ((int) removed);
+ removals++;
+ totalAge += age;
+ double oldAvg = tempAvg;
+ tempAvg += (age - tempAvg) / removals;
+ tempStdDev += (age - oldAvg) * (age - tempAvg);
+ hist.add(age);
+ }
+
+ double avgAge = totalAge / (double) removals;
+ LOG.info("Avg age: " + (avgAge ));
+ LOG.info("Avg age: " + (tempAvg ));
+ LOG.info("Std dev age: " + Math.sqrt((tempStdDev / entries)));
+ System.out.println(hist.toString());
+ assertThat(avgAge, is(greaterThan(entries * .9 )));
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.