summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2012-11-06 00:19:54 +0000
committerBrian S. O'Neill <bronee@gmail.com>2012-11-06 00:19:54 +0000
commit79d893ac1bad62d94750b26980f45928330870ed (patch)
tree47ace7f6c697a376c2ed820b83df75fbf5198ad4 /src/main
parentfb4121548fcbd904db954f171989686a46291dab (diff)
Layout metadata sync fixes.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/amazon/carbonado/layout/Layout.java50
-rw-r--r--src/main/java/com/amazon/carbonado/layout/LayoutFactory.java51
-rw-r--r--src/main/java/com/amazon/carbonado/layout/LayoutSync.java27
3 files changed, 84 insertions, 44 deletions
diff --git a/src/main/java/com/amazon/carbonado/layout/Layout.java b/src/main/java/com/amazon/carbonado/layout/Layout.java
index 89806fe..d11e4ef 100644
--- a/src/main/java/com/amazon/carbonado/layout/Layout.java
+++ b/src/main/java/com/amazon/carbonado/layout/Layout.java
@@ -41,6 +41,7 @@ import com.amazon.carbonado.FetchException;
import com.amazon.carbonado.FetchNoneException;
import com.amazon.carbonado.PersistException;
import com.amazon.carbonado.Query;
+import com.amazon.carbonado.Repository;
import com.amazon.carbonado.RepositoryException;
import com.amazon.carbonado.Storable;
import com.amazon.carbonado.Storage;
@@ -343,30 +344,38 @@ public class Layout {
{
final String filter = "storableTypeName = ? & generation = ?";
- final FetchNoneException ex;
try {
- return mLayoutFactory.mLayoutStorage
+ StoredLayoutEquivalence equiv =
+ mLayoutFactory.mRepository.storageFor(StoredLayoutEquivalence.class)
.query(filter)
.with(getStorableTypeName()).with(generation)
- .loadOne();
- } catch (FetchNoneException e) {
- ex = e;
+ .tryLoadOne();
+ if (equiv != null) {
+ generation = equiv.getMatchedGeneration();
+ }
+ } catch (RepositoryException e) {
+ throw e.toFetchException();
}
- // Index might be inconsistent.
- Cursor<StoredLayout> c =
- FilteredCursor.applyFilter(mLayoutFactory.mLayoutStorage.query().fetch(),
- StoredLayout.class, filter,
- getStorableTypeName(), generation);
-
try {
- if (c.hasNext()) {
- return c.next();
+ Cursor<StoredLayout> c = findLayouts
+ (mLayoutFactory.mRepository, getStorableTypeName(), generation);
+
+ try {
+ if (c.hasNext()) {
+ return c.next();
+ }
+ } finally {
+ c.close();
}
- } finally {
- c.close();
+ } catch (RepositoryException e) {
+ throw e.toFetchException();
}
+ FetchException ex = new FetchNoneException
+ ("Layout generation not found: " + getStorableTypeName() + ", " + generation);
+
+
// Try to resync with a master.
ResyncCapability cap =
mLayoutFactory.mRepository.getCapability(ResyncCapability.class);
@@ -400,6 +409,17 @@ public class Layout {
return storedLayout;
}
+ static Cursor<StoredLayout> findLayouts(Repository repo,
+ String storableTypeName, int generation)
+ throws RepositoryException
+ {
+ // Query without using the index, in case it's inconsistent.
+ return FilteredCursor.applyFilter
+ (repo.storageFor(StoredLayout.class).query().fetch(),
+ StoredLayout.class, "storableTypeName = ? & generation = ?",
+ storableTypeName, generation);
+ }
+
/**
* Returns the previous known generation of the storable's layout, or null
* if none.
diff --git a/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java b/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java
index 5a29152..c4333da 100644
--- a/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java
+++ b/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java
@@ -269,7 +269,7 @@ public class LayoutFactory implements LayoutCapability {
// exception, which prevents the mistake from persisting.
assert(newLayout != null);
- int generation = nextGeneration(info.getStorableType().getName());
+ int generation = nextGeneration(mRepository, info.getStorableType().getName());
newLayout.insert(readOnly, generation);
layout = newLayout;
@@ -372,7 +372,7 @@ public class LayoutFactory implements LayoutCapability {
} else {
// Assume alternate key constraint, so increment the generation.
storedLayout.setGeneration
- (nextGeneration(storedLayout.getStorableTypeName()));
+ (nextGeneration(mRepository, storedLayout.getStorableTypeName()));
storedLayout.insert();
}
}
@@ -413,19 +413,56 @@ public class LayoutFactory implements LayoutCapability {
mReconstructed.put(reconstructed, layout);
}
- private int nextGeneration(String typeName) throws FetchException {
- Cursor<StoredLayout> cursor = mLayoutStorage
- .query("storableTypeName = ?").with(typeName).orderBy("-generation").fetch();
+ static int nextGeneration(Repository repo, String typeName) throws FetchException {
+ int highestGen = -1;
+ {
+ Cursor<StoredLayout> cursor;
+ try {
+ cursor = repo.storageFor(StoredLayout.class).query("storableTypeName = ?")
+ .with(typeName).orderBy("-generation").fetchSlice(0, 1L);
+ } catch (RepositoryException e) {
+ throw e.toFetchException();
+ }
+
+ try {
+ if (cursor.hasNext()) {
+ highestGen = cursor.next().getGeneration();
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ Storage<StoredLayoutEquivalence> es;
+ try {
+ es = repo.storageFor(StoredLayoutEquivalence.class);
+ } catch (RepositoryException e) {
+ throw e.toFetchException();
+ }
+
+ Cursor<StoredLayoutEquivalence> cursor = es.query("storableTypeName = ?")
+ .with(typeName).orderBy("-generation").fetchSlice(0, 1L);
+
+ try {
+ if (cursor.hasNext()) {
+ highestGen = Math.max(highestGen, cursor.next().getGeneration());
+ }
+ } finally {
+ cursor.close();
+ }
+
+ cursor = es.query("storableTypeName = ?")
+ .with(typeName).orderBy("-matchedGeneration").fetchSlice(0, 1L);
try {
if (cursor.hasNext()) {
- return cursor.next().getGeneration() + 1;
+ highestGen = Math.max(highestGen, cursor.next().getMatchedGeneration());
}
} finally {
cursor.close();
}
- return 0;
+ return highestGen + 1;
}
/**
diff --git a/src/main/java/com/amazon/carbonado/layout/LayoutSync.java b/src/main/java/com/amazon/carbonado/layout/LayoutSync.java
index 510dc82..cf311e0 100644
--- a/src/main/java/com/amazon/carbonado/layout/LayoutSync.java
+++ b/src/main/java/com/amazon/carbonado/layout/LayoutSync.java
@@ -178,6 +178,7 @@ public class LayoutSync {
String storableTypeName = src.getStorableTypeName();
if (!storableTypeName.equals(dst.getStorableTypeName())) {
+ // Assume that there's never any hashcode collision.
throw new AssertionError();
}
@@ -267,31 +268,13 @@ public class LayoutSync {
private int nextGen(Repository repo, String storableTypeName)
throws RepositoryException
{
- Cursor<StoredLayout> cursor =
- repo.storageFor(StoredLayout.class)
- .query("storableTypeName = ?").with(storableTypeName)
- .orderBy("-generation")
- .fetchSlice(0, 1L);
-
- try {
- // Must always return a result. Otherwise, no conflict existed in
- // the first place, indicating a bug.
- return cursor.next().getGeneration() + 1;
- } finally {
- cursor.close();
- }
-
- // TODO: also choose from highest equivalence
+ return LayoutFactory.nextGeneration(repo, storableTypeName);
}
- private Cursor<StoredLayout> findLayouts(Repository repo,
- String storableTypeName, int generation)
+ static Cursor<StoredLayout> findLayouts(Repository repo,
+ String storableTypeName, int generation)
throws RepositoryException
{
- // Query without using the index, in case it's inconsistent.
- return FilteredCursor.applyFilter
- (repo.storageFor(StoredLayout.class).query().fetch(),
- StoredLayout.class, "storableTypeName = ? & generation = ?",
- storableTypeName, generation);
+ return Layout.findLayouts(repo, storableTypeName, generation);
}
}