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

📄 myldbmemengine.pas

📁 一个本地database引擎,支持中文T_Sql查询,兼容DELPHI标准数据库控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
function TMYLDBMemoryDatabaseData.GetNewObjectId: TMYLDBObjectID;
begin
  Lock;
  try
    Inc(FLastObjectID);
    Result := FLastObjectID;
  finally
   Unlock;
  end;
end;//GetNewObjectId


////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBMemoryRecordManager
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// find record position in buffer by record number
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.FindRecord(RecordNo: TMYLDBRecordNo): TMYLDBRecordNo;
var i{,l,Pos}:  Integer;
    b,k:        Byte;
    n:          TMYLDBRecordNo;
begin
 Result := INVALID_ID8;
 if (RecordNo < 0) or (RecordNo > FRecordCount) then
  Exit;

 if (FNoRecordsDeleted) then
  begin
   Result := RecordNo;
   Exit;
  end;
{
 i := 0; // byte number
 n := 0; // bits count
 Pos := RecordNo div 8;
 while (i < Pos) do
  begin
   b := PByte(FDeleteFlagBuffer + i)^;
   Inc(n,FBitsTable[b]);
   Inc(i);
  end;
 if (i > 0) then Dec(i);
 Result := i * 8;
 if (i > 0) then
  Inc(i);
 if (i > FAllocatedRecordCount) then
  raise EMYLDBException.Create(10457,ErrorLInvalidBitNo,[RecordNo,FAllocatedRecordCount]);
 b := PByte(FDeleteFlagBuffer + i)^;
 l := 7;
 if (i = (FAllocatedRecordCount div 8)) then
  l := (FAllocatedRecordCount mod 8)-1;
 for k := 0 to l do
  begin
   if ((b and (1 shl k)) = 0) then Inc(n);
   if (n > RecordNo) then Break;
   Inc(Result);
  end;

Exit;
}
 i := 0; // byte number
 n := 0; // bits count
 repeat
   b := PByte(FDeleteFlagBuffer + i)^;
   n := n + FBitsTable[b];
   Inc(i);
 until (n >= RecordNo);
 Result := i * 8;
 // scan last byte
 if (n <> RecordNo) then
  for k := 7 downto 0 do
   begin
    if ((b and (1 shl k)) = 0) then Dec(n);
    Dec(Result);
    if (n = RecordNo) then Break;
   end;
end;


//------------------------------------------------------------------------------
// returns position of the record specified by record id,
// or INVALID_ID8 if the record with this id does not exists
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.GetTablePositionByRecordID(
              RecordNo:            TMYLDBRecordNo
                ): TMYLDBRecordNo;
var n,i,j:    Integer;
    b,k:      Byte;
begin
 Result := INVALID_ID8;
 if (RecordNo >= FAllocatedRecordCount) then
  Exit;
 if (FNoRecordsDeleted) then
  begin
   Result := RecordNo+1;
   Exit;
  end;
 // number of byte with flags
 i := RecordNo div 8;
 Result := 0; // bits count
 if (i > 0) then
   for j := 0 to i-1 do
     for k := 7 downto 0 do
      begin
       b := PByte(FDeleteFlagBuffer + j)^;
       if ((b and (1 shl k)) = 0) then Inc(Result);
      end;
 // scan last byte
 b := PByte(FDeleteFlagBuffer + i)^;
 n := RecordNo mod 8;
 for k := 0 to n do
   if ((b and (1 shl k)) = 0) then Inc(Result);
Exit;
 // number of byte with flags
 i := RecordNo div 8;
 Result := 0; // bits count
 // scan last byte
 b := PByte(FDeleteFlagBuffer + i)^;
 n := RecordNo mod 8;
 for k := n downto 0 do
   if ((b and (1 shl k)) = 0) then Inc(Result);
 if (i > 0) then
   for j := 0 to i-1 do
     for k := 7 downto 0 do
      begin
       b := PByte(FDeleteFlagBuffer + j)^;
       if ((b and (1 shl k)) = 0) then Inc(Result);
      end;
 if (Result > 0) then
  Dec(Result);
end;


//------------------------------------------------------------------------------
// return result for attempt of getting record relatively to first position
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.GetRecordFromFirstPosition(
            GetRecordMode: TMYLDBGetRecordMode;
            var RecordID: Integer
                                                           ): TMYLDBGetRecordResult;
begin
 Result := grrError;
 case GetRecordMode of
  grmPrior:
   begin
    Result := grrBOF;
   end;
  grmCurrent:
   begin
    Result := grrError;
   end;
  grmNext:
   begin
    RecordID := FFirstRecordID;
    Result := grrOK;
   end;
 end; // GetRecordMode
end; // GetRecordFromFirstPosition


//------------------------------------------------------------------------------
// return result for attempt of getting record relatively to last position
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.GetRecordFromLastPosition(
            GetRecordMode: TMYLDBGetRecordMode;
            var RecordID: Integer
                                                          ): TMYLDBGetRecordResult;
