⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fts2.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
  DLWriter writer;  int i, n;  const char *pStart = 0;  int nStart = 0;  sqlite_int64 iFirstDocid = 0, iLastDocid = 0;  assert( nReaders>0 );  if( nReaders==1 ){    dataBufferAppend(out, dlrDocData(pReaders), dlrAllDataBytes(pReaders));    return;  }  assert( nReaders<=MERGE_COUNT );  n = 0;  for(i=0; i<nReaders; i++){    assert( pReaders[i].iType==pReaders[0].iType );    readers[i].pReader = pReaders+i;    readers[i].idx = i;    n += dlrAllDataBytes(&pReaders[i]);  }  /* Conservatively size output to sum of inputs.  Output should end  ** up strictly smaller than input.  */  dataBufferExpand(out, n);  /* Get the readers into sorted order. */  while( i-->0 ){    orderedDLReaderReorder(readers+i, nReaders-i);  }  dlwInit(&writer, pReaders[0].iType, out);  while( !dlrAtEnd(readers[0].pReader) ){    sqlite_int64 iDocid = dlrDocid(readers[0].pReader);    /* If this is a continuation of the current buffer to copy, extend    ** that buffer.  memcpy() seems to be more efficient if it has a    ** lots of data to copy.    */    if( dlrDocData(readers[0].pReader)==pStart+nStart ){      nStart += dlrDocDataBytes(readers[0].pReader);    }else{      if( pStart!=0 ){        dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);      }      pStart = dlrDocData(readers[0].pReader);      nStart = dlrDocDataBytes(readers[0].pReader);      iFirstDocid = iDocid;    }    iLastDocid = iDocid;    dlrStep(readers[0].pReader);    /* Drop all of the older elements with the same docid. */    for(i=1; i<nReaders &&             !dlrAtEnd(readers[i].pReader) &&             dlrDocid(readers[i].pReader)==iDocid; i++){      dlrStep(readers[i].pReader);    }    /* Get the readers back into order. */    while( i-->0 ){      orderedDLReaderReorder(readers+i, nReaders-i);    }  }  /* Copy over any remaining elements. */  if( nStart>0 ) dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);  dlwDestroy(&writer);}/* Helper function for posListUnion().  Compares the current position** between left and right, returning as standard C idiom of <0 if** left<right, >0 if left>right, and 0 if left==right.  "End" always** compares greater.*/static int posListCmp(PLReader *pLeft, PLReader *pRight){  assert( pLeft->iType==pRight->iType );  if( pLeft->iType==DL_DOCIDS ) return 0;  if( plrAtEnd(pLeft) ) return plrAtEnd(pRight) ? 0 : 1;  if( plrAtEnd(pRight) ) return -1;  if( plrColumn(pLeft)<plrColumn(pRight) ) return -1;  if( plrColumn(pLeft)>plrColumn(pRight) ) return 1;  if( plrPosition(pLeft)<plrPosition(pRight) ) return -1;  if( plrPosition(pLeft)>plrPosition(pRight) ) return 1;  if( pLeft->iType==DL_POSITIONS ) return 0;  if( plrStartOffset(pLeft)<plrStartOffset(pRight) ) return -1;  if( plrStartOffset(pLeft)>plrStartOffset(pRight) ) return 1;  if( plrEndOffset(pLeft)<plrEndOffset(pRight) ) return -1;  if( plrEndOffset(pLeft)>plrEndOffset(pRight) ) return 1;  return 0;}/* Write the union of position lists in pLeft and pRight to pOut.** "Union" in this case meaning "All unique position tuples".  Should** work with any doclist type, though both inputs and the output** should be the same type.*/static void posListUnion(DLReader *pLeft, DLReader *pRight, DLWriter *pOut){  PLReader left, right;  PLWriter writer;  assert( dlrDocid(pLeft)==dlrDocid(pRight) );  assert( pLeft->iType==pRight->iType );  assert( pLeft->iType==pOut->iType );  plrInit(&left, pLeft);  plrInit(&right, pRight);  plwInit(&writer, pOut, dlrDocid(pLeft));  while( !plrAtEnd(&left) || !plrAtEnd(&right) ){    int c = posListCmp(&left, &right);    if( c<0 ){      plwCopy(&writer, &left);      plrStep(&left);    }else if( c>0 ){      plwCopy(&writer, &right);      plrStep(&right);    }else{      plwCopy(&writer, &left);      plrStep(&left);      plrStep(&right);    }  }  plwTerminate(&writer);  plwDestroy(&writer);  plrDestroy(&left);  plrDestroy(&right);}/* Write the union of doclists in pLeft and pRight to pOut.  For** docids in common between the inputs, the union of the position** lists is written.  Inputs and outputs are always type DL_DEFAULT.*/static void docListUnion(  const char *pLeft, int nLeft,  const char *pRight, int nRight,  DataBuffer *pOut      /* Write the combined doclist here */){  DLReader left, right;  DLWriter writer;  if( nLeft==0 ){    dataBufferAppend(pOut, pRight, nRight);    return;  }  if( nRight==0 ){    dataBufferAppend(pOut, pLeft, nLeft);    return;  }  dlrInit(&left, DL_DEFAULT, pLeft, nLeft);  dlrInit(&right, DL_DEFAULT, pRight, nRight);  dlwInit(&writer, DL_DEFAULT, pOut);  while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){    if( dlrAtEnd(&right) ){      dlwCopy(&writer, &left);      dlrStep(&left);    }else if( dlrAtEnd(&left) ){      dlwCopy(&writer, &right);      dlrStep(&right);    }else if( dlrDocid(&left)<dlrDocid(&right) ){      dlwCopy(&writer, &left);      dlrStep(&left);    }else if( dlrDocid(&left)>dlrDocid(&right) ){      dlwCopy(&writer, &right);      dlrStep(&right);    }else{      posListUnion(&left, &right, &writer);      dlrStep(&left);      dlrStep(&right);    }  }  dlrDestroy(&left);  dlrDestroy(&right);  dlwDestroy(&writer);}/* pLeft and pRight are DLReaders positioned to the same docid.**** If there are no instances in pLeft or pRight where the position** of pLeft is one less than the position of pRight, then this** routine adds nothing to pOut.**** If there are one or more instances where positions from pLeft** are exactly one less than positions from pRight, then add a new** document record to pOut.  If pOut wants to hold positions, then** include the positions from pRight that are one more than a** position in pLeft.  In other words:  pRight.iPos==pLeft.iPos+1.*/static void posListPhraseMerge(DLReader *pLeft, DLReader *pRight,                               DLWriter *pOut){  PLReader left, right;  PLWriter writer;  int match = 0;  assert( dlrDocid(pLeft)==dlrDocid(pRight) );  assert( pOut->iType!=DL_POSITIONS_OFFSETS );  plrInit(&left, pLeft);  plrInit(&right, pRight);  while( !plrAtEnd(&left) && !plrAtEnd(&right) ){    if( plrColumn(&left)<plrColumn(&right) ){      plrStep(&left);    }else if( plrColumn(&left)>plrColumn(&right) ){      plrStep(&right);    }else if( plrPosition(&left)+1<plrPosition(&right) ){      plrStep(&left);    }else if( plrPosition(&left)+1>plrPosition(&right) ){      plrStep(&right);    }else{      if( !match ){        plwInit(&writer, pOut, dlrDocid(pLeft));        match = 1;      }      plwAdd(&writer, plrColumn(&right), plrPosition(&right), 0, 0);      plrStep(&left);      plrStep(&right);    }  }  if( match ){    plwTerminate(&writer);    plwDestroy(&writer);  }  plrDestroy(&left);  plrDestroy(&right);}/* We have two doclists with positions:  pLeft and pRight.** Write the phrase intersection of these two doclists into pOut.**** A phrase intersection means that two documents only match** if pLeft.iPos+1==pRight.iPos.**** iType controls the type of data written to pOut.  If iType is** DL_POSITIONS, the positions are those from pRight.*/static void docListPhraseMerge(  const char *pLeft, int nLeft,  const char *pRight, int nRight,  DocListType iType,  DataBuffer *pOut      /* Write the combined doclist here */){  DLReader left, right;  DLWriter writer;  if( nLeft==0 || nRight==0 ) return;  assert( iType!=DL_POSITIONS_OFFSETS );  dlrInit(&left, DL_POSITIONS, pLeft, nLeft);  dlrInit(&right, DL_POSITIONS, pRight, nRight);  dlwInit(&writer, iType, pOut);  while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){    if( dlrDocid(&left)<dlrDocid(&right) ){      dlrStep(&left);    }else if( dlrDocid(&right)<dlrDocid(&left) ){      dlrStep(&right);    }else{      posListPhraseMerge(&left, &right, &writer);      dlrStep(&left);      dlrStep(&right);    }  }  dlrDestroy(&left);  dlrDestroy(&right);  dlwDestroy(&writer);}/* We have two DL_DOCIDS doclists:  pLeft and pRight.** Write the intersection of these two doclists into pOut as a** DL_DOCIDS doclist.*/static void docListAndMerge(  const char *pLeft, int nLeft,  const char *pRight, int nRight,  DataBuffer *pOut      /* Write the combined doclist here */){  DLReader left, right;  DLWriter writer;  if( nLeft==0 || nRight==0 ) return;  dlrInit(&left, DL_DOCIDS, pLeft, nLeft);  dlrInit(&right, DL_DOCIDS, pRight, nRight);  dlwInit(&writer, DL_DOCIDS, pOut);  while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){    if( dlrDocid(&left)<dlrDocid(&right) ){      dlrStep(&left);    }else if( dlrDocid(&right)<dlrDocid(&left) ){      dlrStep(&right);    }else{      dlwAdd(&writer, dlrDocid(&left));      dlrStep(&left);      dlrStep(&right);    }  }  dlrDestroy(&left);  dlrDestroy(&right);  dlwDestroy(&writer);}/* We have two DL_DOCIDS doclists:  pLeft and pRight.** Write the union of these two doclists into pOut as a** DL_DOCIDS doclist.*/static void docListOrMerge(  const char *pLeft, int nLeft,  const char *pRight, int nRight,  DataBuffer *pOut      /* Write the combined doclist here */){  DLReader left, right;  DLWriter writer;  if( nLeft==0 ){    dataBufferAppend(pOut, pRight, nRight);    return;  }  if( nRight==0 ){    dataBufferAppend(pOut, pLeft, nLeft);    return;  }  dlrInit(&left, DL_DOCIDS, pLeft, nLeft);  dlrInit(&right, DL_DOCIDS, pRight, nRight);  dlwInit(&writer, DL_DOCIDS, pOut);  while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){    if( dlrAtEnd(&right) ){      dlwAdd(&writer, dlrDocid(&left));      dlrStep(&left);    }else if( dlrAtEnd(&left) ){      dlwAdd(&writer, dlrDocid(&right));      dlrStep(&right);    }else if( dlrDocid(&left)<dlrDocid(&right) ){      dlwAdd(&writer, dlrDocid(&left));      dlrStep(&left);    }else if( dlrDocid(&right)<dlrDocid(&left) ){      dlwAdd(&writer, dlrDocid(&right));      dlrStep(&right);    }else{      dlwAdd(&writer, dlrDocid(&left));      dlrStep(&left);      dlrStep(&right);    }  }  dlrDestroy(&left);  dlrDestroy(&right);  dlwDestroy(&writer);}/* We have two DL_DOCIDS doclists:  pLeft and pRight.** Write into pOut as DL_DOCIDS doclist containing all documents that** occur in pLeft but not in pRight.*/static void docListExceptMerge(  const char *pLeft, int nLeft,  const char *pRight, int nRight,  DataBuffer *pOut      /* Write the combined doclist here */){  DLReader left, right;  DLWriter writer;  if( nLeft==0 ) return;  if( nRight==0 ){    dataBufferAppend(pOut, pLeft, nLeft);    return;  }  dlrInit(&left, DL_DOCIDS, pLeft, nLeft);  dlrInit(&right, DL_DOCIDS, pRight, nRight);  dlwInit(&writer, DL_DOCIDS, pOut);  while( !dlrAtEnd(&left) ){    while( !dlrAtEnd(&right) && dlrDocid(&right)<dlrDocid(&left) ){      dlrStep(&right);    }    if( dlrAtEnd(&right) || dlrDocid(&left)<dlrDocid(&right) ){      dlwAdd(&writer, dlrDocid(&left));    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -