Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug fix #432

Open
wants to merge 2 commits into
base: snappy/master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,7 @@
import com.gemstone.gemfire.cache.ConflictException;
import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.cache.AbstractRegionEntry;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.cache.ObjectEqualsHashingStrategy;
import com.gemstone.gemfire.internal.cache.OffHeapRegionEntry;
import com.gemstone.gemfire.internal.cache.TXEntryState;
import com.gemstone.gemfire.internal.cache.TXId;
import com.gemstone.gemfire.internal.cache.TXStateInterface;
import com.gemstone.gemfire.internal.cache.*;
import com.gemstone.gemfire.internal.cache.locks.ExclusiveSharedSynchronizer;
import com.gemstone.gemfire.internal.cache.locks.LockMode;
import com.gemstone.gemfire.internal.cache.locks.LockingPolicy;
Expand Down Expand Up @@ -408,11 +402,23 @@ public Object updateValue(Object key, Object oldValue, RowLocation value,
return null;
}
else if ((oldValueClass = oldValue.getClass()) == RowLocation[].class) {
return insertToRowLocationArray(container, key, value,
(RowLocation[])oldValue, this.isPutDML);
RowLocation[] oldArr = (RowLocation[]) oldValue;
if (oldArr.length == 1 ) {
return insertToRowLocation(container, key, value,
oldArr[0], this.isPutDML);
} else {
return insertToRowLocationArray(container, key, value,
(RowLocation[])oldValue, this.isPutDML);
}
}
else if (oldValueClass == ConcurrentTHashSet.class) {
return insertToHashSet(container, key, value, oldValue, this.isPutDML);
ConcurrentTHashSet<Object> x = (ConcurrentTHashSet<Object>) oldValue;
if (x.size() == 1) {
return insertToRowLocation(container, key, value,
(RowLocation)x.iterator().next(), this.isPutDML);
} else {
return insertToHashSet(container, key, value, oldValue, this.isPutDML);
}
}
else if (RowLocation.class.isAssignableFrom(oldValueClass)) {
return insertToRowLocation(container, key, value,
Expand Down Expand Up @@ -492,6 +498,15 @@ private static Object insertToRowLocation(GemFireContainer container,
container.getQualifiedTableName(), oldValue, insertedValue));
}

