⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 absbtree.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
     ApproxRecCount := Items[i].EntryCount * ApproxRecCount;
   end;
  Result := ApproxRecNo / ApproxRecCount;
end;// GetApproxRecNoInPercents


//------------------------------------------------------------------------------
// GetBitmapRecNoByIndexPosition
//------------------------------------------------------------------------------
function TABSKeyPath.GetBitmapRecNoByIndexPosition(MaxEntriesPerPage: Integer): TABSRecordNo;
var
  i: Integer;
begin
  Result := 0;
  Inc(MaxEntriesPerPage);
  // encode IndexPos to RecNo
  for i := Count-1 downto 0 do
    Result := Result + (Items[(Count-1)-i].EntryNo+1) * Round(Power(MaxEntriesPerPage, i));
end;// GetBitmapRecNoByIndexPosition


//------------------------------------------------------------------------------
// FillItemsByBitmapRecNo
//------------------------------------------------------------------------------
procedure TABSKeyPath.FillItemsByBitmapRecNo(RecordNo, MaxEntriesPerPage: Integer);
var
  i, rn: Integer;
begin
  Clear;
  Inc(MaxEntriesPerPage);
  // calc count
  rn := RecordNo;
  Count := 0;
  while (rn > 0) do
    begin
      Inc(Count);
      rn := rn div MaxEntriesPerPage;
    end;
  // decode RecordNo to IndexPos
  i := 0;
  repeat
    inc(i);
    Items[Count-i].EntryNo := (RecordNo mod MaxEntriesPerPage)-1;
    Items[Count-i].PageNo := INVALID_PAGE_NO;
    Items[Count-i].EntryCount := 0;
    RecordNo := RecordNo div MaxEntriesPerPage;
  until (RecordNo = 0);
end;// FillItemsByBitmapRecNo


////////////////////////////////////////////////////////////////////////////////
//
// TABSBTreeKeyRef
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// get count of key parts
//------------------------------------------------------------------------------
function TABSBTreeKeyRef.GetPartCount: Integer;
begin
  Result := Length(Parts);
end;// GetPartCount


//------------------------------------------------------------------------------
// set size of array
//------------------------------------------------------------------------------
procedure TABSBTreeKeyRef.SetPartCount(Value: Integer);
begin
  SetLength(Parts, Value);
end;// SetPartCount


//------------------------------------------------------------------------------
// allocate buffer for short key
//------------------------------------------------------------------------------
function TABSBTreeKeyRef.AllocShortKeyBuffer: PChar;
begin
  Result := MemoryManager.AllocMem(FShortKeySize);
end;// AllocShortKeyBuffer


//------------------------------------------------------------------------------
// allocate buffer for full key
//------------------------------------------------------------------------------
function TABSBTreeKeyRef.AllocFullKeyBuffer: PChar;
begin
  Result := MemoryManager.AllocMem(FFullKeySize);
end;// AllocFullKeyBuffer


//------------------------------------------------------------------------------
// free key buffer
//------------------------------------------------------------------------------
procedure TABSBTreeKeyRef.FreeAndNilKeyBuffer(var Buffer: PChar);
begin
  MemoryManager.FreeAndNillMem(Buffer);
end;// FreeAndNilKeyBuffer


//------------------------------------------------------------------------------
// CompareReferences
//------------------------------------------------------------------------------
function TABSBTreeKeyRef.CompareReferences(Reference1, Reference2: PChar; Size: Integer): Integer;
var
  i: Integer;
begin
  Result := 0;
  if (Size = sizeof(TABSRecordID)) then
    begin
      if (PABSRecordID(Reference1)^.PageNo < PABSRecordID(Reference2)^.PageNo) then
        Result := -1
      else
       if (PABSRecordID(Reference1)^.PageNo > PABSRecordID(Reference2)^.PageNo) then
         Result := 1
       else
         if (PABSRecordID(Reference1)^.PageItemNo < PABSRecordID(Reference2)^.PageItemNo) then
           Result := -1
         else
           if (PABSRecordID(Reference1)^.PageItemNo > PABSRecordID(Reference2)^.PageItemNo) then
             Result := 1
           else
             Result := 0;
    end
  else
    for i := 0 to Size-1 do
     if ((Reference1+i)^ < (Reference2+i)^) then
      begin
       Result := -1;
       break;
      end
     else
     if ((Reference1+i)^ > (Reference2+i)^) then
      begin
       Result := 1;
       break;
      end
