public void Remove(MerkleTreeSection merkleTreeSection) { lock (_lockObject) { _map.Remove(merkleTreeSection); } }
public void Add(MerkleTreeSection merkleTreeSection) { lock (_lockObject) { _map[merkleTreeSection] = new MerkleTreeSectionManager(merkleTreeSection); } }
public int GetCount(MerkleTreeSection merkleTreeSection, bool state) { lock (_lockObject) { if (_map.TryGetValue(merkleTreeSection, out var merkleTreeSectionManager)) { return(merkleTreeSectionManager.GetCount(state)); } else { if (state) { return(0); } else { return(merkleTreeSection.Hashes.Count); } } } }
public IEnumerable <OmniHash> GetOmniHashes(MerkleTreeSection merkleTreeSection, bool state) { lock (_lockObject) { if (_map.TryGetValue(merkleTreeSection, out var merkleTreeSectionManager)) { return(merkleTreeSectionManager.GetHashes(state)); } else { if (state) { return(Enumerable.Empty <OmniHash>()); } else { return(merkleTreeSection.Hashes); } } } }
public MerkleTreeSectionManager(MerkleTreeSection merkleTreeSection) { _bloomFilter = new BloomFilter <OmniHash>(256, 0.001, (n) => n.GetHashCode()); _dic = new Dictionary <OmniHash, State>(); foreach (var key in merkleTreeSection.Hashes) { _bloomFilter.Add(key); State info; if (!_dic.TryGetValue(key, out info)) { info = new State(); info.IsEnabled = false; info.Count = 0; _dic.Add(key, info); } info.Count++; } }
public async ValueTask <OmniHash[]> ParityDecode(MerkleTreeSection merkleTreeSection, CancellationToken token = default) { return(await Task.Run(async() => { if (merkleTreeSection.CorrectionAlgorithmType == CorrectionAlgorithmType.ReedSolomon8) { // 実ブロック数 int informationCount = merkleTreeSection.Hashes.Count - 128; // デコード可能かチェックする if (merkleTreeSection.Hashes.Count(n => this.Contains(n)) < informationCount) { throw new ParityDecodeFailed(); } // デコードする必要がない場合 if (merkleTreeSection.Hashes.Take(informationCount).All(n => this.Contains(n))) { return merkleTreeSection.Hashes.Take(informationCount).ToArray(); } // 最大ブロック長 uint blockLength = merkleTreeSection.Hashes.Max(n => this.GetLength(n)); var memoryOwners = new List <IMemoryOwner <byte> >(); try { var targetBuffers = new Memory <byte> [128]; var indexes = new int[128]; // Load { int count = 0; int index = 0; int position = 0; for (; index < informationCount && count < informationCount; index++, position++) { token.ThrowIfCancellationRequested(); if (!this.TryGetBlock(merkleTreeSection.Hashes[position], out var blockMemoryOwner)) { continue; } // 実ブロックの長さが足りない場合、0byteでpaddingを行う if (blockMemoryOwner.Memory.Length < blockLength) { var tempMemoryOwner = _bufferPool.Rent((int)blockLength); BytesOperations.Copy(blockMemoryOwner.Memory.Span, tempMemoryOwner.Memory.Span, blockMemoryOwner.Memory.Length); BytesOperations.Zero(tempMemoryOwner.Memory.Span.Slice(blockMemoryOwner.Memory.Length)); blockMemoryOwner.Dispose(); blockMemoryOwner = tempMemoryOwner; } memoryOwners.Add(blockMemoryOwner); indexes[count] = index; targetBuffers[count] = blockMemoryOwner.Memory; count++; } // 実ブロック数が128に満たない場合、0byte配列でPaddingを行う。 for (; index < 128 && count < informationCount; index++) { token.ThrowIfCancellationRequested(); var tempMemoryOwner = _bufferPool.Rent((int)blockLength); BytesOperations.Zero(tempMemoryOwner.Memory.Span); memoryOwners.Add(tempMemoryOwner); indexes[count] = index; targetBuffers[count] = tempMemoryOwner.Memory; count++; } for (; index < 256 && count < informationCount; index++, position++) { token.ThrowIfCancellationRequested(); if (!this.TryGetBlock(merkleTreeSection.Hashes[position], out var blockMemoryOwner)) { continue; } memoryOwners.Add(blockMemoryOwner); indexes[count] = index; targetBuffers[count] = blockMemoryOwner.Memory; count++; } if (count < informationCount) { throw new BlockNotFoundException(); } } var reedSolomon = new ReedSolomon8(informationCount, _threadCount, _bufferPool); await reedSolomon.Decode(targetBuffers, indexes, (int)blockLength, informationCount * 2, token); // Set { ulong length = merkleTreeSection.Length; for (int i = 0; i < informationCount; length -= blockLength, i++) { bool result = _blockStorage.TrySet(merkleTreeSection.Hashes[i], memoryOwners[i].Memory.Span.Slice(0, (int)Math.Min(length, blockLength))); if (!result) { throw new ParityDecodeFailed("Failed to save Block."); } } } } finally { foreach (var memoryOwner in memoryOwners) { memoryOwner.Dispose(); } } return merkleTreeSection.Hashes.Take(informationCount).ToArray(); } else { throw new NotSupportedException(); } })); }