@Override public void setOwner(ORecord owner) { if (owner != null && this.owner != null && !this.owner.equals(owner)) { throw new IllegalStateException( "This data structure is owned by document " + owner + " if you want to use it in other document create new rid bag instance and copy content of current one."); } if (this.owner != null) { for (OIdentifiable entry : newEntries.keySet()) { ORecordInternal.unTrack(this.owner, entry); } for (OIdentifiable entry : changes.keySet()) { ORecordInternal.unTrack(this.owner, entry); } } this.owner = owner; if (this.owner != null) { for (OIdentifiable entry : newEntries.keySet()) { ORecordInternal.track(this.owner, entry); } for (OIdentifiable entry : changes.keySet()) { ORecordInternal.track(this.owner, entry); } } }
public void add(final OIdentifiable identifiable) { if (identifiable == null) throw new NullPointerException("Impossible to add a null identifiable in a ridbag"); if (identifiable.getIdentity().isValid()) { Change counter = changes.get(identifiable); if (counter == null) changes.put(identifiable, new DiffChange(1)); else { if (counter.isUndefined()) { counter = getAbsoluteValue(identifiable); changes.put(identifiable, counter); } counter.increment(); } } else { final OModifiableInteger counter = newEntries.get(identifiable); if (counter == null) newEntries.put(identifiable, new OModifiableInteger(1)); else counter.increment(); } if (size >= 0) size++; if (this.owner != null) ORecordInternal.track(this.owner, identifiable); if (updateOwner) fireCollectionChangedEvent( new OMultiValueChangeEvent<OIdentifiable, OIdentifiable>( OMultiValueChangeEvent.OChangeType.ADD, identifiable, identifiable, null, false)); }
/** * Removes entry with given key from {@link #newEntries}. * * @param identifiable key to remove * @return true if entry have been removed */ private boolean removeFromNewEntries(final OIdentifiable identifiable) { OModifiableInteger counter = newEntries.get(identifiable); if (counter == null) return false; else { if (counter.getValue() == 1) newEntries.remove(identifiable); else counter.decrement(); return true; } }
@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; }
public void confirmDelete() { collectionPointer = null; changes.clear(); newEntries.clear(); size = 0; if (changeListeners != null) changeListeners.clear(); changeListeners = null; }
private RIDBagIterator( IdentityHashMap<OIdentifiable, OModifiableInteger> newEntries, NavigableMap<OIdentifiable, Change> changedValues, SBTreeMapEntryIterator sbTreeIterator, boolean convertToRecord) { newEntryIterator = newEntries.entrySet().iterator(); this.changedValues = changedValues; this.convertToRecord = convertToRecord; this.changedValuesIterator = changedValues.entrySet().iterator(); this.sbTreeIterator = sbTreeIterator; nextChange = nextChangedNotRemovedEntry(changedValuesIterator); if (sbTreeIterator != null) nextSBTreeEntry = nextChangedNotRemovedSBTreeEntry(sbTreeIterator); }
@Override public boolean contains(OIdentifiable identifiable) { if (newEntries.containsKey(identifiable)) return true; Change counter = changes.get(identifiable); if (counter != null) { AbsoluteChange absoluteValue = getAbsoluteValue(identifiable); if (counter.isUndefined()) { changes.put(identifiable, absoluteValue); } counter = absoluteValue; } else { counter = getAbsoluteValue(identifiable); } return counter.applyTo(0) > 0; }
/** * Recalculates real bag size. * * @return real size */ private int updateSize() { int size = 0; if (collectionPointer != null) { final OSBTreeBonsai<OIdentifiable, Integer> tree = loadTree(); try { size = tree.getRealBagSize(changes); } finally { releaseTree(); } } else { for (Change change : changes.values()) { size += change.applyTo(0); } } for (OModifiableInteger diff : newEntries.values()) { size += diff.getValue(); } this.size = size; return size; }
@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; }
private int getChangesSerializedSize() { Set<OIdentifiable> changedIds = new HashSet<OIdentifiable>(changes.keySet()); changedIds.addAll(newEntries.keySet()); return ChangeSerializationHelper.INSTANCE.getChangesSerializedSize(changedIds.size()); }