summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2011-06-30 23:38:06 +0000
committerBrian S. O'Neill <bronee@gmail.com>2011-06-30 23:38:06 +0000
commita05e568387db065a709530b72744174dbe9b9802 (patch)
tree86d4e252d099a2631e76df9c2e04be6a96794b74 /src/main
parent8b4cc8d6136cb2da66f2b660f803167a259fdaed (diff)
Skip corrupt master entries, allow existing index entry.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java140
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java49
2 files changed, 78 insertions, 111 deletions
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
index adafb34..bce6975 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
@@ -22,6 +22,7 @@ import java.util.NoSuchElementException;
import org.apache.commons.logging.LogFactory;
+import com.amazon.carbonado.CorruptEncodingException;
import com.amazon.carbonado.Cursor;
import com.amazon.carbonado.FetchException;
import com.amazon.carbonado.PersistException;
@@ -72,84 +73,91 @@ class IndexedCursor<S extends Storable> extends AbstractCursor<S> {
S master = mStorage.mMasterStorage.prepare();
mAccessor.copyToMasterPrimaryKey(indexEntry, master);
- if (!master.tryLoad()) {
- LogFactory.getLog(getClass()).warn
- ("Master is missing for index entry: " + indexEntry);
- } else {
- if (mAccessor.isConsistent(indexEntry, master)) {
+ try {
+ if (!master.tryLoad()) {
+ LogFactory.getLog(getClass()).warn
+ ("Master is missing for index entry: " + indexEntry);
+ continue;
+ }
+ } catch (CorruptEncodingException e) {
+ LogFactory.getLog(getClass()).error
+ ("Master record for index entry is corrupt: " + indexEntry, e);
+ continue;
+ }
+
+ if (mAccessor.isConsistent(indexEntry, master)) {
+ mNext = master;
+ return true;
+ }
+
+ // This index entry is stale. Repair is needed.
+
+ // Insert a correct index entry, just to be sure.
+ try {
+ final IndexedRepository repo = mStorage.mRepository;
+ final Storage<?> indexEntryStorage =
+ repo.getIndexEntryStorageFor(mAccessor.getReferenceClass());
+ Storable newIndexEntry = indexEntryStorage.prepare();
+ mAccessor.copyFromMaster(newIndexEntry, master);
+
+ if (newIndexEntry.tryLoad()) {
+ // Good, the correct index entry exists. We'll see
+ // the master record eventually, so skip.
+ } else {
+ // We have no choice but to return the master, at
+ // the risk of seeing it multiple times. This is
+ // better than seeing it never.
+ LogFactory.getLog(getClass()).warn
+ ("Inconsistent index entry: " + indexEntry + ", " + master);
mNext = master;
- return true;
}
- // This index entry is stale. Repair is needed.
-
- // Insert a correct index entry, just to be sure.
- try {
- final IndexedRepository repo = mStorage.mRepository;
- final Storage<?> indexEntryStorage =
- repo.getIndexEntryStorageFor(mAccessor.getReferenceClass());
- Storable newIndexEntry = indexEntryStorage.prepare();
- mAccessor.copyFromMaster(newIndexEntry, master);
-
- if (newIndexEntry.tryLoad()) {
- // Good, the correct index entry exists. We'll see
- // the master record eventually, so skip.
- } else {
- // We have no choice but to return the master, at
- // the risk of seeing it multiple times. This is
- // better than seeing it never.
- LogFactory.getLog(getClass()).warn
- ("Inconsistent index entry: " + indexEntry + ", " + master);
- mNext = master;
- }
+ // Repair the stale index entry.
+ RepairExecutor.execute(new Runnable() {
+ public void run() {
+ Transaction txn = repo.enterTransaction();
+ try {
+ // Reload master and verify inconsistency.
+ S master = mStorage.mMasterStorage.prepare();
+ mAccessor.copyToMasterPrimaryKey(indexEntry, master);
+
+ if (master.tryLoad()) {
+ Storable newIndexEntry = indexEntryStorage.prepare();
+ mAccessor.copyFromMaster(newIndexEntry, master);
- // Repair the stale index entry.
- RepairExecutor.execute(new Runnable() {
- public void run() {
- Transaction txn = repo.enterTransaction();
+ newIndexEntry.tryInsert();
+
+ indexEntry.tryDelete();
+ txn.commit();
+ }
+ } catch (FetchException fe) {
+ LogFactory.getLog(IndexedCursor.class).warn
+ ("Unable to check if repair required for " +
+ "inconsistent index entry " +
+ indexEntry, fe);
+ } catch (PersistException pe) {
+ LogFactory.getLog(IndexedCursor.class).error
+ ("Unable to repair inconsistent index entry " +
+ indexEntry, pe);
+ } finally {
try {
- // Reload master and verify inconsistency.
- S master = mStorage.mMasterStorage.prepare();
- mAccessor.copyToMasterPrimaryKey(indexEntry, master);
-
- if (master.tryLoad()) {
- Storable newIndexEntry = indexEntryStorage.prepare();
- mAccessor.copyFromMaster(newIndexEntry, master);
-
- newIndexEntry.tryInsert();
-
- indexEntry.tryDelete();
- txn.commit();
- }
- } catch (FetchException fe) {
- LogFactory.getLog(IndexedCursor.class).warn
- ("Unable to check if repair required for " +
- "inconsistent index entry " +
- indexEntry, fe);
+ txn.exit();
} catch (PersistException pe) {
LogFactory.getLog(IndexedCursor.class).error
("Unable to repair inconsistent index entry " +
indexEntry, pe);
- } finally {
- try {
- txn.exit();
- } catch (PersistException pe) {
- LogFactory.getLog(IndexedCursor.class).error
- ("Unable to repair inconsistent index entry " +
- indexEntry, pe);
- }
}
}
- });
- } catch (Exception re) {
- LogFactory.getLog(getClass()).error
- ("Unable to inspect inconsistent index entry " +
- indexEntry, re);
- }
+ }
+ });
+ } catch (Exception re) {
+ LogFactory.getLog(getClass()).error
+ ("Unable to inspect inconsistent index entry " +
+ indexEntry, re);
+ }
- if (mNext != null) {
- return true;
- }
+ if (mNext != null) {
+ return true;
}
}
} catch (NoSuchElementException e) {
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
index 4e99a06..7a597b6 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
@@ -660,61 +660,20 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
return true;
}
- // FIXME: This code effectively does nothing and always returns false.
-
// If index entry already exists, then index might be corrupt.
try {
Storable freshEntry = mIndexEntryStorage.prepare();
mAccessor.copyFromMaster(freshEntry, userStorable);
+ freshEntry.load();
indexEntry.copyVersionProperty(freshEntry);
if (freshEntry.equals(indexEntry)) {
- // Existing entry is exactly what we expect. Return false if
- // alternate key constraint, since this is user error.
- return !isUnique();
+ // Existing entry is fine.
+ return true;
}
} catch (FetchException e) {
throw e.toPersistException();
}
- // Run the repair outside a transaction.
-
- RepairExecutor.execute(new Runnable() {
- public void run() {
- try {
- // Blow it away entry and re-insert. Don't simply update
- // the entry, since record version number may prevent
- // update.
-
- // Since we may be running outside transaction now, user
- // storable may have changed. Reload to get latest data.
-
- S freshUserStorable = (S) userStorable.copy();
- if (!freshUserStorable.tryLoad()) {
- // Gone now, nothing we can do. Assume index entry
- // was properly deleted.
- return;
- }
-
- Storable freshEntry = mIndexEntryStorage.prepare();
- mAccessor.copyFromMaster(freshEntry, freshUserStorable);
-
- // Blow it away entry and re-insert. Don't simply update
- // the entry, since record version number may prevent
- // update.
- freshEntry.tryDelete();
- freshEntry.tryInsert();
- } catch (FetchException fe) {
- LogFactory.getLog(IndexedStorage.class).warn
- ("Unable to check if repair is required: " +
- userStorable.toStringKeyOnly(), fe);
- } catch (PersistException pe) {
- LogFactory.getLog(IndexedStorage.class).error
- ("Unable to repair index entry for " +
- userStorable.toStringKeyOnly(), pe);
- }
- }
- });
-
- return true;
+ return false;
}
}