示例#1
0
        private PTable(string filename,
                       Guid id,
                       int bufferSize        = 8096,
                       int maxReadingThreads = TFConsts.ReadIndexReaderCount,
                       int depth             = 16)
        {
            if (!File.Exists(filename))
            {
                throw new CorruptIndexException(new PTableNotFoundException(filename));
            }

            _id   = id;
            _size = new FileInfo(filename).Length - PTableHeader.Size - MD5Size;

            _filename = filename;
            File.SetAttributes(_filename, FileAttributes.ReadOnly);
            File.SetAttributes(_filename, FileAttributes.Temporary);
            File.SetAttributes(_filename, FileAttributes.NotContentIndexed);

            _bufferSize        = bufferSize;
            _maxReadingThreads = maxReadingThreads;
            _buffer            = new byte[16];
            _bufferPtr         = GCHandle.Alloc(_buffer, GCHandleType.Pinned);

            using (var stream = File.OpenRead(filename))
                using (var reader = new BinaryReader(stream))
                {
                    PTableHeader.FromStream(reader);
                }

            for (int i = 0; i < _maxReadingThreads; i++)
            {
                var s = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.Read, 16, FileOptions.RandomAccess);
                _streams.Enqueue(s);
            }

            try
            {
                _midpoints = PopulateCache(depth);
            }
            catch (PossibleToHandleOutOfMemoryException)
            {
                Log.Info("Was unable to create midpoints for ptable. Performance hit possible OOM Exception.");
            }
        }
示例#2
0
        private PTable(string filename,
                       Guid id,
                       int initialReaders = ESConsts.PTableInitialReaderCount,
                       int maxReaders     = ESConsts.PTableMaxReaderCount,
                       int depth          = 16)
        {
            Ensure.NotNullOrEmpty(filename, "filename");
            Ensure.NotEmptyGuid(id, "id");
            Ensure.Positive(maxReaders, "maxReaders");
            Ensure.Nonnegative(depth, "depth");

            if (!File.Exists(filename))
            {
                throw new CorruptIndexException(new PTableNotFoundException(filename));
            }

            _id       = id;
            _filename = filename;

            var sw = Stopwatch.StartNew();

            Log.Trace("Loading PTable '{0}' started...", Filename);

            _size = new FileInfo(_filename).Length - PTableHeader.Size - MD5Size;
            File.SetAttributes(_filename, FileAttributes.ReadOnly | FileAttributes.NotContentIndexed);

            _workItems = new ObjectPool <WorkItem>(string.Format("PTable {0} work items", _id),
                                                   initialReaders,
                                                   maxReaders,
                                                   () => new WorkItem(filename, DefaultBufferSize),
                                                   workItem => workItem.Dispose(),
                                                   pool => OnAllWorkItemsDisposed());

            var readerWorkItem = GetWorkItem();

            try
            {
                readerWorkItem.Stream.Seek(0, SeekOrigin.Begin);
                var header = PTableHeader.FromStream(readerWorkItem.Stream);
                if (header.Version != Version)
                {
                    throw new CorruptIndexException(new WrongFileVersionException(_filename, header.Version, Version));
                }
            }
            catch (Exception)
            {
                Dispose();
                throw;
            }
            finally
            {
                ReturnWorkItem(readerWorkItem);
            }

            try
            {
                _midpoints = CacheMidpoints(depth);
            }
            catch (PossibleToHandleOutOfMemoryException)
            {
                Log.Error("Was unable to create midpoints for PTable '{0}' ({1} entries, depth {2} requested). "
                          + "Performance hit possible. OOM Exception.", Filename, Count, depth);
            }
            Log.Trace("Loading PTable '{0}' ({1} entries, cache depth {2}) done in {3}.", Filename, Count, depth, sw.Elapsed);
        }
