[ONOS-6426] Handle tombstones in null comparisons in AsyncConsistentMap state machine

Change-Id: I1a96bb4b7a23703ffcb0daa1376a26f994f10337
This commit is contained in:
Jordan Halterman 2017-05-09 12:15:22 -07:00
parent 5d73df799c
commit e5ce1455ee

View File

@ -295,8 +295,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements Se
if (updateStatus != MapEntryUpdateResult.Status.OK) { if (updateStatus != MapEntryUpdateResult.Status.OK) {
commit.close(); commit.close();
return new MapEntryUpdateResult<>(updateStatus, "", key, return new MapEntryUpdateResult<>(updateStatus, "", key, oldMapValue, oldMapValue);
oldMapValue, oldMapValue);
} }
byte[] newValue = commit.operation().value(); byte[] newValue = commit.operation().value();
@ -329,8 +328,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements Se
} }
publish(Lists.newArrayList(new MapEvent<>("", key, newMapValue, oldMapValue))); publish(Lists.newArrayList(new MapEvent<>("", key, newMapValue, oldMapValue)));
return new MapEntryUpdateResult<>(updateStatus, "", key, oldMapValue, return new MapEntryUpdateResult<>(updateStatus, "", key, oldMapValue, newMapValue);
newMapValue);
} catch (Exception e) { } catch (Exception e) {
log.error("State machine operation failed", e); log.error("State machine operation failed", e);
throw Throwables.propagate(e); throw Throwables.propagate(e);
@ -678,16 +676,15 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements Se
*/ */
private MapEntryUpdateResult.Status validate(UpdateAndGet update) { private MapEntryUpdateResult.Status validate(UpdateAndGet update) {
MapEntryValue existingValue = mapEntries.get(update.key()); MapEntryValue existingValue = mapEntries.get(update.key());
if (existingValue == null && update.value() == null) { boolean isEmpty = existingValue == null || existingValue.type() == MapEntryValue.Type.TOMBSTONE;
if (isEmpty && update.value() == null) {
return MapEntryUpdateResult.Status.NOOP; return MapEntryUpdateResult.Status.NOOP;
} }
if (preparedKeys.contains(update.key())) { if (preparedKeys.contains(update.key())) {
return MapEntryUpdateResult.Status.WRITE_LOCK; return MapEntryUpdateResult.Status.WRITE_LOCK;
} }
byte[] existingRawValue = existingValue == null ? null : existingValue byte[] existingRawValue = isEmpty ? null : existingValue.value();
.value(); Long existingVersion = isEmpty ? null : existingValue.version();
Long existingVersion = existingValue == null ? null : existingValue
.version();
return update.valueMatch().matches(existingRawValue) return update.valueMatch().matches(existingRawValue)
&& update.versionMatch().matches(existingVersion) ? MapEntryUpdateResult.Status.OK && update.versionMatch().matches(existingVersion) ? MapEntryUpdateResult.Status.OK
: MapEntryUpdateResult.Status.PRECONDITION_FAILED; : MapEntryUpdateResult.Status.PRECONDITION_FAILED;