Skip to content

Commit

Permalink
new FieldBitSet() optimized function
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud Bouchez committed Oct 17, 2022
1 parent 34bf50e commit 927dad7
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 27 deletions.
26 changes: 23 additions & 3 deletions src/db/mormot.db.core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ function IsAllFields(const Fields: TFieldBits): boolean;
function FieldBitGet(const Fields: TFieldBits; Index: PtrUInt): boolean;
{$ifdef HASINLINE}inline;{$endif}

/// faster alternative to "include(Fields, Index)" expression
// - warning: no Index range check is done
procedure FieldBitSet(var Fields: TFieldBits; Index: PtrUInt);
{$ifdef HASINLINE}inline;{$endif}

/// faster alternative to "GetBitsCount(Fields, MaxFIelds)" expression
function FieldBitCount(const Fields: TFieldBits; MaxFields: integer = MAX_SQLFIELDS): PtrInt;
{$ifdef HASINLINE}inline;{$endif}
Expand Down Expand Up @@ -1499,6 +1504,21 @@ function FieldBitGet(const Fields: TFieldBits; Index: PtrUInt): boolean;
{$ifend MAX_SQLFIELDS_64 and CPU64}
end;

{$if defined(MAX_SQLFIELDS_64) and defined(CPU64)}
procedure FieldBitSet(var Fields: TFieldBits; Index: PtrUInt);
begin
PInt64(@Fields)^ := PInt64(@Fields)^ or (Int64(1) shl Index);
end;
{$else}
procedure FieldBitSet(var Fields: TFieldBits; Index: PtrUInt);
var
p: PInteger;
begin
p := @PIntegerArray(@Fields)[Index shr 5];
p^ := p^ or (1 shl (Index and 31));
end;
{$ifend MAX_SQLFIELDS_64 and CPU64}

function FieldBitCount(const Fields: TFieldBits; MaxFields: integer): PtrInt;
begin
{$ifdef MAX_SQLFIELDS_64}
Expand Down Expand Up @@ -1582,12 +1602,12 @@ function SearchFieldIndex(var Indexes: TFieldIndexDynArray; Field: integer): int
procedure FieldIndexToBits(const Index: TFieldIndexDynArray;
out Fields: TFieldBits);
var
i: integer;
i: PtrInt;
begin
FillZero(Fields{%H-});
for i := 0 to Length(Index) - 1 do
if Index[i] >= 0 then
include(Fields, Index[i]);
FieldBitSet(Fields, Index[i]);
end;

