📄 absbtree.pas
字号:
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 + -