end;// CompareReferences


////////////////////////////////////////////////////////////////////////////////
//
// TABSRecordKeyRef
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// RetrieveFullKeyByRecordID
//------------------------------------------------------------------------------
procedure TABSRecordKeyRef.RetrieveFullKeyByRecordID(RecordID: TABSRecordID; FullKey: PChar;
                                         SessionID: TABSSessionID);
var
  NavigationInfo: TABSNavigationInfo;
begin
  NavigationInfo.GetRecordMode := grmCurrent;
  NavigationInfo.RecordID := RecordID;
  NavigationInfo.FirstPosition := False;
  NavigationInfo.LastPosition := False;
  NavigationInfo.RecordBuffer := MemoryManager.AllocMem(
     TABSTableData(LTableData).FieldManager.FieldDefs.GetMemoryRecordBufferSize);
  try
    TABSTableData(LTableData).RecordManager.GetRecordBuffer(SessionID, NavigationInfo);
    if (NavigationInfo.GetRecordResult <> grrOK) then
      raise EABSException.Create(20170, ErrorACannotRetreiveRecord);
    // make full key from fetched record buffer
    MakeFullKeyFromRecordBuffer(NavigationInfo.RecordBuffer, FullKey);
  finally
    MemoryManager.FreeAndNillMem(NavigationInfo.RecordBuffer);
  end;
end;// RetrieveFullKeyByRecordID


//------------------------------------------------------------------------------
// SetPartCount
//------------------------------------------------------------------------------
procedure TABSRecordKeyRef.SetPartCount(Value: Integer);
var
  i: Integer;
begin
  inherited SetPartCount(Value);
  SetLength(FCompareLengths, PartCount);
  for i:=0 to Length(FCompareLengths)-1 do
    FCompareLengths[i] := -1;
end;// SetPartCount


//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
constructor TABSRecordKeyRef.Create;
begin
  PartCount := 0;
  FShortKeySize := 0;
  FFullKeySize := 0;
  FKeyIsReference := False;
  FReferenceSize := 0;
  FCompareFieldCount := 0;
  LTableData := nil;
  LRecordBuffer := nil;
end;// Create


//------------------------------------------------------------------------------
// assign IndexDef
//------------------------------------------------------------------------------
procedure TABSRecordKeyRef.Assign(IndexDef: TABSIndexDef; aTableData: Pointer);
var
  i: Integer;
  OffsetInShortKeyBuffer: Integer;
  OffsetInFullKeyBuffer: Integer;
  TableData: TABSTableData;
  FieldDef: TABSFieldDef;
