private bool HandleNewObject(object obj, IReplicationReference ownerRef, IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject, string fieldName , bool needsToBeActivated, bool listenerAlreadyNotified) { if (_directionTo == owner) { return(false); } if (needsToBeActivated) { owner.Activate(obj); } if (!listenerAlreadyNotified) { _event.ResetAction(); _event.Conflict(false); _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); if (owner == _providerA) { _stateInA.SetAll(obj, true, false, ObjectStateImpl.Unknown); _stateInB.SetAll(null, false, false, ObjectStateImpl.Unknown); } else { _stateInA.SetAll(null, false, false, ObjectStateImpl.Unknown); _stateInB.SetAll(obj, true, false, ObjectStateImpl.Unknown); } if (_listener != null) { _listener.OnReplicate(_event); if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return(false); } if (_event._actionChosenState.GetObject() != obj) { return(false); } } } } object counterpart = EmptyClone(owner, obj); ownerRef.SetCounterpart(counterpart); ownerRef.MarkForReplicating(true); IReplicationReference otherRef = other.ReferenceNewObject(counterpart, ownerRef, GetCounterpartRef(referencingObject), fieldName); otherRef.SetCounterpart(obj); PutCounterpartRef(obj, otherRef); if (_event._actionShouldStopTraversal) { return(false); } return(true); }
private void AssertContinousIncrement(TimeStampIdGenerator generator) { long oldId = generator.Generate(); for (int i = 0; i < 1000000; i++) { long newId = generator.Generate(); Assert.IsGreater(oldId, newId); oldId = newId; } }
private long[] GenerateIds() { int count = 500; TimeStampIdGenerator generator = new TimeStampIdGenerator(); long[] ids = new long[count]; for (int i = 0; i < ids.Length; i++) { ids[i] = generator.Generate(); } return(ids); }
private long[] GenerateIds() { var count = 500; var generator = new TimeStampIdGenerator(); var ids = new long[count]; for (var i = 0; i < ids.Length; i++) { ids[i] = generator.Generate(); } return(ids); }
public virtual void TestTimeStamp() { IQuery q = NewItemQuery(); q.Descend("name").Constrain("one"); UUIDTestCase.Item item = (UUIDTestCase.Item)q.Execute().Next(); Db4oUUID uuid = Uuid(item); long longPart = uuid.GetLongPart(); long creationTime = TimeStampIdGenerator.IdToMilliseconds(longPart); Assert.IsGreaterOrEqual(storeStartTime, creationTime); Assert.IsSmallerOrEqual(storeEndTime, creationTime); }
public virtual void TestObjectCounterPartOnlyUses6Bits() { long[] ids = GenerateIds(); for (int i = 1; i < ids.Length; i++) { Assert.IsGreater(ids[i] - 1, ids[i]); long creationTime = TimeStampIdGenerator.IdToMilliseconds(ids[i]); long timePart = TimeStampIdGenerator.MillisecondsToId(creationTime); long objectCounter = ids[i] - timePart; // 6 bits Assert.IsSmallerOrEqual(Binary.LongForBits(6), objectCounter); } }
public virtual void TransientProviderSpecificStore(object obj) { //TODO ak: this implementation of vvv is copied from Hibernate, which works. // However, vvv should be supposed to be replaced by getCurrentVersion(), but that wouldn't work. Find out long vvv = new TimeStampIdGenerator(_lastReplicationVersion).Generate(); TransientReplicationProvider.ObjectInfo info = GetInfo(obj); if (info == null) { Store(obj, new DrsUUIDImpl(new Db4oUUID(_timeStampIdGenerator.Generate(), _signature .GetSignature())), vvv); } else { info._version = vvv; } }
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 void TestContinousIncrement() { TimeStampIdGenerator generator = new TimeStampIdGenerator(); AssertContinousIncrement(generator); }