Browse Source

* Playing around with double-linked indexes, part II

git-svn-id: trunk@9166 -
joost 18 years ago
parent
commit
03ea1bc4c3
1 changed files with 68 additions and 18 deletions
  1. 68 18
      packages/fcl-db/src/bufdataset.pas

+ 68 - 18
packages/fcl-db/src/bufdataset.pas

@@ -83,9 +83,16 @@ type
 
 
   TBufDataset = class(TDBDataSet)
   TBufDataset = class(TDBDataSet)
   private
   private
+    FIndexesCount   : integer;
+    FCurrentIndex   : integer;
+  
     FCurrentRecBuf  : PBufRecLinkItem;
     FCurrentRecBuf  : PBufRecLinkItem;
     FLastRecBuf     : PBufRecLinkItem;
     FLastRecBuf     : PBufRecLinkItem;
     FFirstRecBuf    : PBufRecLinkItem;
     FFirstRecBuf    : PBufRecLinkItem;
+
+    FLastRecBufs    : array of PBufRecLinkItem;
+    FFirstRecBufs   : array of PBufRecLinkItem;
+
     FFilterBuffer   : pchar;
     FFilterBuffer   : pchar;
     FBRecordCount   : integer;
     FBRecordCount   : integer;
 
 
@@ -154,6 +161,8 @@ type
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); virtual; abstract;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); virtual; abstract;
 
 
   public
   public
+    procedure AddSecondIndex;
+  
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
     function GetFieldData(Field: TField; Buffer: Pointer;
     function GetFieldData(Field: TField; Buffer: Pointer;
       NativeFormat: Boolean): Boolean; override;
       NativeFormat: Boolean): Boolean; override;
@@ -185,6 +194,12 @@ uses variants, dbconst;
 constructor TBufDataset.Create(AOwner : TComponent);
 constructor TBufDataset.Create(AOwner : TComponent);
 begin
 begin
   Inherited Create(AOwner);
   Inherited Create(AOwner);
+  FIndexesCount:=2;
+  FCurrentIndex:=0;
+  
+  setlength(FFirstRecBufs,FIndexesCount);
+  SetLength(FLastRecBufs,FIndexesCount);
+
   SetLength(FUpdateBuffer,0);
   SetLength(FUpdateBuffer,0);
   SetLength(FBlobBuffers,0);
   SetLength(FBlobBuffers,0);
   SetLength(FUpdateBlobBuffers,0);
   SetLength(FUpdateBlobBuffers,0);
@@ -212,7 +227,7 @@ end;
 function TBufDataset.intAllocRecordBuffer: PChar;
 function TBufDataset.intAllocRecordBuffer: PChar;
 begin
 begin
   // Note: Only the internal buffers of TDataset provide bookmark information
   // Note: Only the internal buffers of TDataset provide bookmark information
-  result := AllocMem(FRecordsize+sizeof(TBufRecLinkItem));
+  result := AllocMem(FRecordsize+sizeof(TBufRecLinkItem)*FIndexesCount);
 end;
 end;
 
 
 function TBufDataset.AllocRecordBuffer: PChar;
 function TBufDataset.AllocRecordBuffer: PChar;
@@ -335,13 +350,13 @@ begin
   Acceptable := True;
   Acceptable := True;
   case GetMode of
   case GetMode of
     gmPrior :
     gmPrior :
-      if not assigned(PBufRecLinkItem(FCurrentRecBuf)^.prior) then
+      if not assigned(FCurrentRecBuf[FCurrentIndex].prior) then
         begin
         begin
         Result := grBOF;
         Result := grBOF;
         end
         end
       else
       else
         begin
         begin
-        FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.prior;
+        FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].prior;
         end;
         end;
     gmCurrent :
     gmCurrent :
       if FCurrentRecBuf = FLastRecBuf then
       if FCurrentRecBuf = FLastRecBuf then
@@ -352,11 +367,11 @@ begin
         if getnextpacket = 0 then result := grEOF;
         if getnextpacket = 0 then result := grEOF;
         end
         end
       else if FCurrentRecBuf = nil then FCurrentRecBuf := FFirstRecBuf
       else if FCurrentRecBuf = nil then FCurrentRecBuf := FFirstRecBuf
