Информационный сервер для программистов: Исходники со всего света. Паскальные исходники со всего света
  Powered by Поисковый сервер Яndex: Найдется ВСЁ!
На Главную Pascal Форум Информер Страны мира
   Базы Данных    >>    ntx
   
 
 Модуль поддержки Clipper-ных индексов .NTX   Sergey Perevoznik 23.01.1998

NTX.PAS - это интерфейс к Clipper-овским индексам. Библиотек для работы с DBF-файлами хватает, а вот индексы...



2k 
 

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.