From 79d893ac1bad62d94750b26980f45928330870ed Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Tue, 6 Nov 2012 00:19:54 +0000 Subject: Layout metadata sync fixes. --- .../java/com/amazon/carbonado/layout/Layout.java | 50 ++++++++++++++------- .../com/amazon/carbonado/layout/LayoutFactory.java | 51 +++++++++++++++++++--- .../com/amazon/carbonado/layout/LayoutSync.java | 27 +++--------- 3 files changed, 84 insertions(+), 44 deletions(-) (limited to 'src') 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 c = - FilteredCursor.applyFilter(mLayoutFactory.mLayoutStorage.query().fetch(), - StoredLayout.class, filter, - getStorableTypeName(), generation); - try { - if (c.hasNext()) { - return c.next(); + Cursor 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 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 cursor = mLayoutStorage - .query("storableTypeName = ?").with(typeName).orderBy("-generation").fetch(); + static int nextGeneration(Repository repo, String typeName) throws FetchException { + int highestGen = -1; + { + Cursor 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 es; + try { + es = repo.storageFor(StoredLayoutEquivalence.class); + } catch (RepositoryException e) { + throw e.toFetchException(); + } + + Cursor 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 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 findLayouts(Repository repo, - String storableTypeName, int generation) + static Cursor 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); } } -- cgit v1.2.3