示例#1
0
        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);
        }
示例#2
0
        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;
            }
        }
示例#3
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
 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);
     }
 }
示例#7
0
        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;
            }
        }
示例#8
0
        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));
        }
示例#9
0
        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);
        }
示例#10
0
        public virtual void TestContinousIncrement()
        {
            TimeStampIdGenerator generator = new TimeStampIdGenerator();

            AssertContinousIncrement(generator);
        }