Skip to content

Commit 76ace06

Browse files
author
Arnaud Bouchez
committed
optimized IKeyValue<>.TryGetValue
- with a new SMALLGENERICS conditional
1 parent 05da780 commit 76ace06

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/core/mormot.core.collections.pas

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ interface
4343
// TDynArray and TSynDictionary, then specialization helps a little more
4444
{.$define NOSPECIALIZE}
4545

46+
// you could try to define this conditional to generate even less code, which
47+
// may be slightly slower - perhaps not really noticeable on production
48+
{.$define SMALLGENERICS}
4649

4750
uses
4851
classes,
@@ -591,6 +594,7 @@ TIKeyValueParent = class(TInterfacedObject)
591594
function GetValueTypeInfo: PRttiInfo;
592595
procedure AddOne(key, value: pointer);
593596
procedure GetDefault(value: pointer);
597+
procedure GetDefaultAndUnlock(value: pointer);
594598
function GetCapacity: integer;
595599
procedure SetCapacity(value: integer);
596600
function GetTimeOutSeconds: cardinal;
@@ -654,6 +658,7 @@ TIKeyValue<TKey, TValue> = class(
654658
function TryAdd(const key: TKey; const value: TValue): boolean;
655659
/// IKeyValue<> method to search a key and return its associated value
656660
function TryGetValue(const key: TKey; var value: TValue): boolean;
661+
{$ifndef SMALLGENERICS} inline; {$endif}
657662
/// IKeyValue<> method to search a key or a supplied default
658663
function GetValueOrDefault(const key: TKey;
659664
const defaultValue: TValue): TValue;
@@ -1369,6 +1374,14 @@ procedure TIKeyValueParent.AddOne(key, value: pointer);
13691374
end;
13701375

13711376
procedure TIKeyValueParent.GetDefault(value: pointer);
1377+
begin
1378+
if kvoDefaultIfNotFound in fOptions then
1379+
fData.Values.ItemClear(value)
1380+
else
1381+
raise EIKeyValue.CreateUtf8('%.GetItem: key not found', [self]);
1382+
end;
1383+
1384+
procedure TIKeyValueParent.GetDefaultAndUnlock(value: pointer);
13721385
begin
13731386
if kvoDefaultIfNotFound in fOptions then
13741387
fData.Values.ItemClear(value)
@@ -1437,19 +1450,26 @@ procedure TIKeyValueParent.ReadUnLock;
14371450
{ TIKeyValue<TKey, TValue> }
14381451

14391452
function TIKeyValue<TKey, TValue>.GetItem(const key: TKey): TValue;
1453+
{$ifdef SMALLGENERICS}
1454+
begin
1455+
if not fData.FindAndCopy(key, result, fHasTimeout) then
1456+
GetDefault(@result)
1457+
end;
1458+
{$else}
14401459
var
1441-
ndx: PtrInt; // slightly more verbose but faster than FindAndCopy
1460+
ndx: PtrInt; // slightly more verbose but faster than plain FindAndCopy
14421461
begin
14431462
if fHasLock then
14441463
fData.Safe^.ReadLock;
14451464
ndx := fData.Find(key, fHasTimeout);
14461465
if ndx < 0 then
1447-
GetDefault(@result) // may ReadUnLock and raise EIKeyValue
1466+
GetDefaultAndUnlock(@result) // may ReadUnLock and raise EIKeyValue
14481467
else
14491468
result := TArray<TValue>(fData.Values.Value^)[ndx]; // very efficient
14501469
if fHasLock then
14511470
fData.Safe^.ReadUnLock;
14521471
end;
1472+
{$endif SMALLGENERICS}
14531473

14541474
function TIKeyValue<TKey, TValue>.GetKey(ndx: PtrInt): TKey;
14551475
begin
@@ -1481,14 +1501,37 @@ function TIKeyValue<TKey, TValue>.TryAdd(const key: TKey;
14811501

14821502
function TIKeyValue<TKey, TValue>.TryGetValue(const key: TKey;
14831503
var value: TValue): boolean;
1504+
{$ifdef SMALLGENERICS}
14841505
begin
14851506
result := fData.FindAndCopy(key, value, fHasTimeout);
14861507
end;
1508+
{$else}
1509+
var
1510+
ndx: PtrInt;
1511+
begin
1512+
if fHasLock then
1513+
fData.Safe^.ReadLock;
1514+
ndx := fData.Find(key, fHasTimeout);
1515+
if ndx >= 0 then
1516+
begin
1517+
value := TArray<TValue>(fData.Values.Value^)[ndx];
1518+
result := true;
1519+
end
1520+
else
1521+
result := false;
1522+
if fHasLock then
1523+
fData.Safe^.ReadUnLock;
1524+
end;
1525+
{$endif SMALLGENERICS}
14871526

14881527
function TIKeyValue<TKey, TValue>.GetValueOrDefault(const key: TKey;
14891528
const defaultValue: TValue): TValue;
14901529
begin
1530+
{$ifdef SMALLGENERICS}
14911531
if not fData.FindAndCopy(key, result, fHasTimeout) then
1532+
{$else}
1533+
if not TryGetValue(key, result{%H-}) then
1534+
{$endif SMALLGENERICS}
14921535
result := defaultValue;
14931536
end;
14941537

src/mormot.commit.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
'2.1.6315'
1+
'2.1.6316'

0 commit comments

Comments
 (0)