示例#3
0
        private PTable(string filename,
                       Guid id,
                       int initialReaders,
                       int maxReaders,
                       int depth            = 16,
                       bool skipIndexVerify = false)
        {
            Ensure.NotNullOrEmpty(filename, "filename");
            Ensure.NotEmptyGuid(id, "id");
            Ensure.Positive(maxReaders, "maxReaders");
            Ensure.Nonnegative(depth, "depth");

            if (!File.Exists(filename))
            {
                throw new CorruptIndexException(new PTableNotFoundException(filename));
            }

            _id       = id;
            _filename = filename;

            Log.Verbose("Loading " + (skipIndexVerify ? "" : "and Verification ") + "of PTable '{pTable}' started...",
                        Path.GetFileName(Filename));
            var sw = Stopwatch.StartNew();

            _size = new FileInfo(_filename).Length;

            File.SetAttributes(_filename, FileAttributes.ReadOnly | FileAttributes.NotContentIndexed);

            _workItems = new ObjectPool <WorkItem>(string.Format("PTable {0} work items", _id),
                                                   initialReaders,
                                                   maxReaders,
                                                   () => new WorkItem(filename, DefaultBufferSize),
                                                   workItem => workItem.Dispose(),
                                                   pool => OnAllWorkItemsDisposed());

            var readerWorkItem = GetWorkItem();

            try {
                readerWorkItem.Stream.Seek(0, SeekOrigin.Begin);
                var header = PTableHeader.FromStream(readerWorkItem.Stream);
                if ((header.Version != PTableVersions.IndexV1) &&
                    (header.Version != PTableVersions.IndexV2) &&
                    (header.Version != PTableVersions.IndexV3) &&
                    (header.Version != PTableVersions.IndexV4))
                {
                    throw new CorruptIndexException(new WrongFileVersionException(_filename, header.Version, Version));
                }
                _version = header.Version;

                if (_version == PTableVersions.IndexV1)
                {
                    _indexEntrySize = IndexEntryV1Size;
                    _indexKeySize   = IndexKeyV1Size;
                }

                if (_version == PTableVersions.IndexV2)
                {
                    _indexEntrySize = IndexEntryV2Size;
                    _indexKeySize   = IndexKeyV2Size;
                }

                if (_version == PTableVersions.IndexV3)
                {
                    _indexEntrySize = IndexEntryV3Size;
                    _indexKeySize   = IndexKeyV3Size;
                }

                if (_version >= PTableVersions.IndexV4)
                {
                    //read the PTable footer
                    var previousPosition = readerWorkItem.Stream.Position;
                    readerWorkItem.Stream.Seek(readerWorkItem.Stream.Length - MD5Size - PTableFooter.GetSize(_version),
                                               SeekOrigin.Begin);
                    var footer = PTableFooter.FromStream(readerWorkItem.Stream);
                    if (footer.Version != header.Version)
                    {
                        throw new CorruptIndexException(
                                  String.Format("PTable header/footer version mismatch: {0}/{1}", header.Version,
                                                footer.Version), new InvalidFileException("Invalid PTable file."));
                    }

                    if (_version == PTableVersions.IndexV4)
                    {
                        _indexEntrySize = IndexEntryV4Size;
                        _indexKeySize   = IndexKeyV4Size;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unknown PTable version: " + _version);
                    }

                    _midpointsCached    = footer.NumMidpointsCached;
                    _midpointsCacheSize = _midpointsCached * _indexEntrySize;
                    readerWorkItem.Stream.Seek(previousPosition, SeekOrigin.Begin);
                }

                long indexEntriesTotalSize = (_size - PTableHeader.Size - _midpointsCacheSize -
                                              PTableFooter.GetSize(_version) - MD5Size);

                if (indexEntriesTotalSize < 0)
                {
                    throw new CorruptIndexException(String.Format(
                                                        "Total size of index entries < 0: {0}. _size: {1}, header size: {2}, _midpointsCacheSize: {3}, footer size: {4}, md5 size: {5}",
                                                        indexEntriesTotalSize, _size, PTableHeader.Size, _midpointsCacheSize,
                                                        PTableFooter.GetSize(_version), MD5Size));
                }
                else if (indexEntriesTotalSize % _indexEntrySize != 0)
                {
                    throw new CorruptIndexException(String.Format(
                                                        "Total size of index entries: {0} is not divisible by index entry size: {1}",
                                                        indexEntriesTotalSize, _indexEntrySize));
                }

                _count = indexEntriesTotalSize / _indexEntrySize;

                if (_version >= PTableVersions.IndexV4 && _count > 0 && _midpointsCached > 0 && _midpointsCached < 2)
                {
                    //if there is at least 1 index entry with version>=4 and there are cached midpoints, there should always be at least 2 midpoints cached
                    throw new CorruptIndexException(String.Format(
                                                        "Less than 2 midpoints cached in PTable. Index entries: {0}, Midpoints cached: {1}", _count,
                                                        _midpointsCached));
                }
                else if (_count >= 2 && _midpointsCached > _count)
                {
                    //if there are at least 2 index entries, midpoints count should be at most the number of index entries
                    throw new CorruptIndexException(String.Format(
                                                        "More midpoints cached in PTable than index entries. Midpoints: {0} , Index entries: {1}",
                                                        _midpointsCached, _count));
                }

                if (Count == 0)
                {
                    _minEntry = new IndexEntryKey(ulong.MaxValue, long.MaxValue);
                    _maxEntry = new IndexEntryKey(ulong.MinValue, long.MinValue);
                }
                else
                {
                    var minEntry = ReadEntry(_indexEntrySize, Count - 1, readerWorkItem, _version);
                    _minEntry = new IndexEntryKey(minEntry.Stream, minEntry.Version);
                    var maxEntry = ReadEntry(_indexEntrySize, 0, readerWorkItem, _version);
                    _maxEntry = new IndexEntryKey(maxEntry.Stream, maxEntry.Version);
                }
            } catch (Exception) {
                Dispose();
                throw;
            } finally {
                ReturnWorkItem(readerWorkItem);
            }

            int calcdepth = 0;

            try {
                calcdepth  = GetDepth(_count * _indexEntrySize, depth);
                _midpoints = CacheMidpointsAndVerifyHash(calcdepth, skipIndexVerify);
            } catch (PossibleToHandleOutOfMemoryException) {
                Log.Error(
                    "Unable to create midpoints for PTable '{pTable}' ({count} entries, depth {depth} requested). "
                    + "Performance hit will occur. OOM Exception.", Path.GetFileName(Filename), Count, depth);
            }

            Log.Verbose(
                "Loading PTable (Version: {version}) '{pTable}' ({count} entries, cache depth {depth}) done in {elapsed}.",
                _version, Path.GetFileName(Filename), Count, calcdepth, sw.Elapsed);
        }
