Exemple #1
0
/* 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;
}
Exemple #2
0
/*
7 Implementation of class ~SortAlgorithm~

*/
SortAlgorithm::SortAlgorithm( Word stream,
                              const SortOrderSpecification& spec,
                              SortProgressLocalInfo* p,
                              Supplier s,
                              size_t maxFanIn,
                              size_t maxMemSize,
                              size_t ioBufferSize)
: F0(0)
, W(0)
, nextRunNumber(1)
, checkProgressAfter(10)
, stream(stream)
, attributes(-1)
, spec(spec)
//, cmpObj(cmpObj)
, usedMemory(0)
, traceMode(RTFlag::isActive("ERA:TraceSort"))
, traceModeExtended(RTFlag::isActive("ERA:TraceSortExtended"))
, progress(p)
{
  SortedRun *curRun = 0, *nextRun = 0;

  Word wTuple(Address(0));

  // Check specified fan-in for a merge phase
  setMaxFanIn(maxFanIn);

  // Check specified main memory for this operation

  setMemory(maxMemSize, s);

  // Check I/O buffer size for this operation
  setIoBuffer(ioBufferSize);

  if ( traceMode )
  {
    info = new SortInfo(MAX_MEMORY, IO_BUFFER_SIZE);
    info->RunBuildPhase();
    info->MaxMergeFanIn = FMAX;
    TupleQueueCompare::ResetComparisonCounter();
  }

  // Request first tuple and consume the stream completely
  qp->Request(stream.addr, wTuple);

  while( qp->Received(stream.addr) )
  {
    Tuple *t = static_cast<Tuple*>( wTuple.addr );

    progress->read++;

    size_t memSize = t->GetMemSize();

    // Save number of attributes
    if ( attributes == -1 )
    {
      attributes = t->GetNoAttributes();
      curRun = new SortedRun(nextRunNumber++, attributes, spec, IO_BUFFER_SIZE);
      runs.push_back(curRun);
    }

    if ( traceMode )
    {
      info->UpdateStatistics(t->GetSize());
    }

    if( usedMemory <= MAX_MEMORY )
    {
      curRun->AppendToMemory(t);
      usedMemory += memSize;
    }
    else
    {
      if ( curRun->IsFirstTupleOnDisk() )
      {
        // memory is completely used, append to disk
        progress->state = 1;
        curRun->AppendToDisk(t);
      }
      else
      {
        if ( curRun->IsInSortOrder(t) )
        {
          // tuple is on sort order, append to disk
          curRun->AppendToDisk(t);
        }
        else
        {
          if ( traceMode )
          {
            curRun->Info()->TuplesPassedToNextRun++;
          }

          // create next run if necessary
          if ( nextRun == 0 )
          {
            nextRun = new SortedRun( nextRunNumber++, attributes,
                                     spec, IO_BUFFER_SIZE );
            runs.push_back(nextRun);
            updateIntermediateMergeCost();
          }

          // next tuple is smaller, save it for the next relation
          if ( !curRun->IsAtDisk() )
          {
            // push minimum tuple of current run to disk
            curRun->AppendToDisk();

            // append tuple to memory
            nextRun->AppendToMemory(t);
          }
          else
          {
            // finish current run
            curRun->RunFinished();

            // switch runs
            curRun = nextRun;
            nextRun = 0;

            curRun->AppendToDisk(t);
          }
        }
      }
    }

    qp->Request(stream.addr, wTuple);
  }

  if ( traceMode )
  {
    for (size_t i = 0; i < runs.size(); i++)
    {
      info->InitialRunInfo.push_back(runs[i]->InfoCopy());
      info->InitialRunsCount = runs.size();
    }
  }

  mergeInit();
}