public void TestRestoreCacheNoValidate()
        {
            MetadataCache cache = new MetadataCache();

            AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "metadata", "duplicates"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 };

            UserOptions.Default.VerifyDeserializationPaths = false;

            DeserializationContext context = cache.Restore(monitor);

            Assert.AreEqual(9, context.CompleteCount, "Context Complete count");
            Assert.AreEqual(1, context.Incomplete.Count, "Context Incomplete count");
            Assert.AreEqual(19, context.PendingImages.Count, "Context PendingImages count");
            Assert.IsTrue(context.ImplicitChannelImageFileSize > 0.0, "Context ImplicitChannelImageFileSize");
            Assert.AreEqual(2, context.ImplicitChannelImageFrameCount, "Context ImplicitChannelImageFrameCount");

            Assert.AreEqual(2, monitor.Days.Count, "Day count");
            Assert.AreEqual(10, monitor.Tiles.Count, "Tile count");
            Assert.AreEqual(1, monitor.IncompleteTiles.Count, "Incomplete count");
            Assert.AreEqual(4, monitor.Lattice.Duplicates.Count, "Duplicate count");

            Assert.AreEqual(100, monitor.Lattice.Duplicates[0].Position.X);
            Assert.AreEqual(50, monitor.Lattice.Duplicates[0].Position.Y);
            Assert.AreEqual(20, monitor.Lattice.Duplicates[0].Position.Z);
            Assert.AreEqual(3, monitor.Lattice.Duplicates[0].TileCount);

            Assert.AreEqual(100, monitor.Lattice.Duplicates[1].Position.X);
            Assert.AreEqual(55, monitor.Lattice.Duplicates[1].Position.Y);
            Assert.AreEqual(20, monitor.Lattice.Duplicates[1].Position.Z);
            Assert.AreEqual(2, monitor.Lattice.Duplicates[1].TileCount);

            Assert.AreEqual(20, monitor.Lattice.Duplicates[2].Position.X);
            Assert.AreEqual(60, monitor.Lattice.Duplicates[2].Position.Y);
            Assert.AreEqual(40, monitor.Lattice.Duplicates[2].Position.Z);
            Assert.AreEqual(2, monitor.Lattice.Duplicates[2].TileCount);

            Assert.AreEqual(70, monitor.Lattice.Duplicates[3].Position.X);
            Assert.AreEqual(80, monitor.Lattice.Duplicates[3].Position.Y);
            Assert.AreEqual(90, monitor.Lattice.Duplicates[3].Position.Z);
            Assert.AreEqual(2, monitor.Lattice.Duplicates[3].TileCount);
        }
        public void TestRestoreCacheValidate()
        {
            MetadataCache cache = new MetadataCache();

            AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "metadata", "duplicates"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 };

            UserOptions.Default.VerifyDeserializationPaths = true;

            DeserializationContext context = cache.Restore(monitor);

            Assert.AreEqual(0, context.CompleteCount, "Context Complete count");
            Assert.AreEqual(0, context.Incomplete.Count, "Context Incomplete count");
            Assert.AreEqual(0, context.PendingImages.Count, "Context PendingImages count");
            Assert.AreEqual(0.0, context.ImplicitChannelImageFileSize, "Context ImplicitChannelImageFileSize");
            Assert.AreEqual(Int32.MinValue, context.ImplicitChannelImageFrameCount, "Context ImplicitChannelImageFrameCount");

            Assert.AreEqual(0, monitor.Days.Count, "Day count");
            Assert.AreEqual(0, monitor.Tiles.Count, "Tile count");
            Assert.AreEqual(0, monitor.IncompleteTiles.Count, "Incomplete count");
            Assert.AreEqual(0, monitor.Lattice.Duplicates.Count, "Duplicate count");
        }
        private void RestoreMetadata()
        {
            DeserializationContext context;

            if (_metadataCache != null)
            {
                context = _metadataCache.Restore(Model);
            }
            else
            {
                MetadataCache cache = new MetadataCache();
                context = cache.Restore(Model);
            }

            if (context != null)
            {
                TileEvaluateWorker.ImplicitChannelFileSize = context.ImplicitChannelImageFileSize;
                TileEvaluateWorker.ImplicitChannelFrameCount = context.ImplicitChannelImageFrameCount;

                _deserializeCompleteCount = context.CompleteCount;

                foreach (Tile tile in context.Incomplete)
                {
                    _incompleteMonitoringQueue.Enqueue(tile);
                }

                Trace.TraceInformation("\t{0} restored tiles added to the incomplete queue.", context.Incomplete.Count);

                if (UserOptions.Default.QueryTiffContents && !UserOptions.Default.OnlyQueryEmergingTiffContents)
                {
                    foreach (var item in context.PendingImages)
                    {
                        TiffEvaluateWorker.ExistingManager.QueueTiff(item);
                    }

                    if (context.PendingImages.Count > 0)
                    {
                        Trace.TraceInformation("\t{0} restored image files added to the TIFF content processing queue.", context.PendingImages.Count);
                    }
                }
            }
        }
        /// <summary>
        /// Encapsulates the task of observing a root directory for tile additions and changes.
        /// </summary>
        /// <param name="monitor"></param>
        public AcquisitionWorker(AcquisitionMonitor monitor)
        {
            Contract.Requires(monitor != null);

            _model = monitor;
            _hasStarted = false;

            _deserializeCompleteCount = 0;

            _cts = new CancellationTokenSource();

            // Timers (not started)
            _topLevelMonitoringTimer = new System.Timers.Timer(UserOptions.Default.TopLevelDirectoryPollingIntervalMinutes * 60 * 1000);
            _topLevelMonitoringTimer.Elapsed += TopLevelMonitoringElapsed;

            _incompleteMonitoringTimer = new System.Timers.Timer(UserOptions.Default.IncompleteTilePollingIntervalMinutes * 60 * 1000);
            _incompleteMonitoringTimer.Elapsed += EvaluateIncompleteList;

            // Queues
            _incompleteMonitoringQueue = new TileQueue();
            _existingTileQueue = new TileQueue();

            // Discovery workers (not started)
            _discoveryWorkers = new ConcurrentDictionary<TileGroup, TileGroupEmergingWorker>();
            _existingOnlyWorkers = new ConcurrentDictionary<TileGroup, TileGroupExistingWorker>();

            // Evaluate workers (not started)
            _emergingProcessingWorker = new TileEvaluateWorker(null, _incompleteMonitoringQueue, true);

            _existingProcessingWorkers = new List<TileEvaluateWorker>();
            for (int idx = 0; idx < _existingProcessorCount; idx++)
            {
                _existingProcessingWorkers.Add(new TileEvaluateWorker(_existingTileQueue, _incompleteMonitoringQueue, false));
            }

            _incompleteProcessingWorker = new TileEvaluateWorker(null, _incompleteMonitoringQueue, false);

            _duplicateTileWorker = new DuplicateTileWorker();

            // Metadata storage.
            if (UserOptions.Default.SerializeMetadata)
            {
                _metadataCache = new MetadataCache();
            }
            else
            {
                Trace.TraceInformation("Metadata cache has been disabled.  Changes will not be recorded.");
            }
        }