]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
New varint encoding gives a maximum varint length of 9 instead of 10. (CVS 1395)
authordrh <drh@noemail.net>
Tue, 18 May 2004 15:57:42 +0000 (15:57 +0000)
committerdrh <drh@noemail.net>
Tue, 18 May 2004 15:57:42 +0000 (15:57 +0000)
FossilOrigin-Name: 61bdb53a363644074d01682fab8220078523676b

manifest
manifest.uuid
src/test3.c
src/util.c
test/btree.test
test/varint.test [new file with mode: 0644]

index 9cd26e88f6d128402eeac0cd202427e930dfb291..cb2dc6ce447464f5a1750ae5d73ca30bc448249d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Additional\sdebugging\soutput\sfrom\sbtree.c\s(CVS\s1394)
-D 2004-05-18T12:50:17
+C New\svarint\sencoding\sgives\sa\smaximum\svarint\slength\sof\s9\sinstead\sof\s10.\s(CVS\s1395)
+D 2004-05-18T15:57:42
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -54,14 +54,14 @@ F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1
 F src/test1.c 12ef76b8aaba4408422f21f269256b630d4dd627
 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
-F src/test3.c 0752af52c02d6b0053809ecf36adbdc81b90a402
+F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
 F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296
 F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a
 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
 F src/update.c 0cc7291dd0e0f82cf93085e49c973e8ef9e51fd5
 F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f
-F src/util.c f9511ffba78e6cf71a28774c2820d7750b5bacdf
+F src/util.c c2e92ba9bb3b10154ceea6f24bd28e17aa43e428
 F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
 F src/vdbe.c 5cc6e41f2c9f24bbbf591ca538c097c0f7b41a3d
 F src/vdbe.h 1d0d0b5741c7f46ab372a95a4305fed0ae09d466
@@ -75,7 +75,7 @@ F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
 F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
-F test/btree.test d865f501a5aa818d138be06a007b9457053ca701
+F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125
 F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
 F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
@@ -149,6 +149,7 @@ F test/types2.test b9b528e5ec6c5d8ee149ff27d48a23ce3f6075d9
 F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b
 F test/update.test b29bd9061a1150426dab6959806fcc73a41b1217
 F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a
+F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
 F test/version.test 2ba212ba06380e65e476bdf2fcd390e8b05af5a0
 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53
 F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b
@@ -192,7 +193,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P ad4a964158ba9ca9d221cf7ea0439577f3894890
-R 3fbe35ebb1dc80de72b327b868459b56
+P b2def1852c5357629cf69f0071963f9883074a70
+R fcc6388df2907a9562ab1f06c18ae1d4
 U drh