if (oldValue instanceof WrapperRowLocationForTxn && insertedValue instanceof WrapperRowLocationForTxn
&& oldValue.equals(insertedValue)) {
/*WrapperRowLocationForTxn e1 = (WrapperRowLocationForTxn) oldValue;
WrapperRowLocationForTxn e2 = (WrapperRowLocationForTxn) insertedValue;
if (e1.getTXId().equals(e2.getTXId()) && e1.getRegionEntry() == e2.getRegionEntry()) {
return insertedValue;
} */
return insertedValue;
}
RowLocation[] newValues = new RowLocation[2];
newValues[0] = oldValue;
newValues[1] = insertedValue;
Expand All @@ -514,6 +529,7 @@ private static Object insertToRowLocationArray(
numExistingValues + 1, 0.60f,
ObjectEqualsHashingStrategy.getInstance(), container
.getBaseContainer().getRegion().getRegionPerfStats());
boolean skipIfSameTxEntry = false;
for (int i = 0; i < numExistingValues; i++) {
// should not happen when a duplicate entry from both GII and create
// will be converted to an update by GFE and handled properly by
Expand All @@ -528,10 +544,25 @@ private static Object insertToRowLocationArray(
GemFireXDUtils.newDuplicateEntryViolation(
container.getQualifiedTableName(), existingValues[i],
insertedValue));
} else {
skipIfSameTxEntry = insertedValue instanceof WrapperRowLocationForTxn &&
existingValues[i] instanceof WrapperRowLocationForTxn &&
insertedValue.equals(existingValues[i]);
/*
if (insertedValue instanceof WrapperRowLocationForTxn) {
if (existingValues[i] instanceof WrapperRowLocationForTxn) {
skipIfSameTxEntry = ((WrapperRowLocationForTxn)existingValues[i]).getTXId().equals(
((WrapperRowLocationForTxn)insertedValue).getTXId()) &&
((WrapperRowLocationForTxn)existingValues[i]).getRegionEntry() ==
((WrapperRowLocationForTxn)insertedValue).getRegionEntry();
}
} */
}
set.add(existingValues[i]);
}
set.add(insertedValue);
if (!skipIfSameTxEntry) {
set.add(insertedValue);
}
return set;
}
else {
Expand All @@ -550,6 +581,22 @@ private static Object insertToRowLocationArray(
GemFireXDUtils.newDuplicateEntryViolation(
container.getQualifiedTableName(), existingValues[i],
insertedValue));
} else {
boolean isTxSame = insertedValue instanceof WrapperRowLocationForTxn &&
existingValues[i] instanceof WrapperRowLocationForTxn
&& insertedValue.equals(existingValues[i]);

/*if (insertedValue instanceof WrapperRowLocationForTxn ) {
if (existingValues[i] instanceof WrapperRowLocationForTxn) {
isTxSame = ((WrapperRowLocationForTxn)existingValues[i]).getTXId().equals(
((WrapperRowLocationForTxn)insertedValue).getTXId()) &&
((WrapperRowLocationForTxn)existingValues[i]).getRegionEntry() ==
((WrapperRowLocationForTxn)insertedValue).getRegionEntry();
}
} */
if (isTxSame) {
return existingValues;
}
}
newValues[i] = existingValues[i];
}
Expand All @@ -570,19 +617,24 @@ private static Object insertToHashSet(GemFireContainer container, Object key,
final ConcurrentTHashSet<Object> set =
(ConcurrentTHashSet<Object>)oldValue;


Object oldRowLocObj;
if ((oldRowLocObj = set.addKey(insertedValue)) == null || isPutDML) {
return set;
}
assert oldRowLocObj.equals(insertedValue);
// should not happen when a duplicate entry from both GII and create
// will be converted to an update by GFE and handled properly by
// GfxdIndexManager#onEvent();
// can happen in case update is fired on index column updating to the
// old value itself
throw new IndexMaintenanceException(
GemFireXDUtils.newDuplicateEntryViolation(
container.getQualifiedTableName(), oldRowLocObj, insertedValue));
if (!(oldRowLocObj instanceof WrapperRowLocationForTxn && insertedValue instanceof WrapperRowLocationForTxn)) {
// should not happen when a duplicate entry from both GII and create
// will be converted to an update by GFE and handled properly by
// GfxdIndexManager#onEvent();
// can happen in case update is fired on index column updating to the
// old value itself
throw new IndexMaintenanceException(
GemFireXDUtils.newDuplicateEntryViolation(
container.getQualifiedTableName(), oldRowLocObj, insertedValue));
} else {
return set;
}
}

