private Map.Entry<OIdentifiable, Integer> nextChangedNotRemovedSBTreeEntry( Iterator<Map.Entry<OIdentifiable, Integer>> iterator) { while (iterator.hasNext()) { final Map.Entry<OIdentifiable, Integer> entry = iterator.next(); final Change change = changes.get(entry.getKey()); if (change == null) return entry; final int newValue = change.applyTo(entry.getValue()); if (newValue > 0) return new Map.Entry<OIdentifiable, Integer>() { @Override public OIdentifiable getKey() { return entry.getKey(); } @Override public Integer getValue() { return newValue; } @Override public Integer setValue(Integer value) { throw new UnsupportedOperationException(); } }; } return null; }
@Override public boolean convertRecords2Links() { final Map<OIdentifiable, Change> newChangedValues = new HashMap<OIdentifiable, Change>(); for (Map.Entry<OIdentifiable, Change> entry : changes.entrySet()) { OIdentifiable identifiable = entry.getKey(); if (identifiable instanceof ORecord) { ORID identity = identifiable.getIdentity(); ORecord record = (ORecord) identifiable; identity = record.getIdentity(); newChangedValues.put(identity, entry.getValue()); } else newChangedValues.put(entry.getKey().getIdentity(), entry.getValue()); } for (Map.Entry<OIdentifiable, Change> entry : newChangedValues.entrySet()) { if (entry.getKey() instanceof ORecord) { ORecord record = (ORecord) entry.getKey(); newChangedValues.put(record, entry.getValue()); } else return false; } newEntries.clear(); changes.clear(); changes.putAll(newChangedValues); return true; }
private Map.Entry<OIdentifiable, Change> nextChangedNotRemovedEntry( Iterator<Map.Entry<OIdentifiable, Change>> iterator) { Map.Entry<OIdentifiable, Change> entry; while (iterator.hasNext()) { entry = iterator.next(); // TODO workaround if (entry.getValue().applyTo(0) > 0) return entry; } return null; }
@Override public void convertLinks2Records() { TreeMap<OIdentifiable, Change> newChanges = new TreeMap<OIdentifiable, Change>(); for (Map.Entry<OIdentifiable, Change> entry : changes.entrySet()) { final OIdentifiable key = entry.getKey().getRecord(); if (key != null && this.owner != null) { ORecordInternal.unTrack(this.owner, entry.getKey()); ORecordInternal.track(this.owner, key); } newChanges.put((key == null) ? entry.getKey() : key, entry.getValue()); } changes.clear(); changes.putAll(newChanges); }
public <K> void serializeChanges( Map<K, Change> changes, OBinarySerializer<K> keySerializer, byte[] stream, int offset) { OIntegerSerializer.INSTANCE.serializeLiteral(changes.size(), stream, offset); offset += OIntegerSerializer.INT_SIZE; for (Map.Entry<K, Change> entry : changes.entrySet()) { K key = entry.getKey(); if (((OIdentifiable) key).getIdentity().isTemporary()) key = ((OIdentifiable) key).getRecord(); keySerializer.serialize(key, stream, offset); offset += keySerializer.getObjectSize(key); offset += entry.getValue().serialize(stream, offset); } }
@Override public void remove() { if (currentRemoved) throw new IllegalStateException("Current element has already been removed"); if (currentValue == null) throw new IllegalStateException("Next method was not called for given iterator"); if (removeFromNewEntries(currentValue)) { if (size >= 0) size--; } else { Change counter = changedValues.get(currentValue); if (counter != null) { counter.decrement(); if (size >= 0) if (counter.isUndefined()) size = -1; else size--; } else { if (nextChange != null) { changedValues.put(currentValue, new DiffChange(-1)); changedValuesIterator = changedValues.tailMap(nextChange.getKey(), false).entrySet().iterator(); } else { changedValues.put(currentValue, new DiffChange(-1)); } size = -1; } } if (OSBTreeRidBag.this.owner != null) ORecordInternal.unTrack(OSBTreeRidBag.this.owner, currentValue); if (updateOwner) fireCollectionChangedEvent( new OMultiValueChangeEvent<OIdentifiable, OIdentifiable>( OMultiValueChangeEvent.OChangeType.REMOVE, currentValue, null, currentValue, false)); currentRemoved = true; }
public void mergeChanges(OSBTreeRidBag treeRidBag) { for (Map.Entry<OIdentifiable, OModifiableInteger> entry : treeRidBag.newEntries.entrySet()) { mergeDiffEntry(entry.getKey(), entry.getValue().getValue()); } for (Map.Entry<OIdentifiable, Change> entry : treeRidBag.changes.entrySet()) { final OIdentifiable rec = entry.getKey(); final Change change = entry.getValue(); final int diff; if (change instanceof DiffChange) diff = ((DiffChange) change).delta; else if (change instanceof AbsoluteChange) diff = ((AbsoluteChange) change).value - getAbsoluteValue(rec).value; else throw new IllegalArgumentException("change type is not supported"); mergeDiffEntry(rec, diff); } }
@Override public int serialize(byte[] stream, int offset, UUID ownerUuid) { for (Map.Entry<OIdentifiable, OModifiableInteger> entry : newEntries.entrySet()) { OIdentifiable identifiable = entry.getKey(); assert identifiable instanceof ORecord; Change c = changes.get(identifiable); final int delta = entry.getValue().intValue(); if (c == null) changes.put(identifiable, new DiffChange(delta)); else c.applyDiff(delta); } newEntries.clear(); final ORecordSerializationContext context; boolean remoteMode = ODatabaseRecordThreadLocal.INSTANCE.get().getStorage() instanceof OStorageProxy; if (remoteMode) { context = null; } else context = ORecordSerializationContext.getContext(); // make sure that we really save underlying record. if (collectionPointer == null) { if (context != null) { final int clusterId = getHighLevelDocClusterId(); assert clusterId > -1; collectionPointer = ODatabaseRecordThreadLocal.INSTANCE .get() .getSbTreeCollectionManager() .createSBTree(clusterId, ownerUuid); } } OBonsaiCollectionPointer collectionPointer; if (this.collectionPointer != null) collectionPointer = this.collectionPointer; else { collectionPointer = OBonsaiCollectionPointer.INVALID; } OLongSerializer.INSTANCE.serializeLiteral(collectionPointer.getFileId(), stream, offset); offset += OLongSerializer.LONG_SIZE; OBonsaiBucketPointer rootPointer = collectionPointer.getRootPointer(); OLongSerializer.INSTANCE.serializeLiteral(rootPointer.getPageIndex(), stream, offset); offset += OLongSerializer.LONG_SIZE; OIntegerSerializer.INSTANCE.serializeLiteral(rootPointer.getPageOffset(), stream, offset); offset += OIntegerSerializer.INT_SIZE; // Keep this section for binary compatibility with versions older then 1.7.5 OIntegerSerializer.INSTANCE.serializeLiteral(size, stream, offset); offset += OIntegerSerializer.INT_SIZE; if (context == null) { ChangeSerializationHelper.INSTANCE.serializeChanges( changes, OLinkSerializer.INSTANCE, stream, offset); } else { context.push(new ORidBagUpdateSerializationOperation(changes, collectionPointer)); // 0-length serialized list of changes OIntegerSerializer.INSTANCE.serializeLiteral(0, stream, offset); offset += OIntegerSerializer.INT_SIZE; } return offset; }
@Override public OIdentifiable next() { currentRemoved = false; if (currentCounter < currentFinalCounter) { currentCounter++; return currentValue; } if (newEntryIterator.hasNext()) { Map.Entry<OIdentifiable, OModifiableInteger> entry = newEntryIterator.next(); currentValue = entry.getKey(); currentFinalCounter = entry.getValue().intValue(); currentCounter = 1; return currentValue; } if (nextChange != null && nextSBTreeEntry != null) { if (nextChange.getKey().compareTo(nextSBTreeEntry.getKey()) < 0) { currentValue = nextChange.getKey(); currentFinalCounter = nextChange.getValue().applyTo(0); currentCounter = 1; nextChange = nextChangedNotRemovedEntry(changedValuesIterator); } else { currentValue = nextSBTreeEntry.getKey(); currentFinalCounter = nextSBTreeEntry.getValue(); currentCounter = 1; nextSBTreeEntry = nextChangedNotRemovedSBTreeEntry(sbTreeIterator); if (nextChange != null && nextChange.getKey().equals(currentValue)) nextChange = nextChangedNotRemovedEntry(changedValuesIterator); } } else if (nextChange != null) { currentValue = nextChange.getKey(); currentFinalCounter = nextChange.getValue().applyTo(0); currentCounter = 1; nextChange = nextChangedNotRemovedEntry(changedValuesIterator); } else if (nextSBTreeEntry != null) { currentValue = nextSBTreeEntry.getKey(); currentFinalCounter = nextSBTreeEntry.getValue(); currentCounter = 1; nextSBTreeEntry = nextChangedNotRemovedSBTreeEntry(sbTreeIterator); } else throw new NoSuchElementException(); if (convertToRecord) return currentValue.getRecord(); return currentValue; }