Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make memset() uses less error-prone. http://www.sqlite.org/cvstrac/tktview?tn=2036,35 describes some cases where we were passing memset() a length which was the sizeof a pointer, rather than the structure pointed to. Instead, wrap this idiom up in CLEAR() and SCRAMBLE() macros. (CVS 3488) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5878add0839f9c5bec77caae2361ec20 |
User & Date: | shess 2006-10-26 00:04:31.000 |
Context
2006-10-26
| ||
00:41 | Empty queries should get no results. My recent change ( http://www.sqlite.org/cvstrac/chngview?cn=3486 ) broke test fts2a-5.3. This change should make the expected result more obvious. (CVS 3489) (check-in: cde383eb46 user: shess tags: trunk) | |
00:04 | Make memset() uses less error-prone. http://www.sqlite.org/cvstrac/tktview?tn=2036,35 describes some cases where we were passing memset() a length which was the sizeof a pointer, rather than the structure pointed to. Instead, wrap this idiom up in CLEAR() and SCRAMBLE() macros. (CVS 3488) (check-in: 5878add083 user: shess tags: trunk) | |
2006-10-25
| ||
23:22 | Remove unreferenced local variable. (CVS 3487) (check-in: 2d3b22197c user: shess tags: trunk) | |
Changes
Changes to ext/fts2/fts2.c.
︙ | ︙ | |||
324 325 326 327 328 329 330 331 332 333 334 335 336 337 | /* MERGE_COUNT controls how often we merge segments (see comment at ** top of file). */ #define MERGE_COUNT 16 /* utility functions */ /* We may need up to VARINT_MAX bytes to store an encoded 64-bit integer. */ #define VARINT_MAX 10 /* Write a 64-bit variable-length integer to memory starting at p[0]. * The length of data written will be between 1 and VARINT_MAX bytes. * The number of bytes written is returned. */ | > > > > > > > > > > > > > > > > | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | /* MERGE_COUNT controls how often we merge segments (see comment at ** top of file). */ #define MERGE_COUNT 16 /* utility functions */ /* CLEAR() and SCRAMBLE() abstract memset() on a pointer to a single ** record to prevent errors of the form: ** ** my_function(SomeType *b){ ** memset(b, '\0', sizeof(b)); // sizeof(b)!=sizeof(*b) ** } */ /* TODO(shess) Obvious candidates for a header file. */ #define CLEAR(b) memset(b, '\0', sizeof(*(b))) #ifndef NDEBUG # define SCRAMBLE(b) memset(b, 0x55, sizeof(*(b))) #else # define SCRAMBLE(b) #endif /* We may need up to VARINT_MAX bytes to store an encoded 64-bit integer. */ #define VARINT_MAX 10 /* Write a 64-bit variable-length integer to memory starting at p[0]. * The length of data written will be between 1 and VARINT_MAX bytes. * The number of bytes written is returned. */ |
︙ | ︙ | |||
401 402 403 404 405 406 407 | pBuffer->pData = nCapacity==0 ? NULL : malloc(nCapacity); } static void dataBufferReset(DataBuffer *pBuffer){ pBuffer->nData = 0; } static void dataBufferDestroy(DataBuffer *pBuffer){ if( pBuffer->pData!=NULL ) free(pBuffer->pData); | < | < | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | pBuffer->pData = nCapacity==0 ? NULL : malloc(nCapacity); } static void dataBufferReset(DataBuffer *pBuffer){ pBuffer->nData = 0; } static void dataBufferDestroy(DataBuffer *pBuffer){ if( pBuffer->pData!=NULL ) free(pBuffer->pData); SCRAMBLE(pBuffer); } static void dataBufferExpand(DataBuffer *pBuffer, int nAddCapacity){ assert( nAddCapacity>0 ); /* TODO(shess) Consider expanding more aggressively. Note that the ** underlying malloc implementation may take care of such things for ** us already. */ |
︙ | ︙ | |||
619 620 621 622 623 624 625 | pReader->nElement = 0; pReader->iDocid = 0; /* Load the first element's data. There must be a first element. */ dlrStep(pReader); } static void dlrDestroy(DLReader *pReader){ | < | < | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | pReader->nElement = 0; pReader->iDocid = 0; /* Load the first element's data. There must be a first element. */ dlrStep(pReader); } static void dlrDestroy(DLReader *pReader){ SCRAMBLE(pReader); } #ifndef NDEBUG /* Verify that the doclist can be validly decoded. Also returns the ** last docid found because it's convenient in other assertions for ** DLWriter. */ |
︙ | ︙ | |||
699 700 701 702 703 704 705 | pWriter->iType = iType; #ifndef NDEBUG pWriter->has_prevDocid = 0; pWriter->iPrevDocid = 0; #endif } static void dlwDestroy(DLWriter *pWriter){ | < | < | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | pWriter->iType = iType; #ifndef NDEBUG pWriter->has_prevDocid = 0; pWriter->iPrevDocid = 0; #endif } static void dlwDestroy(DLWriter *pWriter){ SCRAMBLE(pWriter); } static void dlwAppend(DLWriter *pWriter, const char *pData, int nData){ #ifndef NDEBUG sqlite_int64 iDocid; int n; n = getVarint(pData, &iDocid); |
︙ | ︙ | |||
836 837 838 839 840 841 842 | pReader->iColumn = 0; pReader->iPosition = 0; pReader->iStartOffset = 0; pReader->iEndOffset = 0; plrStep(pReader); } static void plrDestroy(PLReader *pReader){ | < | < | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 | pReader->iColumn = 0; pReader->iPosition = 0; pReader->iStartOffset = 0; pReader->iEndOffset = 0; plrStep(pReader); } static void plrDestroy(PLReader *pReader){ SCRAMBLE(pReader); } /*******************************************************************/ /* PLWriter is used in constructing a document's position list. As a ** convenience, if iType is DL_DOCIDS, PLWriter becomes a no-op. ** ** plwInit - init for writing a document's poslist. |
︙ | ︙ | |||
921 922 923 924 925 926 927 | static PLWriter *plwNew(sqlite_int64 iDocid, DocListType iType){ PLWriter *pWriter = malloc(sizeof(PLWriter)); plwInit(pWriter, iDocid, iType); return pWriter; } static void plwDestroy(PLWriter *pWriter){ dataBufferDestroy(&pWriter->b); | < | < | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | static PLWriter *plwNew(sqlite_int64 iDocid, DocListType iType){ PLWriter *pWriter = malloc(sizeof(PLWriter)); plwInit(pWriter, iDocid, iType); return pWriter; } static void plwDestroy(PLWriter *pWriter){ dataBufferDestroy(&pWriter->b); SCRAMBLE(pWriter); } static void plwDelete(PLWriter *pWriter){ plwDestroy(pWriter); free(pWriter); } |
︙ | ︙ | |||
2348 2349 2350 2351 2352 2353 2354 | ** and snippet delimiters specification. */ /* Make a copy of the complete argv[][] array in a single allocation. ** The argv[][] array is read-only and transient. We can write to the ** copy in order to modify things and the copy is persistent. */ | | | 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | ** and snippet delimiters specification. */ /* Make a copy of the complete argv[][] array in a single allocation. ** The argv[][] array is read-only and transient. We can write to the ** copy in order to modify things and the copy is persistent. */ CLEAR(pSpec); for(i=n=0; i<argc; i++){ n += strlen(argv[i]) + 1; } azArg = malloc( sizeof(char*)*argc + n ); if( azArg==0 ){ return SQLITE_NOMEM; } |
︙ | ︙ | |||
2463 2464 2465 2466 2467 2468 2469 | int n; fulltext_vtab *v = 0; const sqlite3_tokenizer_module *m = NULL; char *schema; v = (fulltext_vtab *) malloc(sizeof(fulltext_vtab)); if( v==0 ) return SQLITE_NOMEM; | | | 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 | int n; fulltext_vtab *v = 0; const sqlite3_tokenizer_module *m = NULL; char *schema; v = (fulltext_vtab *) malloc(sizeof(fulltext_vtab)); if( v==0 ) return SQLITE_NOMEM; CLEAR(v); /* sqlite will initialize v->base */ v->db = db; v->zName = spec->zName; /* Freed when azColumn is freed */ v->nColumn = spec->nColumn; v->azContentColumn = spec->azContentColumn; spec->azContentColumn = 0; v->azColumn = spec->azColumn; |
︙ | ︙ | |||
2654 2655 2656 2657 2658 2659 2660 | */ static void queryClear(Query *q){ int i; for(i = 0; i < q->nTerms; ++i){ free(q->pTerms[i].pTerm); } free(q->pTerms); | | | | 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 | */ static void queryClear(Query *q){ int i; for(i = 0; i < q->nTerms; ++i){ free(q->pTerms[i].pTerm); } free(q->pTerms); CLEAR(q); } /* Free all of the dynamically allocated memory held by the ** Snippet */ static void snippetClear(Snippet *p){ free(p->aMatch); free(p->zOffset); free(p->zSnippet); CLEAR(p); } /* ** Append a single entry to the p->aMatch[] log. */ static void snippetAppendMatch( Snippet *p, /* Append the entry to this snippet */ int iCol, int iTerm, /* The column and query term */ |
︙ | ︙ | |||
3115 3116 3117 3118 3119 3120 3121 | ++q->nTerms; q->pTerms = realloc(q->pTerms, q->nTerms * sizeof(q->pTerms[0])); if( q->pTerms==0 ){ q->nTerms = 0; return; } t = &q->pTerms[q->nTerms - 1]; | | | 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 | ++q->nTerms; q->pTerms = realloc(q->pTerms, q->nTerms * sizeof(q->pTerms[0])); if( q->pTerms==0 ){ q->nTerms = 0; return; } t = &q->pTerms[q->nTerms - 1]; CLEAR(t); t->pTerm = malloc(nTerm+1); memcpy(t->pTerm, pTerm, nTerm); t->pTerm[nTerm] = 0; t->nTerm = nTerm; t->isOr = q->nextIsOr; q->nextIsOr = 0; t->iColumn = q->nextColumn; |
︙ | ︙ | |||
3640 3641 3642 3643 3644 3645 3646 | ** next level down the tree. */ static void interiorWriterInit(int iHeight, const char *pTerm, int nTerm, sqlite_int64 iChildBlock, InteriorWriter *pWriter){ InteriorBlock *block; assert( iHeight>0 ); | | | 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 | ** next level down the tree. */ static void interiorWriterInit(int iHeight, const char *pTerm, int nTerm, sqlite_int64 iChildBlock, InteriorWriter *pWriter){ InteriorBlock *block; assert( iHeight>0 ); CLEAR(pWriter); pWriter->iHeight = iHeight; #ifndef NDEBUG pWriter->iLastChildBlock = iChildBlock; #endif block = interiorBlockNew(iHeight, iChildBlock, pTerm, nTerm); pWriter->last = pWriter->first = block; |
︙ | ︙ | |||
3687 3688 3689 3690 3691 3692 3693 | while( block!=NULL ){ InteriorBlock *b = block; block = block->next; dataBufferDestroy(&b->term); dataBufferDestroy(&b->data); free(b); } | < | < | 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 | while( block!=NULL ){ InteriorBlock *b = block; block = block->next; dataBufferDestroy(&b->term); dataBufferDestroy(&b->data); free(b); } SCRAMBLE(pWriter); return SQLITE_OK; } /* If pWriter can fit entirely in ROOT_MAX, return it as the root info ** directly, leaving *piEndBlockid unchanged. Otherwise, flush ** pWriter to %_segments, building a new layer of interior nodes, and ** recursively ask for their root into. |
︙ | ︙ | |||
3754 3755 3756 3757 3758 3759 3760 | const char *pData; int nData; sqlite_int64 iBlockid; } InteriorReader; static void interiorReaderDestroy(InteriorReader *pReader){ | < | < | | 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 | const char *pData; int nData; sqlite_int64 iBlockid; } InteriorReader; static void interiorReaderDestroy(InteriorReader *pReader){ SCRAMBLE(pReader); } static void interiorReaderInit(const char *pData, int nData, InteriorReader *pReader){ int n; /* Require at least the leading flag byte */ assert( nData>0 ); assert( pData[0]!='\0' ); CLEAR(pReader); /* Decode the base blockid, and set the cursor to the first term. */ n = getVarint(pData+1, &pReader->iBlockid); assert( 1+n<=nData ); pReader->pData = pData+1+n; pReader->nData = nData-(1+n); } |
︙ | ︙ | |||
3856 3857 3858 3859 3860 3861 3862 | int has_parent; } LeafWriter; static void leafWriterInit(int iLevel, int idx, LeafWriter *pWriter){ char c[VARINT_MAX]; int n; | | | 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 | int has_parent; } LeafWriter; static void leafWriterInit(int iLevel, int idx, LeafWriter *pWriter){ char c[VARINT_MAX]; int n; CLEAR(pWriter); pWriter->iLevel = iLevel; pWriter->idx = idx; dataBufferInit(&pWriter->term, 32); /* Start out with a reasonably sized block, though it can grow. */ dataBufferInit(&pWriter->data, LEAF_MAX); |
︙ | ︙ | |||
4261 4262 4263 4264 4265 4266 4267 | const char *pData; /* data for current term. */ int nData; } LeafReader; static void leafReaderDestroy(LeafReader *pReader){ dataBufferDestroy(&pReader->term); | < | < | 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 | const char *pData; /* data for current term. */ int nData; } LeafReader; static void leafReaderDestroy(LeafReader *pReader){ dataBufferDestroy(&pReader->term); SCRAMBLE(pReader); } static int leafReaderAtEnd(LeafReader *pReader){ return pReader->nData<=0; } /* Access the current term. */ |
︙ | ︙ | |||
4300 4301 4302 4303 4304 4305 4306 | static void leafReaderInit(const char *pData, int nData, LeafReader *pReader){ int nTerm, n; assert( nData>0 ); assert( pData[0]=='\0' ); | | | 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 | static void leafReaderInit(const char *pData, int nData, LeafReader *pReader){ int nTerm, n; assert( nData>0 ); assert( pData[0]=='\0' ); CLEAR(pReader); /* Read the first term, skipping the header byte. */ n = getVarint32(pData+1, &nTerm); dataBufferInit(&pReader->term, nTerm); dataBufferReplace(&pReader->term, pData+1+n, nTerm); /* Position after the first term. */ |
︙ | ︙ | |||
4396 4397 4398 4399 4400 4401 4402 | static int leavesReaderAtEnd(LeavesReader *pReader){ return pReader->eof; } static void leavesReaderDestroy(LeavesReader *pReader){ leafReaderDestroy(&pReader->leafReader); dataBufferDestroy(&pReader->rootData); | < | < | | 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 | static int leavesReaderAtEnd(LeavesReader *pReader){ return pReader->eof; } static void leavesReaderDestroy(LeavesReader *pReader){ leafReaderDestroy(&pReader->leafReader); dataBufferDestroy(&pReader->rootData); SCRAMBLE(pReader); } /* Initialize pReader with the given root data (if iStartBlockid==0 ** the leaf data was entirely contained in the root), or from the ** stream of blocks between iStartBlockid and iEndBlockid, inclusive. */ static int leavesReaderInit(fulltext_vtab *v, int idx, sqlite_int64 iStartBlockid, sqlite_int64 iEndBlockid, const char *pRootData, int nRootData, LeavesReader *pReader){ CLEAR(pReader); pReader->idx = idx; dataBufferInit(&pReader->rootData, 0); if( iStartBlockid==0 ){ /* Entire leaf level fit in root data. */ dataBufferReplace(&pReader->rootData, pRootData, nRootData); leafReaderInit(pReader->rootData.pData, pReader->rootData.nData, |
︙ | ︙ |