begin
  LTableData := aTableData;
  TableData := TABSTableData(LTableData);
  PartCount := IndexDef.ColumnCount;
  FCompareFieldCount := PartCount;
  OffsetInShortKeyBuffer := 0;
  OffsetInFullKeyBuffer := 0;
  FShortKeySize := 0;
  FFullKeySize := 0;
  if (TableData.FieldManager = nil) then
    raise EABSException.Create(20044, ErrorANilPointer);
  if (TableData.FieldManager.FieldDefs = nil) then
    raise EABSException.Create(20045, ErrorANilPointer);
  for i := 0 to IndexDef.ColumnCount-1 do
   begin
    Parts[i].OffsetInShortKeyBuffer := OffsetInShortKeyBuffer;
    Parts[i].OffsetInFullKeyBuffer := OffsetInFullKeyBuffer;
    FieldDef := TableData.FieldManager.FieldDefs.GetFieldDefByName(
                                                 IndexDef.Columns[i].FieldName);
    if (FieldDef = nil) then
     raise EABSException.Create(20043, ErrorACannotFindIndexField,
                                [IndexDef.Columns[i].FieldName]);

    if (IsBLOBFieldType(FieldDef.BaseFieldType)) then
     raise EABSException.Create(20295, ErrorACannotIndexBlobField,
                                [IndexDef.Columns[i].FieldName]);
    Parts[i].OffsetInRecordBuffer := FieldDef.MemoryOffset;
    Parts[i].FieldNo := TableData.FieldManager.FieldDefs.GetDefNumberByName(
          IndexDef.Columns[i].FieldName);

    Parts[i].AddedSize := 0;
    // short index
    if (IndexDef.Columns[i].MaxIndexedSize < FieldDef.MemoryDataSize) then
      begin
        Parts[i].AddedSize := 2;
        Parts[i].ShortSize := IndexDef.Columns[i].MaxIndexedSize+2+BTreeNullFlagSize;
      end
    else
      Parts[i].ShortSize := FieldDef.MemoryDataSize+BTreeNullFlagSize;
    OffsetInShortKeyBuffer := OffsetInShortKeyBuffer + Parts[i].ShortSize;
    FShortKeySize := FShortKeySize + Parts[i].ShortSize;

    // full index
    Parts[i].FullSize := FieldDef.MemoryDataSize+BTreeNullFlagSize;
    OffsetInFullKeyBuffer := OffsetInFullKeyBuffer + Parts[i].FullSize;
    FFullKeySize := FFullKeySize + Parts[i].FullSize;

    Parts[i].DataType := FieldDef.BaseFieldType;
    Parts[i].Descending := IndexDef.Columns[i].Descending;
    Parts[i].CaseInsensitive := IndexDef.Columns[i].CaseInsensitive;
   end;
end;// Assign


//------------------------------------------------------------------------------
// MakeShortKeyFromRecordBuffer
//------------------------------------------------------------------------------
procedure TABSRecordKeyRef.MakeShortKeyFromRecordBuffer(RecordBuffer: PChar; KeyBuffer: PChar);
var
  i: Integer;
begin
  LRecordBuffer := RecordBuffer;
  for i := 0 to PartCount-1 do
   begin
    if (CheckNullFlag(Parts[i].FieldNo, RecordBuffer)) then
     (KeyBuffer+Parts[i].OffsetInShortKeyBuffer)^ := BTreeKeyIsNull
    else
     begin
      (KeyBuffer+Parts[i].OffsetInShortKeyBuffer)^ := BTreeKeyIsNotNull;
      Move((RecordBuffer+Parts[i].OffsetInRecordBuffer)^,
           (KeyBuffer+Parts[i].OffsetInShortKeyBuffer+BTreeNullFlagSize)^,
           Parts[i].ShortSize-Parts[i].AddedSize-BTreeNullFlagSize);
     end;
   end;
end;// MakeShortKeyFromRecordBuffer


//------------------------------------------------------------------------------
// MakeFullKeyFromRecordBuffer
//------------------------------------------------------------------------------
procedure TABSRecordKeyRef.MakeFullKeyFromRecordBuffer(RecordBuffer: PChar; KeyBuffer: PChar);
var
  i: Integer;
begin
  for i := 0 to PartCount-1 do
   begin
    if (CheckNullFlag(Parts[i].FieldNo, RecordBuffer)) then
     (KeyBuffer+Parts[i].OffsetInFullKeyBuffer)^ := BTreeKeyIsNull
    else
     begin
      (KeyBuffer+Parts[i].OffsetInFullKeyBuffer)^ := BTreeKeyIsNotNull;
      Move((RecordBuffer+Parts[i].OffsetInRecordBuffer)^,
           (KeyBuffer+Parts[i].OffsetInFullKeyBuffer+BTreeNullFlagSize)^,
           Parts[i].FullSize-BTreeNullFlagSize);
     end;
   end;
end;// MakeFullKeyFromRecordBuffer


//------------------------------------------------------------------------------
// compare two short keys in index order sense
//------------------------------------------------------------------------------
function TABSRecordKeyRef.CompareShortKeys(KeyBuffer1, KeyBuffer2: PChar;
                                           MayUseFullKeys: Boolean=False;
                                           SessionID: TABSSessionID = INVALID_SESSION_ID;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -