public void Add(string key, IndexData indexData)
        {
            if (Contains(key))
            {
                throw new DuplicateException(nameof(key));
            }

            NewNode(key, indexData);
        }
        //generates new node on the stream and adds this into rootNode.
        private void NewNode(string key, IndexData indexData)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (indexData == null)
            {
                throw new ArgumentNullException(nameof(indexData));
            }

            CheckDisposed();

            var keyBuffer = Encoding.UTF8.GetBytes(key);

            var newNodeSize = DefaultSizes.DefaultNodeSize + keyBuffer.Length;

            EnsureCapacity(_indexCursor, newNodeSize);

            using (var writer = _indexFile.CreateViewStream(_indexCursor, newNodeSize, MemoryMappedFileAccess.Write))
            {
                var keyOffset = _indexCursor + DefaultSizes.DefaultNodeSize;

                writer.WriteLong(keyOffset);                  // keyOffset
                writer.WriteInt(keyBuffer.Length);            //keySize
                WriteIndexData(writer, indexData);            //indexData
                writer.Write(keyBuffer, 0, keyBuffer.Length); //key itself

                _indexCursor += writer.Position;

                var keyInfo = new KeyInfo
                {
                    Key    = key,
                    Offset = keyOffset,
                    Size   = keyBuffer.Length
                };

                var node = new Node()
                {
                    KeyInfo   = keyInfo,
                    IndexData = indexData,
                };

                //since we have to check if key exist before add new node, this approach accelerate check speed
                _rootNode.Nodes.Add(key, node);
            }

            Commit();
        }
        private IndexData ReadIndexData(KeyInfo keyInfo)
        {
            var offset = keyInfo.Offset - DefaultSizes.IndexDataSize; // Index data is stored before key

            using (var reader = _indexFile.CreateViewStream(offset, DefaultSizes.IndexDataSize, MemoryMappedFileAccess.Read))
            {
                var indexData = new IndexData
                {
                    Md5Hash = new byte[DefaultSizes.Md5HashSize],
                    Size    = reader.ReadLong(),
                    Offset  = reader.ReadLong()
                };
                reader.Read(indexData.Md5Hash, 0, DefaultSizes.Md5HashSize);

                return(indexData);
            }
        }
Beispiel #4
0
 public void Add(string key, IndexData indexData)
 {
     WriteLock(() => _index.Add(key, indexData), $"Timeout {_timeout} expired to add key {key} to index");
 }
 private static void WriteIndexData(Stream writer, IndexData data)
 {
     writer.WriteLong(data.Size);
     writer.WriteLong(data.Offset);
     writer.Write(data.Md5Hash, 0, DefaultSizes.Md5HashSize);
 }