Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 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();
 }
Beispiel #4
0
 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());
 }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
                    }
                }
            }
        }
Beispiel #8
0
 private bool CanJoinNodes(ExternalTrieNode node, int recordsInBlock)
 {
     return(node.HasExternalBrother && (recordsInBlock + node.ExternalBrother.RecordCount) <= MaxRecords);
 }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }