public void TestSequenceMap()
        {
            var map = new SequenceMap();

            Assert.AreEqual(0, map.GetCheckpointedSequence());
            Assert.AreEqual(null, map.GetCheckpointedValue());
            Assert.IsTrue(map.IsEmpty());
            Assert.AreEqual(1, map.AddValue("one"));
            Assert.AreEqual(0, map.GetCheckpointedSequence());
            Assert.AreEqual(null, map.GetCheckpointedValue());
            Assert.IsTrue(!map.IsEmpty());
            Assert.AreEqual(2, map.AddValue("two"));
            Assert.AreEqual(0, map.GetCheckpointedSequence());
            Assert.AreEqual(null, map.GetCheckpointedValue());
            Assert.AreEqual(3, map.AddValue("three"));
            Assert.AreEqual(0, map.GetCheckpointedSequence());
            Assert.AreEqual(null, map.GetCheckpointedValue());
            map.RemoveSequence(2);
            Assert.AreEqual(0, map.GetCheckpointedSequence());
            Assert.AreEqual(null, map.GetCheckpointedValue());
            map.RemoveSequence(1);
            Assert.AreEqual(2, map.GetCheckpointedSequence());
            Assert.AreEqual("two", map.GetCheckpointedValue());
            Assert.AreEqual(4, map.AddValue("four"));
            Assert.AreEqual(2, map.GetCheckpointedSequence());
            Assert.AreEqual("two", map.GetCheckpointedValue());
            map.RemoveSequence(3);
            Assert.AreEqual(3, map.GetCheckpointedSequence());
            Assert.AreEqual("three", map.GetCheckpointedValue());
            map.RemoveSequence(4);
            Assert.AreEqual(4, map.GetCheckpointedSequence());
            Assert.AreEqual("four", map.GetCheckpointedValue());
            Assert.IsTrue(map.IsEmpty());
        }
        /// <summary>Process a bunch of remote revisions from the _changes feed at once</summary>
        internal override void ProcessInbox(RevisionList inbox)
        {
            Debug.Assert(inbox != null);

            // Ask the local database which of the revs are not known to it:
            //Log.w(Database.TAG, String.format("%s: Looking up %s", this, inbox));
            var lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID
                                        ();
            var total = ChangesCount - inbox.Count;

            if (!LocalDatabase.FindMissingRevisions(inbox))
            {
                Log.W(Tag, string.Format("{0} failed to look up local revs", this));
                inbox = null;
            }

            //introducing this to java version since inbox may now be null everywhere
            var inboxCount = 0;

            if (inbox != null)
            {
                inboxCount = inbox.Count;
            }
            ChangesCount = total + inboxCount;

            if (inboxCount == 0)
            {
                // Nothing to do. Just bump the lastSequence.
                Log.W(Tag, string.Format("{0} no new remote revisions to fetch", this));

                var seq = pendingSequences.AddValue(lastInboxSequence);
                pendingSequences.RemoveSequence(seq);
                LastSequence = pendingSequences.GetCheckpointedValue();
                return;
            }

            Log.V(Tag, this + " fetching " + inboxCount + " remote revisions...");
            //Log.v(Database.TAG, String.format("%s fetching remote revisions %s", this, inbox));
            // Dump the revs into the queue of revs to pull from the remote db:
            lock (locker) {
                if (revsToPull == null)
                {
                    revsToPull = new AList <RevisionInternal> (200);
                }
                for (int i = 0; i < inbox.Count; i++)
                {
                    var rev = (PulledRevision)inbox [i];
                    // FIXME add logic here to pull initial revs in bulk
                    rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID()));
                    revsToPull.AddItem(rev);
                }
            }
            PullRemoteRevisions();
        }
Beispiel #3
0
        internal override void BeginReplicating()
        {
            Log.To.Sync.I(TAG, "{2} will use MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})",
                          ReplicationOptions.MaxOpenHttpConnections,
                          ReplicationOptions.MaxRevsToGetInBulk,
                          this);

            if (_downloadsToInsert == null)
            {
                const int capacity = INBOX_CAPACITY * 2;
                TimeSpan  delay    = TimeSpan.FromSeconds(1);
                _downloadsToInsert = new Batcher <RevisionInternal>(WorkExecutor, capacity, delay, InsertDownloads);
            }

            if (_pendingSequences == null)
            {
                _pendingSequences = new SequenceMap();
                if (LastSequence != null)
                {
                    // Prime _pendingSequences so its checkpointedValue will reflect the last known seq:
                    var seq = _pendingSequences.AddValue(LastSequence);
                    _pendingSequences.RemoveSequence(seq);
                    Debug.Assert((_pendingSequences.GetCheckpointedValue().Equals(LastSequence)));
                }
            }

            _caughtUp = false;
            StartChangeTracker();
        }
