示例#1
0
/*
** Decode a single doclist and display the results on stdout.
*/
static void decodeDoclist(
    const unsigned char *aData,   /* Content to print */
    int nData                     /* Number of bytes of content */
) {
    sqlite3_int64 iPrevDocid = 0;
    sqlite3_int64 iDocid;
    sqlite3_int64 iPos;
    sqlite3_int64 iPrevPos = 0;
    sqlite3_int64 iCol;
    int i = 0;

    while( i<nData ) {
        i += getVarint(aData+i, &iDocid);
        printf("docid %lld col0", iDocid+iPrevDocid);
        iPrevDocid += iDocid;
        iPrevPos = 0;
        while( 1 ) {
            i += getVarint(aData+i, &iPos);
            if( iPos==1 ) {
                i += getVarint(aData+i, &iCol);
                printf(" col%lld", iCol);
                iPrevPos = 0;
            } else if( iPos==0 ) {
                printf("\n");
                break;
            } else {
                iPrevPos += iPos - 2;
                printf(" %lld", iPrevPos);
            }
        }
    }
}
示例#2
0
static int leafCursorCellColInfo(RecoverLeafCursor *pCursor,
                                 unsigned iCol, u64 *piColType,
                                 unsigned char **ppBase, int *pbFree){
  const unsigned char *pRecordHeader;  
  u64 nRecordHeaderBytes;              
  unsigned nRead;                      
  u64 iColEndOffset;                   
  unsigned nColsSkipped;               
  u64 iSerialType;                     

  if( iCol>=pCursor->nRecordCols ){
    *piColType = 0;
    if( ppBase ){
      *ppBase = 0;
      *pbFree = 0;
    }
    return SQLITE_OK;
  }

  
  pRecordHeader = pCursor->pRecordHeader;
  if( !checkVarint(pRecordHeader, pCursor->nRecordHeaderBytes) ){
    return SQLITE_CORRUPT;
  }

  nRead = getVarint(pRecordHeader, &nRecordHeaderBytes);
  assert( nRecordHeaderBytes==pCursor->nRecordHeaderBytes );

  iColEndOffset = 0;
  nColsSkipped = 0;
  while( nColsSkipped<=iCol && nRead<nRecordHeaderBytes ){
    if( !checkVarint(pRecordHeader + nRead, nRecordHeaderBytes - nRead) ){
      return SQLITE_CORRUPT;
    }
    nRead += getVarint(pRecordHeader + nRead, &iSerialType);
    iColEndOffset += SerialTypeLength(iSerialType);
    nColsSkipped++;
  }

  
  if( nRecordHeaderBytes+iColEndOffset>pCursor->nRecordBytes ){
    return SQLITE_CORRUPT;
  }

  *piColType = iSerialType;
  if( ppBase ){
    const u32 nColBytes = SerialTypeLength(iSerialType);

    
    const unsigned iColOffset = nRecordHeaderBytes+iColEndOffset-nColBytes;

    return overflowGetSegment(pCursor->pPage, pCursor->iRecordOffset,
                              pCursor->nLocalRecordBytes, pCursor->pOverflow,
                              iColOffset, nColBytes, ppBase, pbFree);
  }
  return SQLITE_OK;
}
示例#3
0
static int getVarint32(const char *p, int *pi){
 sqlite_int64 i;
 int ret = getVarint(p, &i);
 *pi = (int) i;
 assert( *pi==i );
 return ret;
}
示例#4
0
/* Read the next docid. */
static sqlite_int64 readDocid(DocListReader *pReader){
  sqlite_int64 ret;
  assert( !readerAtEnd(pReader) );
  pReader->p += getVarint(pReader->p, &ret);
  pReader->iLastPos = 0;
  return ret;
}
示例#5
0
/* Show the content of the %_stat table
*/
static void showStat(sqlite3 *db, const char *zTab) {
    sqlite3_stmt *pStmt;
    pStmt = prepare(db, "SELECT id, value FROM '%q_stat'", zTab);
    while( sqlite3_step(pStmt)==SQLITE_ROW ) {
        printf("stat[%d] =", sqlite3_column_int(pStmt, 0));
        switch( sqlite3_column_type(pStmt, 1) ) {
        case SQLITE_INTEGER: {
            printf(" %d\n", sqlite3_column_int(pStmt, 1));
            break;
        }
        case SQLITE_BLOB: {
            unsigned char *x = (unsigned char*)sqlite3_column_blob(pStmt, 1);
            int len = sqlite3_column_bytes(pStmt, 1);
            int i = 0;
            sqlite3_int64 v;
            while( i<len ) {
                i += getVarint(x, &v);
                printf(" %lld", v);
            }
            printf("\n");
            break;
        }
        }
    }
    sqlite3_finalize(pStmt);
}
示例#6
0
/*
** Decode a single segment block and display the results on stdout.
*/
static void decodeSegment(
    const unsigned char *aData,   /* Content to print */
    int nData                     /* Number of bytes of content */
) {
    sqlite3_int64 iChild = 0;
    sqlite3_int64 iPrefix;
    sqlite3_int64 nTerm;
    sqlite3_int64 n;
    sqlite3_int64 iDocsz;
    int iHeight;
    sqlite3_int64 i = 0;
    int cnt = 0;
    char zTerm[1000];

    i += getVarint(aData, &n);
    iHeight = (int)n;
    printf("height: %d\n", iHeight);
    if( iHeight>0 ) {
        i += getVarint(aData+i, &iChild);
        printf("left-child: %lld\n", iChild);
    }
    while( i<nData ) {
        if( (cnt++)>0 ) {
            i += getVarint(aData+i, &iPrefix);
        } else {
            iPrefix = 0;
        }
        i += getVarint(aData+i, &nTerm);
        if( iPrefix+nTerm+1 >= sizeof(zTerm) ) {
            fprintf(stderr, "term to long\n");
            exit(1);
        }
        memcpy(zTerm+iPrefix, aData+i, (size_t)nTerm);
        zTerm[iPrefix+nTerm] = 0;
        i += nTerm;
        if( iHeight==0 ) {
            i += getVarint(aData+i, &iDocsz);
            printf("term: %-25s doclist %7lld bytes offset %lld\n", zTerm, iDocsz, i);
            i += iDocsz;
        } else {
            printf("term: %-25s child %lld\n", zTerm, ++iChild);
        }
    }
}
示例#7
0
/*
** Read a single varint from file-descriptor pFile. Return SQLITE_OK if
** successful, or an SQLite error code if some error occurs.
**
** The value of *piOffset when this function is called is used as the
** byte offset in file pFile from whence to read the varint. If successful
** (i.e. if no IO error occurs), then *piOffset is set to the offset of
** the first byte past the end of the varint before returning. *piVal is
** set to the integer value read. If an error occurs, the final values of
** both *piOffset and *piVal are undefined.
*/
static int vdbeSorterReadVarint(
  sqlite3_file *pFile,            /* File to read from */
  i64 *piOffset,                  /* IN/OUT: Read offset in pFile */
  i64 *piVal                      /* OUT: Value read from file */
){
  u8 aVarint[9];                  /* Buffer large enough for a varint */
  i64 iOff = *piOffset;           /* Offset in file to read from */
  int rc;                         /* Return code */

  rc = sqlite3OsRead(pFile, aVarint, 9, iOff);
  if( rc==SQLITE_OK ){
    *piOffset += getVarint(aVarint, (u64 *)piVal);
  }

  return rc;
}
/*
** usage:   varint_test  START  MULTIPLIER  COUNT  INCREMENT
**
** This command tests the putVarint() and getVarint()
** routines, both for accuracy and for speed.
**
** An integer is written using putVarint() and read back with
** getVarint() and varified to be unchanged.  This repeats COUNT
** times.  The first integer is START*MULTIPLIER.  Each iteration
** increases the integer by INCREMENT.
**
** This command returns nothing if it works.  It returns an error message
** if something goes wrong.
*/
static int btree_varint_test(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  u32 start, mult, count, incr;
  u64 in, out;
  int n1, n2, i, j;
  unsigned char zBuf[100];
  if( argc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " START MULTIPLIER COUNT INCREMENT\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR;
  if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR;
  if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR;
  if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR;
  in = start;
  in *= mult;
  for(i=0; i<count; i++){
    char zErr[200];
    n1 = putVarint(zBuf, in);
    if( n1>9 || n1<1 ){
      sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1);
      Tcl_AppendResult(interp, zErr, 0);
      return TCL_ERROR;
    }
    n2 = getVarint(zBuf, &out);
    if( n1!=n2 ){
      sprintf(zErr, "putVarint returned %d and getVarint returned %d", n1, n2);
      Tcl_AppendResult(interp, zErr, 0);
      return TCL_ERROR;
    }
    if( in!=out ){
      sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx", in, out);
      Tcl_AppendResult(interp, zErr, 0);
      return TCL_ERROR;
    }
    if( (in & 0xffffffff)==in ){
      u32 out32;
      n2 = getVarint32(zBuf, out32);
      out = out32;
      if( n1!=n2 ){
        sprintf(zErr, "putVarint returned %d and GetVarint32 returned %d", 
                  n1, n2);
        Tcl_AppendResult(interp, zErr, 0);
        return TCL_ERROR;
      }
      if( in!=out ){
        sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx from GetVarint32",
            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++){
      getVarint(zBuf, &out);
    }
    in += incr;
  }
  return TCL_OK;
}
示例#9
0
/* Peek at the next docid without advancing the read pointer. */
static sqlite_int64 peekDocid(DocListReader *pReader){
  sqlite_int64 ret;
  assert( !readerAtEnd(pReader) );
  getVarint(pReader->p, &ret);
  return ret;
}
示例#10
0
static int leafCursorCellDecode(RecoverLeafCursor *pCursor){
  const unsigned char *pPageHeader;  
  const unsigned char *pCellOffsets; 
  unsigned iCellOffset;              
  const unsigned char *pCell;        
  unsigned nCellMaxBytes;            
  unsigned iEndOffset;               
  u64 nRecordBytes;                  
  u64 iRowid;                        
  unsigned nRead;                    
  unsigned nRecordHeaderRead;        
  u64 nRecordHeaderBytes;            
  unsigned nRecordCols;              
  u64 nRecordColBytes;               
  unsigned i;
  int rc;

  assert( pCursor->iCell<pCursor->nCells );

  leafCursorDestroyCellData(pCursor);

  
  pPageHeader = PageHeader(pCursor->pPage);
  pCellOffsets = pPageHeader + knPageLeafHeaderBytes;
  iCellOffset = decodeUnsigned16(pCellOffsets + pCursor->iCell*2);
  if( iCellOffset>=pCursor->nPageSize ){
    return ValidateError();
  }

  pCell = PageData(pCursor->pPage, iCellOffset);
  nCellMaxBytes = pCursor->nPageSize - iCellOffset;

  if( !checkVarints(pCell, nCellMaxBytes, 3) ){
    return ValidateError();
  }

  nRead = getVarint(pCell, &nRecordBytes);
  assert( iCellOffset+nRead<=pCursor->nPageSize );
  pCursor->nRecordBytes = nRecordBytes;

  nRead += getVarint(pCell + nRead, &iRowid);
  assert( iCellOffset+nRead<=pCursor->nPageSize );
  pCursor->iRowid = (i64)iRowid;

  pCursor->iRecordOffset = iCellOffset + nRead;

  rc = overflowMaybeCreate(pCursor->pPage, pCursor->nPageSize,
                           pCursor->iRecordOffset, pCursor->nRecordBytes,
                           &pCursor->nLocalRecordBytes,
                           &pCursor->pOverflow);
  if( rc!=SQLITE_OK ){
    return ValidateError();
  }

  
  iEndOffset = pCursor->iRecordOffset + pCursor->nLocalRecordBytes;
  for( i=0; i<pCursor->nCells; ++i ){
    const unsigned iOtherOffset = decodeUnsigned16(pCellOffsets + i*2);
    if( iOtherOffset>iCellOffset && iOtherOffset<iEndOffset ){
      return ValidateError();
    }
  }

  nRecordHeaderRead = getVarint(pCell + nRead, &nRecordHeaderBytes);
  assert( nRecordHeaderBytes<=nRecordBytes );
  pCursor->nRecordHeaderBytes = nRecordHeaderBytes;

  
  rc = overflowGetSegment(pCursor->pPage,
                          pCursor->iRecordOffset, pCursor->nLocalRecordBytes,
                          pCursor->pOverflow, 0, nRecordHeaderBytes,
                          &pCursor->pRecordHeader, &pCursor->bFreeRecordHeader);
  if( rc!=SQLITE_OK ){
    return ValidateError();
  }

  
  nRecordCols = 0;
  nRecordColBytes = 0;
  while( nRecordHeaderRead<nRecordHeaderBytes ){
    u64 iSerialType;  
    if( !checkVarint(pCursor->pRecordHeader + nRecordHeaderRead,
                     nRecordHeaderBytes - nRecordHeaderRead) ){
      return ValidateError();
    }
    nRecordHeaderRead += getVarint(pCursor->pRecordHeader + nRecordHeaderRead,
                                   &iSerialType);
    if( iSerialType==10 || iSerialType==11 ){
      return ValidateError();
    }
    nRecordColBytes += SerialTypeLength(iSerialType);
    nRecordCols++;
  }
  pCursor->nRecordCols = nRecordCols;

  
  if( nRecordHeaderRead!=nRecordHeaderBytes ){
    return ValidateError();
  }

  
  if( nRecordHeaderBytes+nRecordColBytes!=nRecordBytes ){
    return ValidateError();
  }

  return SQLITE_OK;
}