static final class ReplaceValue extends UpdateReplacementValue {
Expand All @@ -603,10 +655,19 @@ public Object replaceValue(Object key, Object oldValue,
}
else if ((mapValueClass = existingValue.getClass()) ==
RowLocation[].class) {
return replaceRowLocationArray(container, key, oldValue,
(RowLocation)newValue, (RowLocation[])existingValue, this.isPutDML);
RowLocation[] arr = (RowLocation[])existingValue;
if (arr.length == 1) {
return newValue;
} else {
return replaceRowLocationArray(container, key, oldValue,
(RowLocation)newValue, (RowLocation[])existingValue, this.isPutDML);
}
}
else if (mapValueClass == ConcurrentTHashSet.class) {
ConcurrentTHashSet<Object> x = (ConcurrentTHashSet<Object>)existingValue;
if (x.size() == 1) {
return newValue;
}
return replaceInHashSet(container, key, oldValue,
newValue, existingValue);
}
Expand Down Expand Up @@ -649,16 +710,45 @@ private static RowLocation[] replaceRowLocationArray(
// GfxdIndexManager#onEvent();
// can happen in case update is fired on index column updating to the
// old value itself
if (insertedValue != existingValue) {
if (oldValue != existingValue) {
try {
newValues[++index] = existingValue;
} catch (ArrayIndexOutOfBoundsException ae) {
// throw back a proper exception for the case when value to be
// replaced is not found
throw new IndexMaintenanceException(
GemFireXDUtils.newOldValueNotFoundException(key, oldValue,
existingValues, container));

/*
boolean isTxSame = false;
if (insertedValue instanceof WrapperRowLocationForTxn ) {
/* if (existingValue instanceof RegionEntry) {
isTxSame = ((WrapperRowLocationForTxn)insertedValue).getRegionEntry() == existingValue;
} else*/ /* if (existingValue instanceof WrapperRowLocationForTxn) {
isTxSame = ((WrapperRowLocationForTxn)existingValue).getTXId().equals(
((WrapperRowLocationForTxn)insertedValue).getTXId()) &&
((WrapperRowLocationForTxn)existingValue).getRegionEntry() ==
((WrapperRowLocationForTxn)insertedValue).getRegionEntry();
}
} */
boolean isTxSame = insertedValue instanceof WrapperRowLocationForTxn
&& existingValue instanceof WrapperRowLocationForTxn &&
insertedValue.equals(existingValue);




if (insertedValue != existingValue ) {
if (isTxSame) {
//do not add this value as we wil add inserted value to 0 position
foundOldValue = true;
} else if (oldValue != existingValue) {
if (oldValue instanceof TXEntryState &&
((TXEntryState)oldValue).getOriginalValue() == existingValue) {
//do not add this value as we wil add inserted value to 0 position
foundOldValue = true;
} else {
try {
newValues[++index] = existingValue;
} catch (ArrayIndexOutOfBoundsException ae) {
// throw back a proper exception for the case when value to be
// replaced is not found
throw new IndexMaintenanceException(
GemFireXDUtils.newOldValueNotFoundException(key, oldValue,
existingValues, container));
}
}
}
else if (!foundOldValue) {
Expand Down Expand Up @@ -698,10 +788,16 @@ private static ConcurrentTHashSet<Object> replaceInHashSet(
final ConcurrentTHashSet<Object> set =
(ConcurrentTHashSet<Object>)existingValue;

// TODO: Asif : How to conflate two WrapperRowLocationTxn? May be that situation does not arise?
if (set.replace(oldValue, insertedValue)) {
return set;
}
else {
if (oldValue instanceof TXEntryState ) {
if (set.replace(((TXEntryState)oldValue).getOriginalValue(), insertedValue)) {
return set;
}
}
// throw back a proper exception for the case when value to be
// replaced is not found
throw new IndexMaintenanceException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,29 @@ public WrapperRowLocationForTxn(GfxdTXEntryState rowLocationToBeWrapped,
this.createdForUpdateOperation = forUpdateOp;
}


@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj instanceof WrapperRowLocationForTxn && this.actualRowLocation != null
&& ((WrapperRowLocationForTxn)obj).actualRowLocation != null) {
WrapperRowLocationForTxn that = (WrapperRowLocationForTxn) obj;
return this.actualRowLocation.equals(that.actualRowLocation);
} else {
return false;
}
}

@Override
public int hashCode() {
int h = 17;
// h = h * 37 + this.indexContainer.hashCode();
// h = h * 37 + this.indexKey.hashCode();
h = h * 37 + (this.actualRowLocation != null ? this.actualRowLocation.hashCode() : super.hashCode());
return h;
}

public boolean wasCreatedForUpdateOp() {
return this.createdForUpdateOperation;
}
Expand Down