private void commitArrayIndex(Marker from, Marker to, long originalMarker) { while (true) { long oldVal = state.get(), rc = from.getRc(oldVal); long newVal = from.setRc(oldVal, rc - 1); // Decrease refcount. assert rc > 0; if (rc == 1) { // We are the last of the concurrent operations to finish. Commit. long marker = from.getMarker(oldVal), delta = from.getDelta(oldVal), otherMarker = to.getMarker(oldVal), otherDelta = to.getDelta(oldVal); assert rc <= delta; // Move marker according to delta, change delta to 0. long newMarker = applyDeltaToMarker(marker, otherMarker, delta); newVal = from.setDelta(from.setMarker(newVal, newMarker), 0); if (otherMarker == NO_MARKER) { // The other list doesn't exist, create it at the first index of our op. assert otherDelta == 0; newVal = to.setMarker(newVal, originalMarker); } else if (otherDelta > 0 && otherDelta != NO_DELTA && applyDeltaToMarker(otherMarker, marker, otherDelta) == NO_MARKER) { // The other list will be exhausted when it commits. Create new one pending that commit. newVal = to.setDelta(to.setMarker(newVal, originalMarker), NO_DELTA); } } if (setState(oldVal, newVal)) return; } }
private void commitArrayIndex(Marker from, Marker to, long originalMarker) { while (true) { long oldVal = state.get(), rc = from.getRc(oldVal); long newVal = from.setRc(oldVal, rc - 1); // Decrease refcount. assert rc > 0; if (rc == 1) { // We are the last of the concurrent operations to finish. Commit. long marker = from.getMarker(oldVal), delta = from.getDelta(oldVal), otherMarker = to.getMarker(oldVal), otherDelta = to.getDelta(oldVal); assert rc <= delta; // Move marker according to delta, change delta to 0. long newMarker = applyDeltaToMarker(marker, otherMarker, delta); newVal = from.setDelta(from.setMarker(newVal, newMarker), 0); if (otherMarker == NO_MARKER) { // The other list doesn't exist, create it at the first index of our op. assert otherDelta == 0; newVal = to.setMarker(newVal, originalMarker); } else if (otherDelta > 0 && otherDelta != NO_DELTA && applyDeltaToMarker(otherMarker, marker, otherDelta) == NO_MARKER) { // The other list will be exhausted when it commits. Create new one pending that commit. newVal = to.setDelta(to.setMarker(newVal, originalMarker), NO_DELTA); } } if (setState(oldVal, newVal)) return; } }