begin
 Result := grrError;
 case GetRecordMode of
  grmPrior:
   begin
    RecordID := FLastRecordID;
    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 TMYLDBMemoryRecordManager.GetRecordFromAnyPosition(
            GetRecordMode: TMYLDBGetRecordMode;
            var RecordID: Integer
                                      ): TMYLDBGetRecordResult;
begin
 Result := grrError;
 case GetRecordMode of
  grmPrior:
   begin
    Result := grrBOF;
    if (RecordID > 0) then
     begin
      Dec(RecordID);
      while (RecordID >= FFirstRecordID) do
       begin
        // record found
        if (not CheckNullFlag(RecordID,FDeleteFlagBuffer)) then
         begin
          Result := grrOK;
          break;
         end;
        Dec(RecordID);
       end; // scan prior record
     end; // RecordID > 0
   end;
  grmCurrent:
   begin
    if ((RecordID > FLastRecordID) or (RecordID < FFirstRecordID)) then
     // current record does not exist
     Result := grrError
    else
    if (CheckNullFlag(RecordID,FDeleteFlagBuffer)) then
     // current record is deleted
     Result := grrError
    else
     Result := grrOK;
   end;
  grmNext:
   begin
    Result := grrEOF;
    if (RecordID < FAllocatedRecordCount-1) then
     begin
      Inc(RecordID);
      while ((RecordID <= FLastRecordID) and (RecordID < FAllocatedRecordCount)) do
       begin
        // record found
        if (not CheckNullFlag(RecordID,FDeleteFlagBuffer)) then
         begin
          Result := grrOK;
          break;
         end;
        Inc(RecordID);
       end; // scan prior record
     end;
   end;
 end; // GetRecordMode
end; // GetRecordFromAnyPosition


//------------------------------------------------------------------------------
// set record count
//------------------------------------------------------------------------------
procedure TMYLDBMemoryRecordManager.SetRecordCount(NewRecordCount: Integer);
var i: Integer;
begin
 if (NewRecordCount = 0) then
  MemoryManager.FreeAndNillMem(FRecordBuffer)
 else
 if (FAllocatedRecordCount = 0) then
   FRecordBuffer := MemoryManager.GetMem(NewRecordCount * FRecordBufferSize)
 else
   MemoryManager.ReallocMem(FRecordBuffer,NewRecordCount * FRecordBufferSize,False);
 i := (NewRecordCount div 8) + Integer((NewRecordCount mod 8) > 0);
 if (i = 0) then
  MemoryManager.FreeAndNillMem(FDeleteFlagBuffer)
 else
 if (FAllocatedRecordCount = 0) then
  FDeleteFlagBuffer := MemoryManager.GetMem(i)
 else
  MemoryManager.ReallocMem(Pointer(FDeleteFlagBuffer),i);
 FAllocatedRecordCount := NewRecordCount;
end; // SetRecordCount


//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
constructor TMYLDBMemoryRecordManager.Create(
                        RecordBufferSize:     Integer;
                        AllocRecordsBy:       Integer
                      );
var
    i,c: Byte;
begin
 if ((RecordBufferSize = 0) and (not IsDesignMode)) then
  raise EMYLDBException.Create(10011,ErrorLInvalidRecordSize);
 FRecordBuffer := nil;
 FDeleteFlagBuffer := nil;
 FRecordCount := 0;
 FAllocatedRecordCount := 0;
 FFirstRecordID := 0;
 FLastRecordID := 0;
 FRecordBufferSize := RecordBufferSize;
 FAllocRecordsBy := AllocRecordsBy;
 FNoRecordsDeleted := True;
 for i := 0 to 255 do
  begin
   c := 0;
   if ((i and 1) = 0) then Inc(c);
   if ((i and 2) = 0) then Inc(c);
   if ((i and 4) = 0) then Inc(c);
   if ((i and 8) = 0) then Inc(c);
   if ((i and 16) = 0) then Inc(c);
   if ((i and 32) = 0) then Inc(c);
   if ((i and 64) = 0) then Inc(c);
   if ((i and 128) = 0) then Inc(c);
   FBitsTable[i] := c;
  end;
end; // Create;


//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TMYLDBMemoryRecordManager.Destroy;
begin
 Empty(SYSTEM_SESSION_ID);
 inherited Destroy;
end; // Destroy


//------------------------------------------------------------------------------
// Empty
//------------------------------------------------------------------------------
procedure TMYLDBMemoryRecordManager.Empty(SessionID: TMYLDBSessionID);
begin
 FAllocatedRecordCount := 0;
 FRecordCount := 0;
 if (FRecordBuffer <> nil) then
   MemoryManager.FreeAndNillMem(FRecordBuffer);
 if (FDeleteFlagBuffer <> nil) then
   MemoryManager.FreeAndNillMem(FDeleteFlagBuffer);
 FFirstRecordID := 0;
 FLastRecordID := 0;
end; // Empty


//------------------------------------------------------------------------------
// add record and return its number
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.AddRecord(SessionID: TMYLDBSessionID; RecordBuffer: TMYLDBRecordBuffer; var RecordID: TMYLDBRecordID): Boolean;
var OldRecordCount, i: Integer;
begin
 try
   // add to the end of buffer
//   RecordID.PageNo := FRecordCount;

⌨️ 快捷键说明

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