Beispiel #4
0
        internal override void BeginReplicating()
        {
            Log.D(TAG, string.Format("Using MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})",
                                     ManagerOptions.Default.MaxOpenHttpConnections, ManagerOptions.Default.MaxRevsToGetInBulk));

            if (_downloadsToInsert == null)
            {
                const int capacity = INBOX_CAPACITY * 2;
                const int delay    = 1000;
                _downloadsToInsert = new Batcher <RevisionInternal>(WorkExecutor, capacity, delay, InsertDownloads);
            }

            if (_pendingSequences == null)
            {
                _pendingSequences = new SequenceMap();
                if (LastSequence != null)
                {
                    // Prime _pendingSequences so its checkpointedValue will reflect the last known seq:
                    var seq = _pendingSequences.AddValue(LastSequence);
                    _pendingSequences.RemoveSequence(seq);
                    Debug.Assert((_pendingSequences.GetCheckpointedValue().Equals(LastSequence)));
                }
            }

            StartChangeTracker();
        }
Beispiel #5
0
        internal override void BeginReplicating()
        {
            Log.D(Tag, string.Format("Using MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})",
                                     ManagerOptions.Default.MaxOpenHttpConnections, ManagerOptions.Default.MaxRevsToGetInBulk));

            if (downloadsToInsert == null)
            {
                const int capacity = 200;
                const int delay    = 1000;
                downloadsToInsert = new Batcher <RevisionInternal> (WorkExecutor, capacity, delay, InsertDownloads);
            }

            if (pendingSequences == null)
            {
                pendingSequences = new SequenceMap();
                if (LastSequence != null)
                {
                    // Prime _pendingSequences so its checkpointedValue will reflect the last known seq:
                    var seq = pendingSequences.AddValue(LastSequence);
                    pendingSequences.RemoveSequence(seq);
                    Debug.Assert((pendingSequences.GetCheckpointedValue().Equals(LastSequence)));
                }
            }

            Log.D(Tag, "starting ChangeTracker with since = " + LastSequence);

            var mode = Continuous
                       ? ChangeTrackerMode.LongPoll
                       : ChangeTrackerMode.OneShot;

            changeTracker = new ChangeTracker(RemoteUrl, mode, LastSequence, true, this, WorkExecutor);
            changeTracker.Authenticator = Authenticator;

            if (Filter != null)
            {
                changeTracker.SetFilterName(Filter);
                if (FilterParams != null)
                {
                    changeTracker.SetFilterParams(FilterParams.ToDictionary(kvp => kvp.Key, kvp => (Object)kvp.Value));
                }
            }
            if (!continuous)
            {
                Log.D(Tag, "BeginReplicating() calling asyncTaskStarted()");
                AsyncTaskStarted();
            }

            changeTracker.UsePost = CheckServerCompatVersion("0.93");
            changeTracker.Start();
        }
Beispiel #6
0
 public override void BeginReplicating()
 {
     if (downloadsToInsert == null)
     {
         int capacity = 200;
         int delay    = 1000;
         downloadsToInsert = new Batcher <RevisionInternal>(workExecutor, capacity, delay,
                                                            new _BatchProcessor_131(this));
     }
     if (pendingSequences == null)
     {
         pendingSequences = new SequenceMap();
         if (GetLastSequence() != null)
         {
             // Prime _pendingSequences so its checkpointedValue will reflect the last known seq:
             long seq = pendingSequences.AddValue(GetLastSequence());
             pendingSequences.RemoveSequence(seq);
             System.Diagnostics.Debug.Assert((pendingSequences.GetCheckpointedValue().Equals(GetLastSequence
                                                                                                 ())));
         }
     }
     Log.W(Log.TagSync, "%s: starting ChangeTracker with since=%s", this, lastSequence
           );
     changeTracker = new ChangeTracker(remote, continuous ? ChangeTracker.ChangeTrackerMode
                                       .LongPoll : ChangeTracker.ChangeTrackerMode.OneShot, true, lastSequence, this);
     changeTracker.SetAuthenticator(GetAuthenticator());
     Log.W(Log.TagSync, "%s: started ChangeTracker %s", this, changeTracker);
     if (filterName != null)
     {
         changeTracker.SetFilterName(filterName);
         if (filterParams != null)
         {
             changeTracker.SetFilterParams(filterParams);
         }
     }
     changeTracker.SetDocIDs(documentIDs);
     changeTracker.SetRequestHeaders(requestHeaders);
     if (!continuous)
     {
         Log.V(Log.TagSync, "%s | %s: beginReplicating() calling asyncTaskStarted()", this
               , Sharpen.Thread.CurrentThread());
         AsyncTaskStarted();
     }
     changeTracker.SetUsePOST(ServerIsSyncGatewayVersion("0.93"));
     changeTracker.Start();
 }
