public IfpRecord ReadIfpRecord ( long offset ) { IfpRecord result = IfpRecord.Read(Ifp, offset); return(result); }
/// <summary> /// ibatrak чтение заголовка записи IFP (для подсчета количества ссылок) /// </summary> public static IfpRecord ReadLeader ( Stream stream, long offset ) { stream.Position = offset; IfpRecord result = new IfpRecord { LowOffset = stream.ReadInt32Network(), HighOffset = stream.ReadInt32Network(), TotalLinkCount = stream.ReadInt32Network(), BlockLinkCount = stream.ReadInt32Network(), Capacity = stream.ReadInt32Network() }; return(result); }
/// <summary> /// Read the record. /// </summary> public static IfpRecord Read ( [NotNull] Stream stream, long offset ) { stream.Position = offset; IfpRecord result = new IfpRecord { LowOffset = stream.ReadInt32Network(), HighOffset = stream.ReadInt32Network(), TotalLinkCount = stream.ReadInt32Network(), BlockLinkCount = stream.ReadInt32Network(), Capacity = stream.ReadInt32Network() }; // ibatrak чтение вложенных записей в спец блоке // Специальный формат записи .ifp // В этом случае первой записью является специальный блок, // который представляет собой заголовок (обыкновенного формата), // в котором смещения имеют специальные значения = -1001 if (result.LowOffset == -1001 && result.HighOffset == -1001) { // irbis64.dll делает так // читает первые 24 байта блока спец ссылок // (это 2 записи) // записи с реальными адресами идут через одну // берет вторую запись, адрес из нее в файле // и читает записеи IFP // по количеству result.BlockLinkCount // первую запись спец блока просто пропускаем, // читаем сразу вторую stream.Position += 12; SpecialPostingBlockEntry entry = new SpecialPostingBlockEntry { Posting = stream.ReadInt32Network(), Low = stream.ReadInt32Network(), High = stream.ReadInt32Network() }; stream.Position = entry.Offset; IfpRecord[] nestedRecords = new IfpRecord[result.BlockLinkCount]; for (int i = 0; i < result.BlockLinkCount; i++) { var nestedRecord = Read(stream, stream.Position); nestedRecords[i] = nestedRecord; // Last record in the list must have // negative offset values if (nestedRecord.LowOffset == -1 && nestedRecord.HighOffset == -1) { if (i != result.BlockLinkCount - 1) { throw new InvalidOperationException ( "IFP reading error" ); } break; } if (nestedRecord.FullOffset < 0) { throw new InvalidOperationException ( "IFP reading error" ); } stream.Position = nestedRecord.FullOffset; } TermLink[] links = nestedRecords .SelectMany(r => r.Links) .ToArray(); if (links.Length != result.TotalLinkCount) { throw new InvalidOperationException ( "IFP reading error" ); } result.Links.AddRange(links); return(result); } //ibatrak до сюда for (int i = 0; i < result.BlockLinkCount; i++) { TermLink link = TermLink.Read(stream); result.Links.Add(link); } return(result); }
public TermLink[] SearchStart ( [CanBeNull] string key ) { List <TermLink> result = new List <TermLink>(); if (string.IsNullOrEmpty(key)) { return(new TermLink[0]); } key = key.ToUpperInvariant(); NodeRecord firstNode = ReadNode(1); NodeRecord rootNode = ReadNode(firstNode.Leader.Number); NodeRecord currentNode = rootNode; NodeItem goodItem = null; while (true) { bool found = false; bool beyond = false; foreach (NodeItem item in currentNode.Items) { int compareResult = string.CompareOrdinal(item.Text, key); if (compareResult > 0) { beyond = true; break; } goodItem = item; found = true; } if (goodItem == null) { break; } if (found) { if (beyond || (currentNode.Leader.Next == -1)) { if (goodItem.RefersToLeaf) { goto FOUND; } currentNode = ReadNode(goodItem.LowOffset); } else { currentNode = ReadNext(currentNode); } } else { if (goodItem.RefersToLeaf) { goto FOUND; } currentNode = ReadNode(goodItem.LowOffset); } //Console.WriteLine(currentNode); } FOUND: if (goodItem != null) { currentNode = ReadLeaf(goodItem.LowOffset); while (true) { foreach (NodeItem item in currentNode.Items) { int compareResult = string.CompareOrdinal(item.Text, key); if (compareResult >= 0) { bool starts = item.Text.StartsWith(key); if ((compareResult > 0) && !starts) { goto DONE; } if (starts) { IfpRecord ifp = ReadIfpRecord(item.FullOffset); result.AddRange(ifp.Links); } } } if (currentNode.Leader.Next > 0) { currentNode = ReadNext(currentNode); } } } DONE: return(result .Distinct() .ToArray()); }
public TermLink[] SearchExact ( [CanBeNull] string key ) { if (string.IsNullOrEmpty(key)) { return(new TermLink[0]); } key = key.ToUpperInvariant(); NodeRecord firstNode = ReadNode(1); NodeRecord rootNode = ReadNode(firstNode.Leader.Number); NodeRecord currentNode = rootNode; NodeItem goodItem = null; while (true) { bool found = false; bool beyond = false; foreach (NodeItem item in currentNode.Items) { int compareResult = string.CompareOrdinal(item.Text, key); if (compareResult > 0) { beyond = true; break; } goodItem = item; found = true; if ((compareResult == 0) && currentNode.IsLeaf) { goto FOUND; } } if (goodItem == null) { break; } if (found) { if (beyond || (currentNode.Leader.Next == -1)) { currentNode = goodItem.RefersToLeaf ? ReadLeaf(goodItem.LowOffset) : ReadNode(goodItem.LowOffset); } else { currentNode = ReadNext(currentNode); } } else { currentNode = goodItem.RefersToLeaf ? ReadLeaf(goodItem.LowOffset) : ReadNode(goodItem.LowOffset); } //Console.WriteLine(currentNode); } FOUND: if (goodItem != null) { IfpRecord ifp = ReadIfpRecord(goodItem.FullOffset); return(ifp.Links.ToArray()); } return(new TermLink[0]); }
public TermLink[] SearchExact ( [CanBeNull] string key ) { if (string.IsNullOrEmpty(key)) { return(new TermLink[0]); } try { key = key.ToUpperInvariant(); NodeRecord firstNode = ReadNode(1); NodeRecord rootNode = ReadNode(firstNode.Leader.Number); NodeRecord currentNode = rootNode; NodeItem goodItem = null; while (true) { bool found = false; bool beyond = false; foreach (NodeItem item in currentNode.Items) { int compareResult = string.CompareOrdinal(item.Text, key); if (compareResult > 0) { beyond = true; break; } goodItem = item; found = true; if (compareResult == 0 && currentNode.IsLeaf) { goto FOUND; } } if (goodItem == null) { break; } if (found) { if (beyond || currentNode.Leader.Next == -1) { currentNode = goodItem.RefersToLeaf ? ReadLeaf(goodItem.LowOffset) : ReadNode(goodItem.LowOffset); } else { currentNode = ReadNext(currentNode); } } else { currentNode = goodItem.RefersToLeaf ? ReadLeaf(goodItem.LowOffset) : ReadNode(goodItem.LowOffset); } //Console.WriteLine(currentNode); } FOUND: if (goodItem != null) { // ibatrak записи могут иметь ссылки на следующие List <TermLink> result = new List <TermLink>(); long offset = goodItem.FullOffset; while (offset > 0) { IfpRecord ifp = ReadIfpRecord(offset); result.AddRange(ifp.Links); offset = ifp.FullOffset > 0 ? ifp.FullOffset : 0; } return(result .Distinct() .ToArray()); //ibatrak до сюда } } catch (Exception ex) { Debug.WriteLine(ex); } return(new TermLink[0]); }