-Z 3b96c3a7f2a622caf172e143f2195e19
+Z e7da228fbe2303ffbc30d46f572dedcc
index af49a8ef96f851431c1262adbe1d2cc1935e7b35..d02ce2d71245d240d0c006de1ccf61bd21395e4e 100644 (file)
@@ -1 +1 @@
-b2def1852c5357629cf69f0071963f9883074a70
\ No newline at end of file
+61bdb53a363644074d01682fab8220078523676b
\ No newline at end of file
index 777dbc46e98248ceb2b3bf553163d884dafa1b04..0ee59bbcf0e32e208d65a599a16d58e076b6d8b6 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.37 2004/05/14 16:50:06 drh Exp $
+** $Id: test3.c,v 1.38 2004/05/18 15:57:42 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -1167,7 +1167,7 @@ static int btree_varint_test(
 ){
   u32 start, mult, count, incr;
   u64 in, out;
-  int n1, n2, i;
+  int n1, n2, i, j;
   unsigned char zBuf[100];
   if( argc!=5 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
@@ -1181,22 +1181,32 @@ static int btree_varint_test(
   in = start;
   in *= mult;
   for(i=0; i<count; i++){
+    char zErr[200];
     n1 = sqlite3PutVarint(zBuf, in);
     if( n1>9 || n1<1 ){
-      Tcl_AppendResult(interp, "PutVarint returned value out of range", 0);
+      sprintf(zErr, "PutVarint returned %d - should be between 1 and 9", n1);
+      Tcl_AppendResult(interp, zErr, 0);
       return TCL_ERROR;
     }
     n2 = sqlite3GetVarint(zBuf, &out);
     if( n1!=n2 ){
-      Tcl_AppendResult(interp, \
-         "GetVarint returned value different from PutVarint", 0);
+      sprintf(zErr, "PutVarint returned %d and GetVarint returned %d", n1, n2);
+      Tcl_AppendResult(interp, zErr, 0);
       return TCL_ERROR;
     }
     if( in!=out ){
-      Tcl_AppendResult(interp, \
-         "Value read is different from value written", 0);
+      sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx", in, out);
+      Tcl_AppendResult(interp, zErr, 0);
       return TCL_ERROR;
     }
+
+    /* In order to get realistic timings, run getVarint 19 more times.
+    ** This is because getVarint is called about 20 times more often
+    ** than putVarint.
+    */
+    for(j=0; j<19; j++){
+      sqlite3GetVarint(zBuf, &out);
+    }
     in += incr;
   }
   return TCL_OK;
index c7437aad0cfa7873b84fb7c3caa2184668aa92a7..9853c8dae96447e88c98d138673675abcfdb730a 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.82 2004/05/14 16:50:06 drh Exp $
+** $Id: util.c,v 1.83 2004/05/18 15:57:42 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -1139,6 +1139,25 @@ int sqlite3SafetyCheck(sqlite *db){
   return 0;
 }
 
+/*
+** The variable-length integer encoding is as follows:
+**
+** KEY:
+**         A = 0xxxxxxx    7 bits of data and one flag bit
+**         B = 1xxxxxxx    7 bits of data and one flag bit
+**         C = xxxxxxxx    8 bits of data
+**
+**  7 bits - A
+** 14 bits - BA
+** 21 bits - BBA
+** 28 bits - BBBA
+** 35 bits - BBBBA
+** 42 bits - BBBBBA
+** 49 bits - BBBBBBA
+** 56 bits - BBBBBBBA
+** 64 bits - BBBBBBBBC
+*/
+
 /*
 ** Write a 64-bit variable-length integer to memory starting at p[0].
 ** The length of data write will be between 1 and 9 bytes.  The number
@@ -1146,17 +1165,28 @@ int sqlite3SafetyCheck(sqlite *db){
 **
 ** A variable-length integer consists of the lower 7 bits of each byte
 ** for all bytes that have the 8th bit set and one byte with the 8th
-** bit clear.
+** bit clear.  Except, if we get to the 9th byte, it stores the full
+** 8 bits and is the last byte.
 */
 int sqlite3PutVarint(unsigned char *p, u64 v){
   int i, j, n;
   u8 buf[10];
+  if( v & 0xff00000000000000 ){
+    p[8] = v;
+    v >>= 8;
+    for(i=7; i>=0; i--){
+      p[i] = (v & 0x7f) | 0x80;
+      v >>= 7;
+    }
+    return 9;
+  }    
   n = 0;
   do{
     buf[n++] = (v & 0x7f) | 0x80;
     v >>= 7;
   }while( v!=0 );
   buf[0] &= 0x7f;
+  assert( n<=9 );
   for(i=0, j=n-1; j>=0; j--, i++){
     p[i] = buf[j];
   }
@@ -1199,6 +1229,10 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
   n = 4;
   do{
     c = p[n++];
+    if( n==9 ){
+      x64 = (x64<<8) | c;
+      break;
+    }
     x64 = (x64<<7) | (c&0x7f);
   }while( (c & 0x80)!=0 );
   *v = x64;
@@ -1213,7 +1247,7 @@ int sqlite3GetVarint32(const unsigned char *p, u32 *v){
   int n = 1;
   unsigned char c = p[0];
   u32 x = c & 0x7f;
-  while( (c & 0x80)!=0 ){
+  while( (c & 0x80)!=0 && n<9 ){
     c = p[n++];
     x = (x<<7) | (c & 0x7f);
   }
@@ -1230,6 +1264,6 @@ int sqlite3VarintLen(u64 v){
   do{
     i++;
     v >>= 7;
-  }while( v!=0 );
+  }while( v!=0 && i<9 );
   return i;
 }
index c5ca030e16e42f18d4ff32bfb2eea92dce533295..b7b2ec8ea7ce235f61cd2de20e87421247b5ef8f 100644 (file)
 # This file implements regression tests for SQLite library.  The
 # focus of this script is btree database backend
 #
-# $Id: btree.test,v 1.24 2004/05/14 16:50:07 drh Exp $
+# $Id: btree.test,v 1.25 2004/05/18 15:57:42 drh Exp $
 
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
-# Testing of varint reading writing.
-#
-do_test btree-0.1 {
-  btree_varint_test 0 0 500 1
-} {}
-do_test btree-0.2 {
-  btree_varint_test 1024 1 500 1
-} {}
-do_test btree-0.3 {
-  btree_varint_test -1 1 500 1
-} {}
-do_test btree-0.4 {
-  btree_varint_test -1 100000 500 1
-} {}
-
 # Basic functionality.  Open and close a database.
 #
 do_test btree-1.1 {
diff --git a/test/varint.test b/test/varint.test
new file mode 100644 (file)
index 0000000..974e88f
--- /dev/null
@@ -0,0 +1,32 @@
+# 2001 September 15
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this script is variable-length integer encoding scheme.
+#
+# $Id: varint.test,v 1.1 2004/05/18 15:57:42 drh Exp $
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Test reading and writing of varints.
+#
+set cnt 0
+foreach start {0 100 10000 1000000 0x10000000} {
+  foreach mult {1 0x10 0x100 0x1000 0x10000 0x100000 0x1000000 0x10000000} {
+    foreach incr {1 500 10000 50000000} {
+      incr cnt
+      do_test varint-1.$cnt {
+        btree_varint_test $start $mult 5000 $incr
+      } {}
+    }
+  }
+}