?? myldbtempengine.pas
字號(hào):
end; // GetRecordMode
end; // GetRecordFromFirstPosition
//------------------------------------------------------------------------------
// return result for attempt of getting record relatively to last position
// and set RecordID to new record ID
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.GetRecordFromLastPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
begin
Result := grrError;
case GetRecordMode of
grmPrior:
begin
RecordID := FRecordCount-1;
Result := grrOK;
end;
grmCurrent:
begin
Result := grrError;
end;
grmNext:
begin
Result := grrEOF;
end;
end; // GetRecordMode
end; // GetRecordFromLastPosition
//------------------------------------------------------------------------------
// return result for attempt of getting record relatively any position
// and set RecordID to new record ID
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.GetRecordFromAnyPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
begin
Result := grrError;
case GetRecordMode of
grmPrior:
begin
Result := grrBOF;
if (RecordID > 0) then
begin
Dec(RecordID);
Result := grrOK;
end; // RecordID > 0
end;
grmCurrent:
begin
if ((RecordID >= FRecordCount) or (RecordID < 0)) then
// current record does not exist
Result := grrError
else
Result := grrOK;
end;
grmNext:
begin
Result := grrEOF;
if (RecordID < FRecordCount-1) then
begin
Inc(RecordID);
Result := grrOK;
end;
end;
end; // GetRecordMode
end; // GetRecordFromAnyPosition
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
constructor TMYLDBTemporaryRecordManager.Create(
RecordBufferSize: Integer;
RecordsPerPage: Integer;
AllocRecordsBy: Integer;
DisableTempFiles: Boolean
);
begin
if (RecordBufferSize = 0) then
raise EMYLDBException.Create(10124,ErrorLInvalidRecordSize);
FRecordCount := 0;
FRecordBufferSize := RecordBufferSize;
FRecordsPerPage := RecordsPerPage;
if (FRecordsPerPage = 0) then
FRecordsPerPage := 1;
FMaxCachedRecordCount := ((MemoryManager.GetFreeMemorySize div 10) div
FRecordBufferSize);
FPageSize := FRecordsPerPage * FRecordBufferSize;
FTempPage := MemoryManager.GetMem(FPageSize);
FTempPageRecordCount := 0;
FCachedRecordCount := 0;
FCache := nil;
FAllocRecordsBy := AllocRecordsBy;
FTempPageFile := nil;
FDisableTempFiles := DisableTempFiles;
end; // Create;
//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TMYLDBTemporaryRecordManager.Destroy;
begin
Empty(SYSTEM_SESSION_ID);
MemoryManager.FreeAndNillMem(FTempPage);
inherited Destroy;
end; // Destroy
//------------------------------------------------------------------------------
// Empty
//------------------------------------------------------------------------------
procedure TMYLDBTemporaryRecordManager.Empty(SessionID: TMYLDBSessionID);
begin
FRecordCount := 0;
FTempPageRecordCount := 0;
if (FCache <> nil) then
MemoryManager.FreeAndNillMem(FCache);
FCachedRecordCount := 0;
FAllocatedRecordCount := 0;
if (FTempPageFile <> nil) then
FreeAndNil(FTempPageFile);
end; // Empty
//------------------------------------------------------------------------------
// add record and return its number
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.AddRecord(
SessionID: TMYLDBSessionID;
RecordBuffer: TMYLDBRecordBuffer;
var RecordID: TMYLDBRecordID
): Boolean;
var SaveToTemp: Boolean;
begin
try
SaveToTemp := False;
if (FCachedRecordCount >= FAllocatedRecordCount) then
begin
// need extending cache or writing to temporary file
if (FDisableTempFiles or (FAllocatedRecordCount < FMaxCachedRecordCount)) then
begin
// create or extend cache
if (FDisableTempFiles) then
Inc(FAllocatedRecordCount,FAllocRecordsBy)
else
if (FAllocatedRecordCount + FAllocRecordsBy <= FMaxCachedRecordCount) then
Inc(FAllocatedRecordCount,FAllocRecordsBy)
else
FAllocatedRecordCount := FMaxCachedRecordCount;
if (FCache = nil) then
FCache := MemoryManager.GetMem(FAllocatedRecordCount * FRecordBufferSize)
else
MemoryManager.ReallocMem(FCache,(FAllocatedRecordCount * FRecordBufferSize));
Inc(FCachedRecordCount);
end
else
begin
SaveToTemp := True;
// need writing to temporary file
if (FTempPageFile = nil) then
FTempPageFile := TMYLDBFileStream.Create(GetTempFileName,fmCreate,True);
SaveTempPage;
Move(RecordBuffer^,(FTempPage + FTempPageRecordCount * FRecordBufferSize)^,
FRecordBufferSize);
Inc(FTempPageRecordCount);
end;
end
else
begin
// no need in extending
Inc(FCachedRecordCount);
end;
if (not SaveToTemp) then
Move(RecordBuffer^,(FCache + FRecordCount * FRecordBufferSize)^,
FRecordBufferSize);
Move(FRecordCount,RecordID,sizeof(RecordID));
Inc(FRecordCount);
Result := True;
except
Result := False;
end;
end; // AddRecord
//------------------------------------------------------------------------------
// update record, return true if record was updated, false if record was deleted
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.UpdateRecord(SessionID: TMYLDBSessionID; RecordBuffer: TMYLDBRecordBuffer; RecordID: TMYLDBRecordID): Boolean;
begin
Result := False;
end;// UpdateRecord
//------------------------------------------------------------------------------
// delete record, return true if record was deleted, false if record was deleted earlier
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.DeleteRecord(SessionID: TMYLDBSessionID; var RecordID: TMYLDBRecordID): Boolean;
begin
Result := False;
end;// DeleteRecord
//------------------------------------------------------------------------------
// get record
//------------------------------------------------------------------------------
procedure TMYLDBTemporaryRecordManager.GetRecordBuffer(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
var RecordNo: TMYLDBRecordNo;
begin
RecordNo := 0;
Move(NavigationInfo.RecordID,RecordNo,sizeof(NavigationInfo.RecordID));
if (FRecordCount = 0) then
begin
NavigationInfo.GetRecordResult := grrEOF;
Exit;
end;
// get record relatively to the first position
if (NavigationInfo.FirstPosition) then
begin
NavigationInfo.GetRecordResult := GetRecordFromFirstPosition(
NavigationInfo.GetRecordMode,
RecordNo
);
if (NavigationInfo.GetRecordResult = grrOK) then
NavigationInfo.FirstPosition := False;
end
else
// get record relatively to the last position
if (NavigationInfo.LastPosition) then
begin
NavigationInfo.GetRecordResult := GetRecordFromLastPosition(
NavigationInfo.GetRecordMode,
RecordNo
);
if (NavigationInfo.GetRecordResult = grrOK) then
NavigationInfo.LastPosition := False;
end
else
NavigationInfo.GetRecordResult := GetRecordFromAnyPosition(
NavigationInfo.GetRecordMode,
RecordNo
);
if (NavigationInfo.GetRecordResult = grrOK) then
begin
NavigationInfo.GetRecordResult := grrError;
if (ReadRecord(NavigationInfo.RecordBuffer,RecordNo)) then
NavigationInfo.GetRecordResult := grrOK;
end; // record retrieved successfully
Move(RecordNo,NavigationInfo.RecordID,sizeof(NavigationInfo.RecordID));
end; // GetRecordBuffer
//------------------------------------------------------------------------------
// return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.CompareRecordID(RecordID1: TMYLDBRecordID; RecordID2: TMYLDBRecordID): Integer;
var RecordNo1, RecordNo2: TMYLDBRecordNo;
begin
RecordNo1 := 0;
RecordNo2 := 0;
Move(RecordID1,RecordNo1,Sizeof(RecordID1));
Move(RecordID2,RecordNo2,Sizeof(RecordID2));
if (RecordNo1 = RecordNo2) then
Result := 0
else
if (RecordNo1 > RecordNo2) then
Result := 1
else
Result := -1;
end; // CompareRecordID
//------------------------------------------------------------------------------
// return record no
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.GetApproximateRecNo(SessionID: TMYLDBSessionID;
RecordID: TMYLDBRecordID): TMYLDBRecordNo;
begin
Result := 0;
Move(RecordID,Result,Sizeof(RecordID));
if (Result >= FRecordCount) then
Result := -1
else
begin
Inc(Result);
end;
end; // GetApproximateRecNo
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryPageManager
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// InternalAddPage
//------------------------------------------------------------------------------
procedure TMYLDBTemporaryPageManager.InternalAddPage(aPage: TMYLDBPage);
var
PageNo: Integer;
begin
PageNo := FAllocatedPageCount;
if (FDisableTempFiles or (PageNo < FMaxMemoryPageCount)) then
begin
FMemoryPageManager.InternalAddPage(aPage);
if (aPage.PageNo >= FAllocatedPageCount) then
begin
FAllocatedPageCount := aPage.PageNo +1;
FAllocatedPageMap.Size := FAllocatedPageCount;
end;
FAllocatedPageMap.SetBit(aPage.PageNo, True);
Inc(FPageCount);
end
else
begin
if (FTempPageFile = nil) then
FTempPageFile := TMYLDBFileStream.Create(GetTempFileName,fmCreate, True);
Inc(FAllocatedPageCount);
FAllocatedPageMap.Size := FAllocatedPageCount;
Inc(FPageCount);
FAllocatedPageMap.SetBit(PageNo, True);
if (FTempPageFile.Size < FAllocatedPageCount * FPageSize) then
FTempPageFile.Size := FAllocatedPageCount * FPageSize * 3 div 2;
aPage.PageNo := PageNo;
if ((not aPage.OwnBuffer) or (aPage.PageBuffer = nil)) then
begin
aPage.AllocPageBuffer;
aPage.OwnBuffer := True;
end;
end;
end;// InternalAddPage
//------------------------------------------------------------------------------
// InternalRemovePage
//------------------------------------------------------------------------------
procedure TMYLDBTemporaryPageManager.InternalRemovePage(PageNo: TMYLDBPageNo);
begin
Dec(FPageCount);
FAllocatedPageMap.SetBit(PageNo, False);
if (FDisableTempFiles or (PageNo < FMaxMemoryPageCount)) then
FMemoryPageManager.InternalRemovePage(PageNo)
end;// InternalRemovePage
//------------------------------------------------------------------------------
// InternalReadPage
//------------------------------------------------------------------------------
function TMYLDBTemporaryPageManager.InternalReadPage(aPage: TMYLDBPage): Boolean;
begin
if (not FAllocatedPageMap.GetBit(aPage.PageNo)) then
raise EMYLDBException.Create(10396, ErrorANotReleasedPageIsAllocated);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -