コード例 #1
0
ファイル: fulltext.c プロジェクト: bhanug/likewise-open
/* Read the posting list for [zTerm]; AND it with the doclist [in] to
 * produce the doclist [out], using the given offset [iOffset] for phrase
 * matching.
 * (*pSelect) is used to hold an SQLite statement used inside this function;
 * the caller should initialize *pSelect to NULL before the first call.
 */
static int query_merge(fulltext_vtab *v, sqlite3_stmt **pSelect,
                       const char *zTerm,
                       DocList *pIn, int iOffset, DocList *out){
  int rc;
  DocListMerge merge;

  if( pIn!=NULL && !pIn->nData ){
    /* If [pIn] is already empty, there's no point in reading the
     * posting list to AND it in; return immediately. */
      return SQLITE_OK;
  }

  rc = term_select_doclist(v, zTerm, -1, pSelect);
  if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ) return rc;

  mergeInit(&merge, pIn, iOffset, out);
  while( rc==SQLITE_ROW ){
    DocList block;
    docListInit(&block, DL_POSITIONS_OFFSETS,
                sqlite3_column_blob(*pSelect, 0),
                sqlite3_column_bytes(*pSelect, 0));
    mergeBlock(&merge, &block);
    docListDestroy(&block);

    rc = sqlite3_step(*pSelect);
    if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
      return rc;
    }
  }

  return SQLITE_OK;
}
コード例 #2
0
static void mergeBlock(int mergeIdx, metadata_t *currBlock) {
	// base case
	if (mergeIdx == 7) {
		return;
	}
	// add the current block to the freelist
	if (freelist[mergeIdx] != NULL) { // if there is any other blocks in the freelist[mergeIdx]
		freelist[mergeIdx]->prev = currBlock;
		currBlock->next = freelist[mergeIdx];
	}
	freelist[mergeIdx] = currBlock;
    // calculate the potential address (metadata address) of the buddy block
    metadata_t *buddyBlock = (metadata_t*) ((char*)currBlock + currBlock->size);
    if (buddyBlock == NULL) {
    	return;
    }
    // see if the buddy is free
    if (buddyBlock->in_use) {
    	return;
    }
    // see if two blocks are of the same size
    if (currBlock->size != buddyBlock->size) {
        return;
    }
    // see if two blocks are paired correctly
    int shift = (int)log2(currBlock->size) + 1;
    int currBit = ((int)((char*)currBlock-(char*)heap)) >> shift & 1;
    int buddyBit = ((int)((char*)buddyBlock-(char*)heap)) >> shift & 1;
    if (currBit != buddyBit) {
        return;
    }

    /*~~~~~~~if all criteira are met, merge the two blocks~~~~~~~*/

    currBlock->size *= 2;
    currBlock->in_use = 0;
    currBlock->next = NULL;
    currBlock->prev = NULL;
    // remove the two blocks from the free list
    if (buddyBlock->prev != NULL) {
    	buddyBlock->prev->next = buddyBlock->next;
    	if (buddyBlock->next != NULL) {
    		buddyBlock->next->prev = buddyBlock->prev;
    	}
    	buddyBlock->prev = NULL;
    	buddyBlock->next = NULL;
    	buddyBlock = NULL;
    }
    if (currBlock->next != NULL) {
    	freelist[mergeIdx] = currBlock->next;
    } else {
    	freelist[mergeIdx] = NULL;
    }
    // recursion occurs here!
    mergeBlock(mergeIdx++, currBlock);
}
コード例 #3
0
void my_free(void* ptr)
{
    // get the address of the metadata
    char *p = (char*) ptr;
    // get the address of the current 
    metadata_t *currBlock = (metadata_t*)(p - sizeof(metadata_t));
    // detect double free
    if (!currBlock->in_use) {
        ERRNO = DOUBLE_FREE_DETECTED;
        return;
    } else {
        currBlock->in_use = 0;
    }
    // recursively merge blocks if possible
    int idx = getIdx(currBlock->size);
    mergeBlock(idx, currBlock);

    // set the error code
    ERRNO = NO_ERROR;
}