-      else if (PBufRecLinkItem(FCurrentRecBuf)^.next = FLastRecBuf) then
+      else if (FCurrentRecBuf[FCurrentIndex].next = FLastRecBuf) then
         begin
         begin
         if getnextpacket > 0 then
         if getnextpacket > 0 then
           begin
           begin
-          FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
+          FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].next;
           end
           end
         else
         else
           begin
           begin
@@ -365,7 +380,7 @@ begin
         end
         end
       else
       else
         begin
         begin
-        FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
+        FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].next;
         end;
         end;
   end;
   end;
 
 
@@ -377,7 +392,7 @@ begin
       BookmarkData := FCurrentRecBuf;
       BookmarkData := FCurrentRecBuf;
       BookmarkFlag := bfCurrent;
       BookmarkFlag := bfCurrent;
       end;
       end;
-    move((pointer(FCurrentRecBuf)+sizeof(TBufRecLinkItem))^,buffer^,FRecordSize);
+    move((pointer(FCurrentRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount)^,buffer^,FRecordSize);
     GetCalcFields(Buffer);
     GetCalcFields(Buffer);
 
 
     if Filtered then
     if Filtered then
@@ -459,13 +474,13 @@ begin
     exit;
     exit;
     end;
     end;
   i := 0;
   i := 0;
-  pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem));
+  pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount);
   while ((i < FPacketRecords) or (FPacketRecords = -1)) and (loadbuffer(pb) = grOk) do
   while ((i < FPacketRecords) or (FPacketRecords = -1)) and (loadbuffer(pb) = grOk) do
     begin
     begin
     FLastRecBuf^.next := pointer(IntAllocRecordBuffer);
     FLastRecBuf^.next := pointer(IntAllocRecordBuffer);
     FLastRecBuf^.next^.prior := FLastRecBuf;
     FLastRecBuf^.next^.prior := FLastRecBuf;
     FLastRecBuf := FLastRecBuf^.next;
     FLastRecBuf := FLastRecBuf^.next;
-    pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem));
+    pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount);
     inc(i);
     inc(i);
     end;
     end;
   FBRecordCount := FBRecordCount + i;
   FBRecordCount := FBRecordCount + i;
@@ -568,7 +583,7 @@ begin
       result := false;
       result := false;
       exit;
       exit;
       end;
       end;
-    currbuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer+sizeof(TBufRecLinkItem);
+    currbuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer+sizeof(TBufRecLinkItem)*FIndexesCount;
     end
     end
   else
   else
     begin
     begin
@@ -624,7 +639,7 @@ begin
     exit;
     exit;
     end;
     end;
   if state = dsFilter then  // Set the value into the 'temporary' FLastRecBuf buffer for Locate and Lookup
   if state = dsFilter then  // Set the value into the 'temporary' FLastRecBuf buffer for Locate and Lookup
-    CurrBuff := pointer(FLastRecBuf) + sizeof(TBufRecLinkItem)
+    CurrBuff := pointer(FLastRecBuf) + sizeof(TBufRecLinkItem)*FIndexesCount
   else
   else
     CurrBuff := GetCurrentBuffer;
     CurrBuff := GetCurrentBuffer;
   If Field.Fieldno > 0 then // If = 0, then calculated field or something
   If Field.Fieldno > 0 then // If = 0, then calculated field or something
@@ -715,7 +730,7 @@ begin
         begin
         begin
         if UpdateKind = ukModify then
         if UpdateKind = ukModify then
           begin
           begin
-          move(pchar(OldValuesBuffer+sizeof(TBufRecLinkItem))^,pchar(BookmarkData+sizeof(TBufRecLinkItem))^,FRecordSize);
+          move(pchar(OldValuesBuffer+sizeof(TBufRecLinkItem)*FIndexesCount)^,pchar(BookmarkData+sizeof(TBufRecLinkItem)*FIndexesCount)^,FRecordSize);
           FreeRecordBuffer(OldValuesBuffer);
           FreeRecordBuffer(OldValuesBuffer);
           end
           end
         else if UpdateKind = ukDelete then
         else if UpdateKind = ukDelete then
