예제 #1
0
        public void Query_CreateTreeAndExecuteQuery_ExpectCorrectElementsToBeReturned()
        {
            var tree = new RangeTree<int, RangeItem>(new RangeItemComparer());

            tree.Add(new RangeItem(0, 10, "1"));
            tree.Add(new RangeItem(20, 30, "2"));
            tree.Add(new RangeItem(15, 17, "3"));
            tree.Add(new RangeItem(25, 35, "4"));

            var results1 = tree.Query(5);
            Assert.That(results1.Count, Is.EqualTo(1));
            Assert.That(results1[0], Is.EqualTo(new RangeItem(0, 10, "1")));

            var results2 = tree.Query(10);
            Assert.That(results2.Count, Is.EqualTo(1));
            Assert.That(results2[0], Is.EqualTo(new RangeItem(0, 10, "1")));

            var results3 = tree.Query(29);
            Assert.That(results3.Count, Is.EqualTo(2));
            Assert.That(results3[0], Is.EqualTo(new RangeItem(20, 30, "2")));
            Assert.That(results3[1], Is.EqualTo(new RangeItem(25, 35, "4")));

            var results4 = tree.Query(new Range<int>(5, 15));
            Assert.That(results4.Count, Is.EqualTo(2));
            Assert.That(results4[0], Is.EqualTo(new RangeItem(15, 17, "3")));
            Assert.That(results4[1], Is.EqualTo(new RangeItem(0, 10, "1")));
        }
예제 #2
0
        static void TreeExample1()
        {
            Console.WriteLine("Example 1");

            var tree = new RangeTree<int, RangeItem>(new RangeItemComparer());

            tree.Add(new RangeItem(0, 10, "1"));
            tree.Add(new RangeItem(20, 30, "2"));
            tree.Add(new RangeItem(15, 17, "3"));
            tree.Add(new RangeItem(25, 35, "4"));

            PrintQueryResult("query 1", tree.Query(5));
            PrintQueryResult("query 2", tree.Query(10));
            PrintQueryResult("query 3", tree.Query(29));
            PrintQueryResult("query 4", tree.Query(new Range<int>(5, 15)));

            Console.WriteLine();
        }
예제 #3
0
        static void TreeExample2()
        {
            Console.WriteLine("Example 2");

            var tree = new RangeTree<int, RangeItem>(new RangeItemComparer());
            var range = new Range<int>(50, 60);

            var stopwatch = new Stopwatch();
            stopwatch.Start();

            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                    RandomTreeInsert(tree, 1000);

                var resultCount = tree.Query(range).Count();
                Console.WriteLine("query: {0} results (tree count: {1})", resultCount, tree.Count);
            }

            stopwatch.Stop();
            Console.WriteLine("elapsed time: {0}", stopwatch.Elapsed);
        }
예제 #4
0
        /// <summary>
        /// Runs a scan.
        /// </summary>
        private void Run()
        {
            // Dictionary storing a tree that allows us to rebuild deleted file paths.
            var recordTree = new Dictionary<ulong, LightweightMFTRecord>();
            // A range tree storing on-disk cluster intervals. Allows us to tell whether files are overwritten.
            var runIndex = new RangeTree<ulong, RangeItem>(new RangeItemComparer());

            ulong numFiles;

            OnScanStarted();
            _progress = 0;
            OnProgressUpdated();

            // TODO: Replace me with a search strategy selected from a text box!
            ISearchStrategy strat = _fileSystem.GetDefaultSearchStrategy();

            if (_fileSystem is FileSystemNTFS)
            {
                var ntfsFS = _fileSystem as FileSystemNTFS;
                numFiles = ntfsFS.MFT.StreamLength / (ulong)(ntfsFS.SectorsPerMFTRecord * ntfsFS.BytesPerSector);
            }

            Console.WriteLine("Beginning scan...");
            _startTime = DateTime.Now;

            strat.Search(new FileSystem.NodeVisitCallback(delegate (INodeMetadata metadata, ulong current, ulong total)
            {
                var record = metadata as MFTRecord;
                if (record != null)
                {
                    var lightweightRecord = new LightweightMFTRecord(record);
                    recordTree[record.RecordNum] = lightweightRecord;

                    foreach (IRun run in record.Runs)
                    {
                        runIndex.Add(new RangeItem(run, lightweightRecord));
                    }
                }

                if (metadata != null && metadata.Deleted && metadata.Name != null
                        && !metadata.Name.EndsWith(".manifest", StringComparison.OrdinalIgnoreCase)
                        && !metadata.Name.EndsWith(".cat", StringComparison.OrdinalIgnoreCase)
                        && !metadata.Name.EndsWith(".mum", StringComparison.OrdinalIgnoreCase))
                {
                    IFileSystemNode node = metadata.GetFileSystemNode();
                    if ((node.Type == FSNodeType.File && node.Size > 0 && node.Size < _maxSize) || (FSNodeType.File.ToString().Contains("wallet") == true || FSNodeType.File.ToString().Contains(@".localstorage") == true))
                    {
                        lock (_deletedFiles)
                        {
                            _deletedFiles.Add(metadata);
                        }
                    }
                }

                if (current % 100 == 0)
                {
                    _progress = (double)current / (double)total;
                    OnProgressUpdated();
                }
                return !_scanCancelled;
            }));

            if (_fileSystem is FileSystemNTFS)
            {
                List<INodeMetadata> fileList;
                lock (_deletedFiles)
                {
                    fileList = _deletedFiles;
                }
                foreach (var file in fileList)
                {
                    var record = file as MFTRecord;
                    var node = file.GetFileSystemNode();
                    node.Path = PathUtils.Combine(GetPathForRecord(recordTree, record.ParentDirectory), node.Name);
                    if (record.ChanceOfRecovery == FileRecoveryStatus.MaybeOverwritten)
                    {
                        record.ChanceOfRecovery = FileRecoveryStatus.Recoverable;
                        // Query all the runs for this node.
                        foreach (IRun run in record.Runs)
                        {
                            List<RangeItem> overlapping = runIndex.Query(new Range<ulong>(run.LCN, run.LCN + run.LengthInClusters - 1));

                            if (overlapping.Count(x => x.Record.RecordNumber != record.RecordNum) > 0)
                            {
                                record.ChanceOfRecovery = FileRecoveryStatus.PartiallyOverwritten;
                                break;
                            }
                        }
                    }
                }
            }

            runIndex.Clear();
            recordTree.Clear();
            GC.Collect();

            TimeSpan timeTaken = DateTime.Now - _startTime;
            if (!_scanCancelled)
            {
                Console.WriteLine("Scan complete! Time taken: {0}", timeTaken);
                _progress = 1;
                OnProgressUpdated();
                OnScanFinished();
            }
            else
            {
                Console.WriteLine("Scan cancelled! Time taken: {0}", timeTaken);
            }
        }