Скачать Модуль поддержки Clipper-ных индексов .NTX

23.01.1998
Скачать файл (2,59 Кб)




unit NTX;

interface

Type NTX_Node = array[0..511] of word;

   NTX_Head = Record
                     Sign        : Word;
                     Version     : Word;
                     Root        : Longint;
                     Next_Blk    : Longint;
                     Item_Size   : Word;
                     Key_Lgth    : Word;
                     Key_Dec     : Word;
                     Max_Keys    : word;
                     HalfPage    : word;
                     Key_Form    : array [0..255] of char;
                     Unique      : boolean;
                     Ignored     : array[1..746] of byte;
                  end;


            TNTX = object
                    NTX_Name     : String[64];
                    NTX_Hdr      : NTX_Head;
                    NTX_File     : file;
                    NodeRec      : Ntx_Node;
                    NodeOfs      : longInt;
                    L,R, ItemNo  : word;

                    Constructor Init(IName : String);
                    FUNCTION    KeyFind(st : String) : longint;
                    Function    KeyNext(Var Key : string) : longInt;
                    Destructor  Done;
                 end;

implementation

  function CharStr(Ch : Char; Len : Byte) : string;
    {-Return a string of length len filled with ch}
  var
    S : string;
  begin
    if Len = 0 then
      CharStr[0] := #0
    else begin
      S[0] := Chr(Len);
      FillChar(S[1], Len, Ch);
      CharStr := S;
    end;
  end;

Constructor TNTX.Init(IName : String);
var
   ct : word;
begin
   NTX_Name := IName;
   assign(NTX_File,NTX_Name);
   reset(NTX_File,1);
   BlockRead(NTX_File,NTX_Hdr,1024,ct);
end;

Destructor TNTX.Done;
begin
  Close(NTX_File);
end;

FUNCTION    TNTX.KeyFind(st : String) : longint;
var
  Position : Word;


Function GetKey(Item : word) : string;
Var
  tempSt   : string;
begin
   TempSt := CharStr(' ',NTX_Hdr.Key_Lgth);
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)+4],TempSt[1],NTX_Hdr.Key_Lgth);
   GetKey := TempSt;

end;

Function GetRecNo(Item : word) : longInt;
var
  I : LongInt;
begin
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)+2],I,4);
   GetRecNo := I;
end;

Function GetNodeOfs(Item : Word) : longint;
var
  I : LongInt;
begin
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)],I,4);
   GetNodeOfs := I;
end;

begin
  KeyFind := 0;
  NodeOfs := NTX_Hdr.Root;
  While NodeOfs > 0 do
    begin
      Seek(NTX_File,NodeOfs);
      BlockRead(NTX_File,NodeRec,1024);
      if NodeRec[0] > 0 then
        begin
          L := 1;
          R := NodeRec[0];
      repeat
        if Ntx_hdr.Unique then
          ItemNo := (L+R) shr 1
        else
          ItemNo := L;
        if St = GetKey(ItemNo) then
          begin
            if Ntx_Hdr.Unique then
              begin
                KeyFind := GetRecNo(ItemNo);
                Exit;
              end
               else
                begin
                  if GetNodeOfs(ItemNo) > 0 then
                    break
                      else
                        begin
                          KeyFind := GetRecNo(ItemNo);
                          Exit;
                        end;
               end
          end
           else
             if St < GetKey(ItemNo) then
              R := Pred(ItemNo)
               else
                L := Succ(ItemNo)
       until R < L;

       NodeOfs := GetNodeOfs(ItemNo);
      end
      else
        NodeOfs := 0;
     end;
end;


Function  Tntx.KeyNext(Var Key : string) : longInt;

var
  Position : Word;


Function GetKey(Item : word) : string;
Var
  tempSt   : string;
begin
   TempSt := CharStr(' ',NTX_Hdr.Key_Lgth);
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)+4],TempSt[1],NTX_Hdr.Key_Lgth);
   GetKey := TempSt;

end;

Function GetRecNo(Item : word) : longInt;
var
  I : LongInt;
begin
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)+2],I,4);
   GetRecNo := I;
end;

Function GetNodeOfs(Item : Word) : longint;
var
  I : LongInt;
begin
   Position := NodeRec[Item];
   Move(NodeRec[Round(Position/2)],I,4);
   GetNodeOfs := I;
end;

begin
  KeyNext := 0;
  if ((NodeOfs = FileSize(Ntx_File) - 1024 ) and (L = NodeRec[0])) then
    Exit;
  if L = NodeRec[0] then
   begin
    repeat
      NodeOfs := NodeOfs + 1024;
      if (NodeOfs > FileSize(Ntx_File) - 1024 )  then
      Exit;
      Seek(NTX_File,NodeOfs);
      BlockRead(NTX_File,NodeRec,1024);
    until NodeRec[0] > 0;
     L := 0;
   end;
   Inc(L);
   ItemNo := L;
   Key := GetKey(ItemNo);
   KeyNext := GetRecNo(ItemNo);
end;


end.