@@ -931,7 +946,7 @@ begin
       begin
       begin
       // Update the oldvalues-buffer
       // Update the oldvalues-buffer
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
-      move(FCurrentRecBuf^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize+sizeof(TBufRecLinkItem));
+      move(FCurrentRecBuf^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize+sizeof(TBufRecLinkItem)*FIndexesCount);
       FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukModify;
       FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukModify;
       end
       end
     else
     else
@@ -939,7 +954,7 @@ begin
     end;
     end;
 
 
   CurrBuff := pchar(FCurrentRecBuf);
   CurrBuff := pchar(FCurrentRecBuf);
-  inc(Currbuff,sizeof(TBufRecLinkItem));
+  inc(Currbuff,sizeof(TBufRecLinkItem)*FIndexesCount);
   move(ActiveBuffer^,CurrBuff^,FRecordSize);
   move(ActiveBuffer^,CurrBuff^,FRecordSize);
 end;
 end;
 
 
@@ -1221,6 +1236,41 @@ begin
     Refresh;
     Refresh;
 end;
 end;
 
 
+procedure TBufDataset.AddSecondIndex;
+
+var ALinkItem,
+    ANewLinkItem : PBufRecLinkItem;
+
+begin
+  ALinkItem:=FLastRecBuf[0].prior;
+  ANewLinkItem:=FLastRecBuf[0].prior;
+
+  FFirstRecBufs[1]:=ANewLinkItem;
+
+  while ALinkItem<>FFirstRecBuf do
+    begin
+    ANewLinkItem[1].next:=ALinkItem[0].prior;
+    ANewLinkItem[1].prior:=ALinkItem[0].next;
+    ALinkItem:=ALinkItem[0].prior;
+    ANewLinkItem:=ANewLinkItem[1].next;
+    end;
+    
+  FLastRecBufs[1]:=FLastRecBuf;
+  ANewLinkItem[1].next:=FLastRecBufs[1];
+  FLastRecBufs[1][1].prior:=ANewLinkItem;
+  FFirstRecBufs[1][1].prior:=nil;
+  FLastRecBufs[1][1].next:=nil;
+  
+// Stel in op tweede index:
+  FCurrentIndex:=1;
+  FLastRecBuf:=FLastRecBufs[FCurrentIndex];
+  FFirstRecBuf:=FFirstRecBufs[FCurrentIndex];
+  FCurrentRecBuf:=FFirstRecBuf;
+
+  Resync([rmExact,rmCenter]);
+end;
+
+
 procedure TBufDataset.ParseFilter(const AFilter: string);
 procedure TBufDataset.ParseFilter(const AFilter: string);
 begin
 begin
   // parser created?
   // parser created?
@@ -1303,7 +1353,7 @@ begin
     FieldBufPos := FFieldBufPositions[keyfield.FieldNo-1];
     FieldBufPos := FFieldBufPositions[keyfield.FieldNo-1];
     VBLength := keyfield.DataSize;
     VBLength := keyfield.DataSize;
     ValueBuffer := AllocMem(VBLength);
     ValueBuffer := AllocMem(VBLength);
-    currbuff := pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)+FieldBufPos;
+    currbuff := pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount+FieldBufPos;
     move(currbuff^,ValueBuffer^,VBLength);
     move(currbuff^,ValueBuffer^,VBLength);
     end;
     end;
 
 
@@ -1312,7 +1362,7 @@ begin
   if CheckNull then
   if CheckNull then
     begin
     begin
     repeat
     repeat
-    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
+    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
     if GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
     if GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
       begin
       begin
       result := True;
       result := True;
@@ -1325,7 +1375,7 @@ begin
   else if keyfield.DataType = ftString then
   else if keyfield.DataType = ftString then
     begin
     begin
     repeat
     repeat
-    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
+    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
     if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
     if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
       begin
       begin
       inc(CurrBuff,FieldBufPos);
       inc(CurrBuff,FieldBufPos);
@@ -1342,7 +1392,7 @@ begin
   else
   else
     begin
     begin
     repeat
     repeat
-    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
+    currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
     if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
     if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
       begin
       begin
       inc(CurrBuff,FieldBufPos);
       inc(CurrBuff,FieldBufPos);