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

📄 abstempengine.pas

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


//------------------------------------------------------------------------------
// return result for attempt of getting record relatively to last position
// and set RecordID to new record ID
//------------------------------------------------------------------------------
function TABSTemporaryRecordManager.GetRecordFromLastPosition(
        GetRecordMode: TABSGetRecordMode;
        var RecordID:  TABSRecordNo
                                  ): TABSGetRecordResult;
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 TABSTemporaryRecordManager.GetRecordFromAnyPosition(
        GetRecordMode: TABSGetRecordMode;
        var RecordID:  TABSRecordNo
                                  ): TABSGetRecordResult;
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 TABSTemporaryRecordManager.Create(
                        RecordBufferSize:     Integer;
                        RecordsPerPage:       Integer;
                        AllocRecordsBy:       Integer;
                        DisableTempFiles:     Boolean
                      );
begin
 if (RecordBufferSize = 0) then
  raise EABSException.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 TABSTemporaryRecordManager.Destroy;
begin
 Empty(SYSTEM_SESSION_ID);
 MemoryManager.FreeAndNillMem(FTempPage);
 inherited Destroy;
end; // Destroy


//------------------------------------------------------------------------------
// Empty
//------------------------------------------------------------------------------
procedure TABSTemporaryRecordManager.Empty(SessionID: TABSSessionID);
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 TABSTemporaryRecordManager.AddRecord(
                                              SessionID: TABSSessionID;
                                              RecordBuffer: TABSRecordBuffer;
                                              var RecordID: TABSRecordID
                                              ): 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 := TABSFileStream.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 TABSTemporaryRecordManager.UpdateRecord(SessionID: TABSSessionID; RecordBuffer: TABSRecordBuffer; RecordID: TABSRecordID): Boolean;
begin
  Result := False;
end;// UpdateRecord


//------------------------------------------------------------------------------
// delete record, return true if record was deleted, false if record was deleted earlier
//------------------------------------------------------------------------------
function TABSTemporaryRecordManager.DeleteRecord(SessionID: TABSSessionID; var RecordID: TABSRecordID): Boolean;
begin
  Result := False;
end;// DeleteRecord


//------------------------------------------------------------------------------
// get record
//------------------------------------------------------------------------------
procedure TABSTemporaryRecordManager.GetRecordBuffer(SessionID: TABSSessionID;
                                        var NavigationInfo: TABSNavigationInfo);
var RecordNo: TABSRecordNo;
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 TABSTemporaryRecordManager.CompareRecordID(RecordID1: TABSRecordID; RecordID2: TABSRecordID): Integer;
var RecordNo1, RecordNo2: TABSRecordNo;
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 TABSTemporaryRecordManager.GetApproximateRecNo(SessionID: TABSSessionID;
                                          RecordID: TABSRecordID): TABSRecordNo;
begin
 Result := 0;
 Move(RecordID,Result,Sizeof(RecordID));
 if (Result >= FRecordCount) then
  Result := -1
 else
  begin
   Inc(Result);
  end;
end; // GetApproximateRecNo


////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryPageManager
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// InternalAddPage
//------------------------------------------------------------------------------
procedure TABSTemporaryPageManager.InternalAddPage(aPage: TABSPage);
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 := TABSFileStream.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 TABSTemporaryPageManager.InternalRemovePage(PageNo: TABSPageNo);
begin
  Dec(FPageCount);
  FAllocatedPageMap.SetBit(PageNo, False);
  if (FDisableTempFiles or (PageNo < FMaxMemoryPageCount)) then
   FMemoryPageManager.InternalRemovePage(PageNo)
end;// InternalRemovePage


//------------------------------------------------------------------------------
// InternalReadPage
//------------------------------------------------------------------------------
function TABSTemporaryPageManager.InternalReadPage(aPage: TABSPage): Boolean;
begin
  if (not FAllocatedPageMap.GetBit(aPage.PageNo)) then
   raise EABSException.Create(10396, ErrorANotReleasedPageIsAllocated);

⌨️ 快捷键说明

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