private InternalTrieNode TransformExternal(ExternalTrieNode node) { var inter = new InternalTrieNode { Parent = node.Parent }; if (node.InternalParent?.LeftChild == node) { node.InternalParent.LeftChild = inter; } else { if (node.InternalParent != null) { node.InternalParent.RightChild = inter; } } if (node == Root) { Root = inter; } inter.LeftChild = new ExternalTrieNode(); inter.RightChild = new ExternalTrieNode(); return(inter); }
private bool PutRecordInCorrectBlock(ExternalTrieNode leftExternal, ExternalTrieNode rightExternal, T rec) { var bArray = new BitArray(new int[1] { rec.GetHashCode() }); bool result; if (_currentDepth == bArray.Length) { return(false); } if (bArray[_currentDepth]) { result = _rightWorkingBlock.AddRecord(rec); if (result && rightExternal != null) { rightExternal.RecordCount++; } } else { result = _leftWorkingBlock.AddRecord(rec); if (result && leftExternal != null) { leftExternal.RecordCount++; } } return(result); }
public void Clear() { Root = new ExternalTrieNode(); _workingBlock1 = new Block <T>(MaxRecords); _overflowBlock = new Block <T>(MaxRecordsInOverflow); _freeBlocks.Clear(); _freeBlocksOverflow.Clear(); _blockFile.ResetFile(); _overflowFile.ResetFile(); ResetFileDataSize(); }
public DynHash(FilePaths files, int maxRecords, int maxRecordsInOverflow) { Root = new ExternalTrieNode(); _files = files; MaxRecords = maxRecords; MaxRecordsInOverflow = maxRecordsInOverflow; _overflowBlock = new Block <T>(maxRecordsInOverflow); _workingBlock1 = new Block <T>(maxRecords); _freeBlocks = new List <int>(); _freeBlocksOverflow = new List <int>(); _blockFile = new BinaryFileManager(_files.FileBlockData, _workingBlock1.GetSize()); _overflowFile = new BinaryFileManager(_files.FileOverflowFile, _overflowBlock.GetSize()); }
private void DoJoinNodes(ExternalTrieNode node) { while (CanJoinNodes(node, _workingBlock1.ValidCount)) { if (node.IndexOfBlock > -1) { _freeBlocks.Add(node.IndexOfBlock); } if (node.ExternalBrother.IndexOfBlock > -1) { _freeBlocks.Add(node.ExternalBrother.IndexOfBlock); } if (node.ExternalBrother.RecordCount > 0) //len ak ma load zmysel { _leftWorkingBlock = new Block <T>(MaxRecords); _leftWorkingBlock.FromByteArray(_blockFile.ReadData(node.ExternalBrother.IndexOfBlock)); AddBlockData(_leftWorkingBlock, _workingBlock1); } node = TransformInternal(node.InternalParent); } if (_workingBlock1.ValidCount > 0) { if (node.IndexOfBlock == -1) { node.IndexOfBlock = WriteNewBlockAndGetIndex(_workingBlock1); } else { _blockFile.WriteData(node.IndexOfBlock, _workingBlock1.ToByteArray()); } } else { _freeBlocks.Add(node.IndexOfBlock); node.IndexOfBlock = -1; } node.RecordCount = _workingBlock1.ValidCount; AdjustFile(); }
private ExternalTrieNode TransformInternal(InternalTrieNode internalTrieNode) { var ext = new ExternalTrieNode(); if (internalTrieNode == Root) { Root = ext; } else { if (internalTrieNode.InternalParent.LeftChild == internalTrieNode) { internalTrieNode.InternalParent.LeftChild = ext; } else { internalTrieNode.InternalParent.RightChild = ext; } ext.Parent = internalTrieNode.Parent; } return(ext); }
public void LoadTreeData() { var list = new List <string>(); try { using (StreamReader sr = new StreamReader(_files.FileTreeData)) { string line; while ((line = sr.ReadLine()) != null) { list.Add(line); } } } catch (Exception) { return; } if (list.Count == 0) //nic v subore nie je { return; } Root = null; MaxRecords = Int32.Parse(list[0]); MaxRecordsInOverflow = Int32.Parse(list[1]); _workingBlock1 = new Block <T>(MaxRecords); _overflowBlock = new Block <T>(MaxRecordsInOverflow); if (list[2] != "") { _freeBlocks.StringToList(';', list[2]); } if (list[3] != "") { _freeBlocksOverflow.StringToList(';', list[3]); } var stack = new Stack <InternalTrieNode>(); for (int i = 4; i < list.Count; i++) { if (list[i][0] == 'I') { var iNode = new InternalTrieNode(); if (Root == null) { Root = iNode; } else { CorrectInsertToTree(stack, iNode); } stack.Push(iNode); } else { var eNode = new ExternalTrieNode(); eNode.LoadDataFromString(list[i]); if (Root == null) { Root = eNode; } else { CorrectInsertToTree(stack, eNode); } } } }
private bool CanJoinNodes(ExternalTrieNode node, int recordsInBlock) { return(node.HasExternalBrother && (recordsInBlock + node.ExternalBrother.RecordCount) <= MaxRecords); }
private bool TryRemoveOverflow(ExternalTrieNode node, T record, out T removedRecord, out bool canDoJoin) { //najskor pozriet do seba ci nemam node //ak nie //nacitat vsetky ostatne (ak mam) //najst a vymazat //skusit utriast removedRecord = default(T); canDoJoin = false; _workingBlock1 = new Block <T>(MaxRecords); _workingBlock1.FromByteArray(_blockFile.ReadData(node.IndexOfBlock)); var listOverflowBlocks = new List <Block <T> >(); var index = _workingBlock1.NextOverflowBlockIndex; if (index == -1) { throw new Exception($"This should not happened, index of block: {node.IndexOfBlock} and should NOT be -1"); } while (index != -1) //nacitam vsetky preplnene { listOverflowBlocks.Add(new Block <T>(MaxRecordsInOverflow)); listOverflowBlocks[listOverflowBlocks.Count - 1].FromByteArray(_overflowFile.ReadData(index)); index = listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex; } var currentCount = node.RecordCount; if (_workingBlock1.TryRemoveRecord(record, out removedRecord)) { node.RecordCount--; } else { foreach (var block in listOverflowBlocks) { if (block.TryRemoveRecord(record, out removedRecord)) { node.RecordCount--; break; } } } if (currentCount == node.RecordCount) { return(false); //nepodarilo sa vymazat } if ((MaxRecords + listOverflowBlocks.Count * MaxRecordsInOverflow) - node.RecordCount == MaxRecordsInOverflow) { //ideme utriasat var lastBlock = listOverflowBlocks[listOverflowBlocks.Count - 1]; listOverflowBlocks.RemoveAt(listOverflowBlocks.Count - 1); if (listOverflowBlocks.Count > 0) { _freeBlocksOverflow.Add(listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex); listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex = -1; } else { _freeBlocksOverflow.Add(_workingBlock1.NextOverflowBlockIndex); _workingBlock1.NextOverflowBlockIndex = -1; } _overflowFile.AdjustFileSize(_freeBlocksOverflow); var helpCounter = 0; foreach (var rec in lastBlock.GetAllRecords()) { if (_workingBlock1.AddRecord(rec)) { helpCounter++; continue; } foreach (var blockInList in listOverflowBlocks) { if (blockInList.AddRecord(rec)) { helpCounter++; break; } } } if (helpCounter != lastBlock.ValidCount) { throw new Exception($"This should not happened, not all blocks were added"); } //mame utrasene mozme zapisat } for (int i = listOverflowBlocks.Count - 1; i > 0; i--) { _overflowFile.WriteData(listOverflowBlocks[i - 1].NextOverflowBlockIndex, listOverflowBlocks[i].ToByteArray()); //kazdeho zapisem podla indexu predchadzajuceho (az na prveho) } if (listOverflowBlocks.Count > 0) { _overflowFile.WriteData(_workingBlock1.NextOverflowBlockIndex, listOverflowBlocks[0].ToByteArray()); } canDoJoin = CanJoinNodes(node, node.RecordCount); if (!canDoJoin) //zapisem povodny blok len ak uz sa nejde s nim hybat { _blockFile.WriteData(node.IndexOfBlock, _workingBlock1.ToByteArray()); } if (node.RecordCount < MaxRecords) { throw new Exception($"This should not happened, record count < _maxrecords during overflow deleting"); } return(true); }
private bool AddOverflow(ExternalTrieNode node, T record, Block <T> workingBlock = null) { if (workingBlock == null) { if (node.IndexOfBlock == -1) { throw new Exception($"This should not happened, index of block: {node.IndexOfBlock} and should not be"); } if (node.RecordCount < MaxRecords) { throw new Exception($"This should not happened nodeRecords vs maxRecords {node.RecordCount} < {MaxRecords}"); } //nacitaj podla indexu blok, //skus vlozit do bloku //ak nie //kym ma blok adresu na dalsieho, nacitavaj do listu //postupne nacitavaj blok kym sa nenajde taky kde sa zaznam zmesti //ak sa nikde nezmesti, vytvor novy pozri free bloky inak na koniec //record count ++ _workingBlock1 = new Block <T>(MaxRecords); _workingBlock1.FromByteArray(_blockFile.ReadData(node.IndexOfBlock)); if (_workingBlock1.TryFindRecord(record, out var data)) //ak tam uz existuje { return(false); } if (_workingBlock1.NextOverflowBlockIndex == -1) //ak zatial nebol preplneny { if (_workingBlock1.AddRecord(record)) //ak ho pridame do povodneho tak len zapiseme a koniec, netreba kontrolu lebo nema preplnovacie, i ked myslim ze to ani nenastane { node.RecordCount++; _blockFile.WriteData(node.IndexOfBlock, _workingBlock1.ToByteArray()); return(true); } _overflowBlock = new Block <T>(MaxRecordsInOverflow); _overflowBlock.AddRecord(record); node.RecordCount++; if (_freeBlocksOverflow.Count == 0) { var index = _freeBlocksOverflow.Min(i => i); _freeBlocksOverflow.Remove(index); _overflowFile.WriteData(index, _overflowBlock.ToByteArray()); //zapisem preplneny a nastavim index _workingBlock1.NextOverflowBlockIndex = index; } else { _workingBlock1.NextOverflowBlockIndex = _overflowFile.WriteData(_overflowBlock.ToByteArray()); } } else //ak uz bol preplneny { var listOverflowBlocks = new List <Block <T> >(); var index = _workingBlock1.NextOverflowBlockIndex; while (index != -1) { listOverflowBlocks.Add(new Block <T>(MaxRecordsInOverflow)); listOverflowBlocks[listOverflowBlocks.Count - 1].FromByteArray(_overflowFile.ReadData(index)); index = listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex; } //to ci uz existuje v normalnom bloku sa overilo hore foreach (var ofBlock in listOverflowBlocks) //overit ci niekde uz nie je v preplnovacke { if (ofBlock.TryFindRecord(record, out var dataRec)) { return(false); //v nejakom z nich uz existuje } } if (node.RecordCount - MaxRecords < listOverflowBlocks.Count * MaxRecordsInOverflow) //niekde sa zmestia { if (!_workingBlock1.AddRecord(record)) //ak sa nezmesti do normalneho skus do ostatnych { foreach (var ofBlock in listOverflowBlocks) //prechadzat a naplnat { if (ofBlock.AddRecord(record)) { break; } } } } else //nikde sa nezmestia - vytvorit novy { _overflowBlock = new Block <T>(MaxRecordsInOverflow); _overflowBlock.AddRecord(record); if (_freeBlocksOverflow.Count > 0) { index = _freeBlocksOverflow.Min(i => i); _freeBlocksOverflow.Remove(index); _overflowFile.WriteData(index, _overflowBlock.ToByteArray()); } else { index = _overflowFile.WriteData(_overflowBlock.ToByteArray()); } if (listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex != -1) { throw new Exception($"This should not happened, index of block: {node.IndexOfBlock} and should be -1"); } listOverflowBlocks[listOverflowBlocks.Count - 1].NextOverflowBlockIndex = index; } node.RecordCount++; for (int i = listOverflowBlocks.Count - 1; i > 0; i--) { _overflowFile.WriteData(listOverflowBlocks[i - 1].NextOverflowBlockIndex, listOverflowBlocks[i].ToByteArray()); //kazdeho zapisem podla indexu predchadzajuceho (az na prveho) } _overflowFile.WriteData(_workingBlock1.NextOverflowBlockIndex, listOverflowBlocks[0].ToByteArray()); } _blockFile.WriteData(node.IndexOfBlock, _workingBlock1.ToByteArray()); //zapisem povodny blok } else { if (node.IndexOfBlock != -1) { throw new Exception($"This should not happened, index of block: {node.IndexOfBlock} and should be -1"); } //zapis nodu novy working blok a daj mu adresu na prvy preplnovak kde pojde record //record count ++; if (workingBlock.TryFindRecord(record, out var dataRec)) { throw new Exception($"This should not happened, block already contains record"); } _overflowBlock = new Block <T>(MaxRecordsInOverflow); _overflowBlock.AddRecord(record); var index = -1; if (_freeBlocksOverflow.Count > 0) { index = _freeBlocksOverflow.Min(i => i); _freeBlocksOverflow.Remove(index); _overflowFile.WriteData(index, _overflowBlock.ToByteArray()); } else { index = _overflowFile.WriteData(_overflowBlock.ToByteArray()); } if (index == -1) { throw new Exception($"This should not happened, index of block: {node.IndexOfBlock} and should NOT be -1"); } workingBlock.NextOverflowBlockIndex = index; node.IndexOfBlock = WriteNewBlockAndGetIndex(workingBlock); node.RecordCount++; } return(true); }