public virtual void StoreReplica(object obj) { IReplicationReference @ref = GetCachedReference(obj); if (@ref == null) { throw new Exception(); } Store(obj, @ref.Uuid(), @ref.Version()); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference unused, string unused2) { //System.out.println("referenceNewObject: " + obj + " UUID: " + counterpartReference.uuid()); IDrsUUID uuid = counterpartReference.Uuid(); long version = counterpartReference.Version(); if (GetObject(uuid) != null) { throw new Exception("Object exists already."); } IReplicationReference result = CreateReferenceFor(obj); Store(obj, uuid, version); return(result); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference referencingObjCounterPartRef, string fieldName) { IDrsUUID uuid = counterpartReference.Uuid(); if (uuid == null) { return(null); } byte[] signature = uuid.GetSignaturePart(); long longPart = uuid.GetLongPart(); long version = counterpartReference.Version(); Db4oDatabase db = _signatureMap.Produce(signature, 0); Db4oReplicationReferenceImpl @ref = new Db4oReplicationReferenceImpl(obj, db, longPart , version); AddReference(@ref); return(@ref); }
public virtual bool WasModifiedSinceLastReplication(IReplicationReference reference ) { long timestamp = reference.Version(); if (timestamp > _replicationRecord._version) { return(true); } long[] concurrentTimestamps = _replicationRecord.ConcurrentTimestamps(); if (concurrentTimestamps == null) { return(false); } for (int i = 0; i < concurrentTimestamps.Length; i++) { if (timestamp == concurrentTimestamps[i]) { return(true); } } return(false); }
private bool HandleMissingObjectInOther(object obj, IReplicationReference ownerRef , IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject , string fieldName) { bool isConflict = false; bool wasModified = owner.WasModifiedSinceLastReplication(ownerRef); if (wasModified) { isConflict = true; } if (_directionTo == other) { isConflict = true; } object prevailing = null; //by default, deletion prevails if (isConflict) { owner.Activate(obj); } _event.ResetAction(); _event.Conflict(isConflict); _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); long modificationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Version()); if (owner == _providerA) { _stateInA.SetAll(obj, false, wasModified, modificationDate); _stateInB.SetAll(null, false, false, ObjectStateImpl.Unknown); } else { //owner == _providerB _stateInA.SetAll(null, false, false, ObjectStateImpl.Unknown); _stateInB.SetAll(obj, false, wasModified, modificationDate); } _listener.OnReplicate(_event); if (isConflict && !_event._actionWasChosen) { ThrowReplicationConflictException(); } if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return(false); } if (_event._actionChosenState == _stateInA) { prevailing = _stateInA.GetObject(); } if (_event._actionChosenState == _stateInB) { prevailing = _stateInB.GetObject(); } } if (prevailing == null) { //Deletion has prevailed. if (_directionTo == other) { return(false); } ownerRef.MarkForDeleting(); return(!_event._actionShouldStopTraversal); } bool needsToBeActivated = !isConflict; //Already activated if there was a conflict. return(HandleNewObject(obj, ownerRef, owner, other, referencingObject, fieldName, needsToBeActivated, true)); }
private bool PrepareObjectToBeReplicated(object obj, object referencingObject, string fieldName) { //TODO Optimization: keep track of the peer we are traversing to avoid having to look in both. Logger4Support.LogIdentity(obj); _obj = obj; _referencingObject = referencingObject; _fieldName = fieldName; IReplicationReference refA = _providerA.ProduceReference(_obj, _referencingObject , _fieldName); IReplicationReference refB = _providerB.ProduceReference(_obj, _referencingObject , _fieldName); if (refA == null && refB == null) { throw new Exception(string.Empty + _obj.GetType() + " " + _obj + " must be stored in one of the databases being replicated." ); } //FIXME: Use db4o's standard for throwing exceptions. if (refA != null && refB != null) { throw new Exception(string.Empty + _obj.GetType() + " " + _obj + " cannot be referenced by both databases being replicated." ); } //FIXME: Use db4o's standard for throwing exceptions. IReplicationProviderInside owner = refA == null ? _providerB : _providerA; IReplicationReference ownerRef = refA == null ? refB : refA; IReplicationProviderInside other = Other(owner); IDrsUUID uuid = ownerRef.Uuid(); IReplicationReference otherRef = other.ProduceReferenceByUUID(uuid, _obj.GetType( )); if (refA == null) { refA = otherRef; } else { refB = otherRef; } //TODO for circular referenced object, otherRef should not be null in the subsequent pass. //But db4o always return null. A bug. check! if (otherRef == null) { //Object is only present in one ReplicationProvider. Missing in the other. Could have been deleted or never replicated. if (WasProcessed(uuid)) { IReplicationReference otherProcessedRef = other.ProduceReferenceByUUID(uuid, _obj .GetType()); if (otherProcessedRef != null) { ownerRef.SetCounterpart(otherProcessedRef.Object()); } return(false); } MarkAsProcessed(uuid); long creationTime = ownerRef.Uuid().GetLongPart(); if (creationTime > owner.TimeStamps().From()) { //if it was created after the last time two ReplicationProviders were replicated it has to be treated as new. if (_isReplicatingOnlyDeletions) { return(false); } return(HandleNewObject(_obj, ownerRef, owner, other, _referencingObject, _fieldName , true, false)); } else { // If it was created before the last time two ReplicationProviders were replicated it has to be treated as deleted. // No, not always, in a three-way replication setup it can also be new. return(HandleMissingObjectInOther(_obj, ownerRef, owner, other, _referencingObject , _fieldName)); } } if (_isReplicatingOnlyDeletions) { return(false); } ownerRef.SetCounterpart(otherRef.Object()); otherRef.SetCounterpart(ownerRef.Object()); if (WasProcessed(uuid)) { return(false); } //Has to be done AFTER the counterpart is set because object yet to be replicated might reference the current one, replicated previously. MarkAsProcessed(uuid); object objectA = refA.Object(); object objectB = refB.Object(); bool changedInA = _providerA.WasModifiedSinceLastReplication(refA); //System.out.println("changedInA = " + changedInA); bool changedInB = _providerB.WasModifiedSinceLastReplication(refB); //System.out.println("changedInB = " + changedInB); if (!changedInA && !changedInB) { return(false); } bool conflict = false; if (changedInA && changedInB) { conflict = true; } if (changedInA && _directionTo == _providerA) { conflict = true; } if (changedInB && _directionTo == _providerB) { conflict = true; } object prevailing = _obj; _providerA.Activate(objectA); _providerB.Activate(objectB); _event.ResetAction(); _event.Conflict(conflict); _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(uuid.GetLongPart()); _stateInA.SetAll(objectA, false, changedInA, TimeStampIdGenerator.IdToMilliseconds (ownerRef.Version())); _stateInB.SetAll(objectB, false, changedInB, TimeStampIdGenerator.IdToMilliseconds (otherRef.Version())); _listener.OnReplicate(_event); if (conflict) { if (!_event._actionWasChosen) { ThrowReplicationConflictException(); } if (_event._actionChosenState == null) { return(false); } if (_event._actionChosenState == _stateInA) { prevailing = objectA; } if (_event._actionChosenState == _stateInB) { prevailing = objectB; } } else { if (_event._actionWasChosen) { if (_event._actionChosenState == _stateInA) { prevailing = objectA; } if (_event._actionChosenState == _stateInB) { prevailing = objectB; } if (_event._actionChosenState == null) { return(false); } } else { if (changedInA) { prevailing = objectA; } if (changedInB) { prevailing = objectB; } } } IReplicationProviderInside prevailingPeer = prevailing == objectA ? _providerA : _providerB; if (_directionTo == prevailingPeer) { return(false); } if (!conflict) { prevailingPeer.Activate(prevailing); } //Already activated if there was a conflict. if (prevailing != _obj) { otherRef.SetCounterpart(_obj); otherRef.MarkForReplicating(true); MarkAsNotProcessed(uuid); _traverser.ExtendTraversalTo(prevailing); } else { //Now we start traversing objects on the other peer! Is that cool or what? ;) ownerRef.MarkForReplicating(true); } return(!_event._actionShouldStopTraversal); }
public virtual bool WasModifiedSinceLastReplication(IReplicationReference reference ) { return reference.Version() > GetLastReplicationVersion(); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference referencingObjCounterPartRef, string fieldName) { IDrsUUID uuid = counterpartReference.Uuid(); if (uuid == null) { return null; } byte[] signature = uuid.GetSignaturePart(); long longPart = uuid.GetLongPart(); long version = counterpartReference.Version(); Db4oDatabase db = _signatureMap.Produce(signature, 0); Db4oReplicationReferenceImpl @ref = new Db4oReplicationReferenceImpl(obj, db, longPart , version); AddReference(@ref); return @ref; }
public virtual bool WasModifiedSinceLastReplication(IReplicationReference reference ) { return(reference.Version() > GetLastReplicationVersion()); }
private bool HandleMissingObjectInOther(object obj, IReplicationReference ownerRef , IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject , string fieldName) { bool isConflict = false; bool wasModified = owner.WasModifiedSinceLastReplication(ownerRef); if (wasModified) { isConflict = true; } if (_directionTo == other) { isConflict = true; } object prevailing = null; //by default, deletion prevails if (isConflict) { owner.Activate(obj); } _event.ResetAction(); _event._isConflict = isConflict; _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); long modificationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Version()); if (owner == _providerA) { _stateInA.SetAll(obj, false, wasModified, modificationDate); _stateInB.SetAll(null, false, false, -1); } else { //owner == _providerB _stateInA.SetAll(null, false, false, -1); _stateInB.SetAll(obj, false, wasModified, modificationDate); } _listener.OnReplicate(_event); if (isConflict && !_event._actionWasChosen) { ThrowReplicationConflictException(); } if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return false; } if (_event._actionChosenState == _stateInA) { prevailing = _stateInA.GetObject(); } if (_event._actionChosenState == _stateInB) { prevailing = _stateInB.GetObject(); } } if (prevailing == null) { //Deletion has prevailed. if (_directionTo == other) { return false; } ownerRef.MarkForDeleting(); return !_event._actionShouldStopTraversal; } bool needsToBeActivated = !isConflict; //Already activated if there was a conflict. return HandleNewObject(obj, ownerRef, owner, other, referencingObject, fieldName, needsToBeActivated, true); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference unused, string unused2) { //System.out.println("referenceNewObject: " + obj + " UUID: " + counterpartReference.uuid()); IDrsUUID uuid = counterpartReference.Uuid(); long version = counterpartReference.Version(); if (GetObject(uuid) != null) { throw new Exception("Object exists already."); } IReplicationReference result = CreateReferenceFor(obj); Store(obj, uuid, version); return result; }
public virtual bool WasModifiedSinceLastReplication(IReplicationReference reference ) { long timestamp = reference.Version(); if (timestamp > _replicationRecord._version) { return true; } long[] concurrentTimestamps = _replicationRecord.ConcurrentTimestamps(); if (concurrentTimestamps == null) { return false; } for (int i = 0; i < concurrentTimestamps.Length; i++) { if (timestamp == concurrentTimestamps[i]) { return true; } } return false; }