diff options
Diffstat (limited to 'src/main/java/com')
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);
      }
  }
 | 