function FieldIndexToBits(const Index: TFieldIndexDynArray): TFieldBits;
Expand Down Expand Up @@ -3296,7 +3316,7 @@ procedure TSelectStatement.SelectFieldBits(var Fields: TFieldBits;
if f^.Field = 0 then
withID := true
else
include(Fields, f^.Field - 1);
FieldBitSet(Fields, f^.Field - 1);
if (SubFields <> nil) and
fHasSelectSubFields then
SubFields^[f^.Field] := f^.SubField;
Expand Down
2 changes: 1 addition & 1 deletion src/mormot.commit.inc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
'2.0.4213'
'2.0.4214'
10 changes: 5 additions & 5 deletions src/orm/mormot.orm.base.pas
Original file line number Diff line number Diff line change
Expand Up @@ -11016,7 +11016,7 @@ function TOrmPropertiesAbstract.FieldBitsFromBlobField(aBlobField: PRttiProp;
for f := 0 to high(BlobFields) do
if BlobFields[f].PropInfo = aBlobField then
begin
Include(Bits, BlobFields[f].PropertyIndex);
FieldBitSet(Bits, BlobFields[f].PropertyIndex);
result := true;
exit;
end;
Expand All @@ -11041,7 +11041,7 @@ function TOrmPropertiesAbstract.FieldBitsFromCsv(const aFieldsCsv: RawUtf8;
ndx := Fields.IndexByName(@n[1]);
if ndx < 0 then
exit; // invalid field name
include(Bits, ndx);
FieldBitSet(Bits, ndx);
end;
result := true;
end;
Expand Down Expand Up @@ -11078,7 +11078,7 @@ function TOrmPropertiesAbstract.FieldBitsFromCsv(const aFieldsCsv: RawUtf8;
ndx := Fields.IndexByName(@n[1]);
if ndx < 0 then
exit; // invalid field name
include(Bits, ndx);
FieldBitSet(Bits, ndx);
end;
result := true;
end;
Expand Down Expand Up @@ -11113,7 +11113,7 @@ function TOrmPropertiesAbstract.FieldBitsFrom(
ndx := Fields.IndexByName(aFields[f]);
if ndx < 0 then
exit; // invalid field name
include(Bits, ndx);
FieldBitSet(Bits, ndx);
end;
result := true;
end;
Expand Down Expand Up @@ -11147,7 +11147,7 @@ function TOrmPropertiesAbstract.FieldBitsFromRawUtf8(
ndx := Fields.IndexByName(pointer(aFields[f]));
if ndx < 0 then
exit; // invalid field name
include(Bits, ndx);
FieldBitSet(Bits, ndx);
end;
result := true;
end;
Expand Down
26 changes: 13 additions & 13 deletions src/orm/mormot.orm.core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6131,7 +6131,7 @@ procedure TOrmFill.AddMapFromName(aRecord: TOrm; aName: PUtf8Char; aIndex: integ
i := IndexByName(aName);
if i >= 0 then
begin // only map if column name is a valid field
include(fTableMapFields, i);
FieldBitSet(fTableMapFields, i);
AddMap(aRecord, List[i], aIndex);
end;
end;
Expand Down Expand Up @@ -6428,7 +6428,7 @@ function TOrm.GetNonVoidFields: TFieldBits;
for f := 0 to Fields.Count - 1 do
if FieldBitGet(CopiableFieldsBits, f) and
not Fields.List[f].IsValueVoid(self) then
include(result, f);
FieldBitSet(result, f);
end;

constructor TOrm.Create(const aClient: IRestOrm; aID: TID; ForUpdate: boolean);
Expand Down Expand Up @@ -6616,7 +6616,7 @@ procedure TOrm.FillValue(var PropIndex: PtrInt; PropName, Value: PUtf8Char;
begin
field.SetValue(self, Value, ValueLen, wasString);
if FieldBits <> nil then
Include(FieldBits^, field.PropertyIndex);
FieldBitSet(FieldBits^, field.PropertyIndex);
end;
end;
end;
Expand Down Expand Up @@ -9087,15 +9087,15 @@ constructor TOrmProperties.Create(aTable: TOrmClass);
// handle unique fields, i.e. if marked as "stored false"
if aIsUnique in F.Attributes then
begin
include(IsUniqueFieldsBits, i);
FieldBitSet(IsUniqueFieldsBits, i);
// must trim() text value before storage, and validate for unicity
if F.OrmFieldType in [oftUtf8Text, oftAnsiText] then
AddFilterOrValidate(i, TSynFilterTrim.Create);
AddFilterOrValidate(i, TSynValidateUniqueField.Create);
end;
// get corresponding properties content
include(fHasTypeFields, F.OrmFieldType);
include(FieldBits[F.OrmFieldType], i);
FieldBitSet(FieldBits[F.OrmFieldType], i);
case F.OrmFieldType of
oftUnknown:
;
Expand Down Expand Up @@ -9156,14 +9156,14 @@ constructor TOrmProperties.Create(aTable: TOrmClass);
end;
oftCreateTime:
begin
include(ComputeBeforeAddFieldsBits, i);
FieldBitSet(ComputeBeforeAddFieldsBits, i);
goto Small;
end;
oftModTime,
oftSessionUserID:
begin
include(ComputeBeforeAddFieldsBits, i);
include(ComputeBeforeUpdateFieldsBits, i);
FieldBitSet(ComputeBeforeAddFieldsBits, i);
FieldBitSet(ComputeBeforeUpdateFieldsBits, i);
goto Small;
end;
oftRecordVersion:
Expand All @@ -9179,15 +9179,15 @@ constructor TOrmProperties.Create(aTable: TOrmClass);
goto Simple;
else
begin
Small: include(SmallFieldsBits, i);
Small: FieldBitSet(SmallFieldsBits, i);
// this code follows NOT_SIMPLE_FIELDS/COPIABLE_FIELDS constants
Simple: SimpleFields[nSimple] := F;
inc(nSimple);
SimpleFieldSelect[nSimple].Field := i + 1; // [0]=ID
include(SimpleFieldsBits[ooSelect], i);
FieldBitSet(SimpleFieldsBits[ooSelect], i);
fSqlTableSimpleFieldsNoRowID := fSqlTableSimpleFieldsNoRowID + F.Name + ',';
fSqlTableRetrieveAllFields := fSqlTableRetrieveAllFields + ',' + F.Name;
Copiabl:include(CopiableFieldsBits, i);
Copiabl:FieldBitSet(CopiableFieldsBits, i);
CopiableFields[nCopiableFields] := F;
inc(nCopiableFields);
end;
Expand Down Expand Up @@ -10378,7 +10378,7 @@ function TOrmMapping.MapFields(
begin
fRowIDFieldName := InternalExternalPairs[i * 2 + 1];
if IdemPropNameU(fRowIDFieldName, 'ID') then
include(fFieldNamesMatchInternal, 0)
FieldBitSet(fFieldNamesMatchInternal, 0)
else // [0]=ID
exclude(fFieldNamesMatchInternal, 0);
end
Expand All @@ -10387,7 +10387,7 @@ function TOrmMapping.MapFields(
fExtFieldNames[f] := InternalExternalPairs[i * 2 + 1];
fExtFieldNamesUnQuotedSql[f] := UnQuotedSQLSymbolName(fExtFieldNames[f]);
if IdemPropNameU(fExtFieldNames[f], fProps.Fields.List[f].Name) then
include(fFieldNamesMatchInternal, f + 1)
FieldBitSet(fFieldNamesMatchInternal, f + 1)
else // [0]=ID [1..n]=fields[i-1]
exclude(fFieldNamesMatchInternal, f + 1);
end;
Expand Down
6 changes: 3 additions & 3 deletions src/orm/mormot.orm.rest.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2658,10 +2658,10 @@ function TOrmTableWritable.UpdatesToBatch(
var
c: TOrmClass;
rec: TOrm;
r: PtrInt;
r, f, p: PtrInt;
def, def32, bits: TFieldBits;
props: TIntegerDynArray;
upd, updlast, b, f, p: integer;
upd, updlast, b: integer;
begin
result := 0;
c := QueryRecordType;
Expand Down Expand Up @@ -2711,7 +2711,7 @@ function TOrmTableWritable.UpdatesToBatch(
if p < 0 then
raise EOrmTable.CreateUtf8(
'%.UpdatesToBatch: Unexpected %.%', [self, c, Results[f]]);
include(bits, p);
FieldBitSet(bits, p);
end;
b := b shl 1;
end;
Expand Down
4 changes: 2 additions & 2 deletions src/orm/mormot.orm.storage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -3837,7 +3837,7 @@ function TRestStorageInMemory.EngineUpdateFieldIncrement(
if fTrackChangesFieldBitsOffset <> 0 then
begin
FillZero(upd);
include(upd, P.PropertyIndex);
FieldBitSet(upd, P.PropertyIndex);
InternalTrackChangeUpdated(fValue[i], upd);
end;
fModified := true;
Expand Down Expand Up @@ -3922,7 +3922,7 @@ function TRestStorageInMemory.EngineUpdateField(TableModelIndex: integer;
(ndx <> 0) then
begin
FillZero(upd);
include(upd, ndx - 1);
FieldBitSet(upd, ndx - 1);
InternalTrackChangeUpdated(rec, upd);
end;
end;
Expand Down

0 comments on commit 927dad7

Please sign in to comment.