示例#4
0
        private PTable(string filename,
                       Guid id,
                       int initialReaders = ESConsts.PTableInitialReaderCount,
                       int maxReaders     = ESConsts.PTableMaxReaderCount,
                       int depth          = 16)
        {
            Ensure.NotNullOrEmpty(filename, "filename");
            Ensure.NotEmptyGuid(id, "id");
            Ensure.Positive(maxReaders, "maxReaders");
            Ensure.Nonnegative(depth, "depth");

            if (!File.Exists(filename))
            {
                throw new CorruptIndexException(new PTableNotFoundException(filename));
            }

            _id       = id;
            _filename = filename;

            Log.Trace("Loading and Verification of PTable '{0}' started...", Path.GetFileName(Filename));
            var sw = Stopwatch.StartNew();

            _size = new FileInfo(_filename).Length;

            File.SetAttributes(_filename, FileAttributes.ReadOnly | FileAttributes.NotContentIndexed);

            _workItems = new ObjectPool <WorkItem>(string.Format("PTable {0} work items", _id),
                                                   initialReaders,
                                                   maxReaders,
                                                   () => new WorkItem(filename, DefaultBufferSize),
                                                   workItem => workItem.Dispose(),
                                                   pool => OnAllWorkItemsDisposed());

            var readerWorkItem = GetWorkItem();

            try
            {
                readerWorkItem.Stream.Seek(0, SeekOrigin.Begin);
                var header = PTableHeader.FromStream(readerWorkItem.Stream);
                if ((header.Version != PTableVersions.Index32Bit) &&
                    (header.Version != PTableVersions.Index64Bit))
                {
                    throw new CorruptIndexException(new WrongFileVersionException(_filename, header.Version, Version));
                }
                _version = header.Version;

                if (_version == PTableVersions.Index32Bit)
                {
                    _indexEntrySize = IndexEntry32Size;
                    _indexKeySize   = IndexKey32Size;
                }
                if (_version == PTableVersions.Index64Bit)
                {
                    _indexEntrySize = IndexEntry64Size;
                    _indexKeySize   = IndexKey64Size;
                }
                _count = ((_size - PTableHeader.Size - MD5Size) / _indexEntrySize);

                if (Count == 0)
                {
                    _minEntry = new IndexEntryKey(ulong.MaxValue, int.MaxValue);
                    _maxEntry = new IndexEntryKey(ulong.MinValue, int.MinValue);
                }
                else
                {
                    var minEntry = ReadEntry(_indexEntrySize, Count - 1, readerWorkItem, _version);
                    _minEntry = new IndexEntryKey(minEntry.Stream, minEntry.Version);
                    var maxEntry = ReadEntry(_indexEntrySize, 0, readerWorkItem, _version);
                    _maxEntry = new IndexEntryKey(maxEntry.Stream, maxEntry.Version);
                }
            }
            catch (Exception)
            {
                Dispose();
                throw;
            }
            finally
            {
                ReturnWorkItem(readerWorkItem);
            }
            int calcdepth = 0;

            try
            {
                calcdepth  = GetDepth(_size, depth);
                _midpoints = CacheMidpointsAndVerifyHash(calcdepth);
            }
            catch (PossibleToHandleOutOfMemoryException)
            {
                Log.Error("Unable to create midpoints for PTable '{0}' ({1} entries, depth {2} requested). "
                          + "Performance hit will occur. OOM Exception.", Path.GetFileName(Filename), Count, depth);
            }
            Log.Trace("Loading PTable (Version: {0}) '{1}' ({2} entries, cache depth {3}) done in {4}.",
                      _version, Path.GetFileName(Filename), Count, calcdepth, sw.Elapsed);
        }