Beispiel #7
0
        /// <summary>Process a bunch of remote revisions from the _changes feed at once</summary>
        internal override void ProcessInbox(RevisionList inbox)
        {
            if (!online)
            {
                Log.V(Tag, "Offline, so skipping inbox process");
                return;
            }

            Debug.Assert(inbox != null);

            if (!canBulkGet)
            {
                canBulkGet = CheckServerCompatVersion("0.81");
            }

            // Ask the local database which of the revs are not known to it:
            var lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID();

            var numRevisionsRemoved = 0;

            try {
                // findMissingRevisions is the local equivalent of _revs_diff. it looks at the
                // array of revisions in inbox and removes the ones that already exist. So whatever's left in inbox
                // afterwards are the revisions that need to be downloaded.
                numRevisionsRemoved = LocalDatabase.FindMissingRevisions(inbox);
            } catch (Exception e) {
                Log.E(Tag, "Failed to look up local revs", e);
                inbox = null;
            }

            //introducing this to java version since inbox may now be null everywhere
            var inboxCount = 0;

            if (inbox != null)
            {
                inboxCount = inbox.Count;
            }

            if (numRevisionsRemoved > 0)
            {
                Log.V(Tag, "processInbox() setting changesCount to: " + (ChangesCount - numRevisionsRemoved));
                SafeAddToChangesCount(-numRevisionsRemoved);
            }

            if (inboxCount == 0)
            {
                // Nothing to do. Just bump the lastSequence.
                Log.W(Tag, string.Format("{0} no new remote revisions to fetch", this));

                var seq = pendingSequences.AddValue(lastInboxSequence);
                pendingSequences.RemoveSequence(seq);
                LastSequence = pendingSequences.GetCheckpointedValue();
                return;
            }

            Log.V(Tag, "fetching " + inboxCount + " remote revisions...");

            // Dump the revs into the queue of revs to pull from the remote db:
            lock (locker) {
                int numBulked = 0;
                for (int i = 0; i < inbox.Count; i++)
                {
                    var rev = (PulledRevision)inbox [i];
                    //TODO: add support for rev isConflicted
                    if (canBulkGet || (rev.GetGeneration() == 1 && !rev.IsDeleted()))
                    {
                        // &&!rev.isConflicted)
                        //optimistically pull 1st-gen revs in bulk
                        if (bulkRevsToPull == null)
                        {
                            bulkRevsToPull = new List <RevisionInternal>(100);
                        }
                        bulkRevsToPull.AddItem(rev);
                        ++numBulked;
                    }
                    else
                    {
                        QueueRemoteRevision(rev);
                    }
                    rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID()));
                }
            }

            PullRemoteRevisions();
        }
Beispiel #8
0
        protected internal override void ProcessInbox(RevisionList inbox)
        {
            if (canBulkGet == null)
            {
                canBulkGet = ServerIsSyncGatewayVersion("0.81");
            }
            // Ask the local database which of the revs are not known to it:
            string lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID
                                           ();
            int numRevisionsRemoved = 0;

            try
            {
                // findMissingRevisions is the local equivalent of _revs_diff. it looks at the
                // array of revisions in ‘inbox’ and removes the ones that already exist. So whatever’s left in ‘inbox’
                // afterwards are the revisions that need to be downloaded.
                numRevisionsRemoved = db.FindMissingRevisions(inbox);
            }
            catch (SQLException e)
            {
                Log.E(Log.TagSync, string.Format("%s failed to look up local revs", this), e);
                inbox = null;
            }
            //introducing this to java version since inbox may now be null everywhere
            int inboxCount = 0;

            if (inbox != null)
            {
                inboxCount = inbox.Count;
            }
            if (numRevisionsRemoved > 0)
            {
                Log.V(Log.TagSync, "%s: processInbox() setting changesCount to: %s", this, GetChangesCount
                          () - numRevisionsRemoved);
                // May decrease the changesCount, to account for the revisions we just found out we don’t need to get.
                AddToChangesCount(-1 * numRevisionsRemoved);
            }
            if (inboxCount == 0)
            {
                // Nothing to do. Just bump the lastSequence.
                Log.W(Log.TagSync, "%s no new remote revisions to fetch", this);
                long seq = pendingSequences.AddValue(lastInboxSequence);
                pendingSequences.RemoveSequence(seq);
                SetLastSequence(pendingSequences.GetCheckpointedValue());
                return;
            }
            Log.V(Log.TagSync, "%s: fetching %s remote revisions...", this, inboxCount);
            // Dump the revs into the queue of revs to pull from the remote db:
            lock (this)
            {
                int numBulked = 0;
                for (int i = 0; i < inbox.Count; i++)
                {
                    PulledRevision rev = (PulledRevision)inbox[i];
                    //TODO: add support for rev isConflicted
                    if (canBulkGet || (rev.GetGeneration() == 1 && !rev.IsDeleted()))
                    {
                        // &&!rev.isConflicted)
                        //optimistically pull 1st-gen revs in bulk
                        if (bulkRevsToPull == null)
                        {
                            bulkRevsToPull = new AList <RevisionInternal>(100);
                        }
                        bulkRevsToPull.AddItem(rev);
                        ++numBulked;
                    }
                    else
                    {
                        QueueRemoteRevision(rev);
                    }
                    rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID()));
                }
            }
            PullRemoteRevisions();
        }