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