Skip to content
Permalink
Browse files

optimized ToVarUInt64()

  • Loading branch information...
Arnaud Bouchez
Arnaud Bouchez committed May 27, 2019
1 parent d676bb2 commit c0dc3550bf0a189a3317cbc3e35e0f2016a4b55c
Showing with 50 additions and 24 deletions.
  1. +40 −20 SynCommons.pas
  2. +9 −3 SynSelfTests.pas
  3. +1 −1 SynopseCommit.inc
result := result and $FFFFFFF or c;
end;

function ToVarInt64(Value: Int64; Dest: PByte): PByte;
begin // 0=0,1=1,2=-1,3=2,4=-2...
{$ifdef CPU32}
if Value<=0 then
// 0->0, -1->2, -2->4..
result := ToVarUInt64((-Value) shl 1,Dest) else
// 1->1, 2->3..
result := ToVarUInt64((Value shl 1)-1,Dest);
{$else}
if Value<=0 then
// 0->0, -1->2, -2->4..
Value := (-Value) shl 1 else
// 1->1, 2->3..
Value := (Value shl 1)-1;
result := ToVarUInt64(Value,Dest);
{$endif}
end;

function ToVarUInt64(Value: QWord; Dest: PByte): PByte;
label _1,_2,_3; // ugly but fast
var c: cardinal;
begin
c := Value;
if {$ifdef CPU32}PInt64Rec(@Value)^.Hi=0{$else}Value shr 32=0{$endif} then begin
result := ToVarUInt32(Value,Dest);
if c>$7f then begin // inlined result := ToVarUInt32(Value,Dest);
if c<$80 shl 7 then goto _1 else
if c<$80 shl 14 then goto _2 else
if c<$80 shl 21 then goto _3;
Dest^ := (c and $7F) or $80;
c := c shr 7;
inc(Dest);
_3: Dest^ := (c and $7F) or $80;
c := c shr 7;
inc(Dest);
_2: Dest^ := (c and $7F) or $80;
c := c shr 7;
inc(Dest);
_1: Dest^ := (c and $7F) or $80;
c := c shr 7;
inc(Dest);
end;
Dest^ := c;
inc(Dest);
result := Dest;
exit;
end;
c := Value;
PCardinal(Dest)^ := (c and $7F) or (((c shr 7)and $7F)shl 8) or
(((c shr 14)and $7F)shl 16) or (((c shr 21)and $7F)shl 24) or $80808080;
Value := Value shr 28;
Source := p;
end;

function ToVarInt64(Value: Int64; Dest: PByte): PByte;
begin // 0=0,1=1,2=-1,3=2,4=-2...
{$ifdef CPU32}
if Value<=0 then
// 0->0, -1->2, -2->4..
result := ToVarUInt64((-Value) shl 1,Dest) else
// 1->1, 2->3..
result := ToVarUInt64((Value shl 1)-1,Dest);
{$else}
if Value<=0 then
// 0->0, -1->2, -2->4..
Value := (-Value) shl 1 else
// 1->1, 2->3..
Value := (Value shl 1)-1;
result := ToVarUInt64(Value,Dest);
{$endif}
end;

function FromVarInt64(var Source: PByte): Int64;
var c,n: PtrUInt;
begin // 0=0,1=1,2=-1,3=2,4=-2...
@@ -4035,9 +4035,15 @@ procedure TTestLowLevelCommon.NumericalConversions;
l := GetInt64(pointer(s),err);
Check(err<>0);
case i of // validate some explicit ToVarUInt32/64 boundaries
9997: j := $00004000;
9998: j := $00200000;
9999: j := $10000000;
9991: j := $00003fff;
9992: j := $00004000;
9993: j := $00004001;
9994: j := $001fffff;
9995: j := $00200000;
9996: j := $00200001;
9997: j := $0fffffff;
9998: j := $10000000;
9999: j := $10000001;
end;
str(j,a);
Check(SysUtils.IntToStr(j)=string(a));
@@ -1 +1 @@
'1.18.5226'
'1.18.5227'

0 comments on commit c0dc355

Please sign in to comment.
You can’t perform that action at this time.