/** Counts the number of virtual indices of a DrawCall. */ int countIndices() const { int count = 0; for( IndexIterator it = indexIterator(); !it.isEnd(); it.next() ) count++; return count; }
/** * Return the score for the given suggestion (number between 0 to 1). * In case the suggestion should not be added return -1. */ static double SpellCheck_GetScore(SpellCheckCtx *scCtx, char *suggestion, size_t len, t_fieldMask fieldMask) { RedisModuleKey *keyp = NULL; InvertedIndex *invidx = Redis_OpenInvertedIndexEx(scCtx->sctx, suggestion, len, 0, &keyp); double retVal = 0; if (!invidx) { // can not find inverted index key, score is 0. goto end; } IndexReader *reader = NewTermIndexReader(invidx, NULL, fieldMask, NULL, 1); IndexIterator *iter = NewReadIterator(reader); RSIndexResult *r; if (iter->Read(iter->ctx, &r) != INDEXREAD_EOF) { // we have at least one result, the suggestion is relevant. if (scCtx->fullScoreInfo) { retVal = invidx->numDocs; } else { retVal = invidx->numDocs; } } else { // fieldMask has filtered all docs, this suggestions should not be returned retVal = -1; } ReadIterator_Free(iter); end: if (keyp) { RedisModule_CloseKey(keyp); } return retVal; }
void moveToNextUnfiltered() { while (iv_pIterator->isValid()) { bool bIsFiltered = iv_cpFilter->isFiltered(iv_pIterator->get()); if (!bIsFiltered) { return; } else { iv_pIterator->moveToNext(); } } }
int NamespaceDetails::_catalogFindIndexByName(OperationContext* txn, const Collection* coll, const StringData& name, bool includeBackgroundInProgress) const { IndexIterator i = ii(includeBackgroundInProgress); while( i.more() ) { const BSONObj obj = coll->docFor(txn, i.next().info.toRecordId()); if ( name == obj.getStringField("name") ) return i.pos()-1; } return -1; }
bool moveTo(TyFS fs) { assert( EXISTS(iv_pIterator) ); return iv_pIterator->moveTo(fs); }
IndexIterator* clone() const { return new FilterIndexIterator(iv_cpFilter, iv_pIterator->clone()); }
bool isValid() const { assert( EXISTS(iv_pIterator) ); return iv_pIterator->isValid(); }
TyFSType getTyFSType() const { assert( isValid() ); return iv_pIterator->getTyFSType(); }
QueryResult *Query_Execute(Query *query) { //__queryStage_Print(query->root, 0); QueryResult *res = malloc(sizeof(QueryResult)); res->error = 0; res->errorString = NULL; res->totalResults = 0; res->ids = NULL; res->numIds = 0; int num = query->offset + query->limit; heap_t *pq = malloc(heap_sizeof(num)); heap_init(pq, cmpHits, NULL, num); // start lazy evaluation of all query steps IndexIterator *it = NULL; if (query->root != NULL) { it = Query_EvalStage(query, query->root); } // no query evaluation plan? if (query->root == NULL || it == NULL) { res->error = QUERY_ERROR_INTERNAL; res->errorString = QUERY_ERROR_INTERNAL_STR; return res; } IndexHit *pooledHit = NULL; // iterate the root iterator and push everything to the PQ while (1) { // TODO - Use static allocation if (pooledHit == NULL) { pooledHit = malloc(sizeof(IndexHit)); } IndexHit *h = pooledHit; IndexHit_Init(h); int rc = it->Read(it->ctx, h); if (rc == INDEXREAD_EOF) { break; } else if (rc == INDEXREAD_NOTFOUND) { continue; } h->totalFreq = processHitScore(h, query->docTable); ++res->totalResults; if (heap_count(pq) < heap_size(pq)) { heap_offerx(pq, h); pooledHit = NULL; } else { IndexHit *qh = heap_peek(pq); if (qh->totalFreq < h->totalFreq) { pooledHit = heap_poll(pq); heap_offerx(pq, h); // IndexHit_Terminate(pooledHit); } else { pooledHit = h; // IndexHit_Terminate(pooledHit); } } } if (pooledHit) { free(pooledHit); } it->Free(it); // Reverse the results into the final result size_t n = MIN(heap_count(pq), query->limit); res->numIds = n; res->ids = calloc(n, sizeof(RedisModuleString *)); for (int i = 0; i < n; ++i) { IndexHit *h = heap_poll(pq); LG_DEBUG("Popping %d freq %f", h->docId, h->totalFreq); res->ids[n - i - 1] = Redis_GetDocKey(query->ctx, h->docId); free(h); } // if we still have something in the heap (meaning offset > 0), we need to // poll... while (heap_count(pq) > 0) { IndexHit *h = heap_poll(pq); free(h); } heap_free(pq); return res; }
void moveToNext() { assert(isValid()); iv_pIterator->moveToNext(); moveToNextUnfiltered(); }
void moveToPrevious() { assert(isValid()); iv_pIterator->moveToPrevious(); moveToPreviousUnfiltered(); }
void moveToLast() { assert( EXISTS(iv_pIterator) ); iv_pIterator->moveToLast(); moveToPreviousUnfiltered(); }
void moveToFirst() { assert( EXISTS(iv_pIterator) ); iv_pIterator->moveToFirst(); moveToNextUnfiltered(); }
void setupScene_MultiDrawElements() { ref<Geometry> torus1 = vl::makeTorus( vec3(-10, -9, 0), 8.0f, 1.0f, 20, 20 ); ref<Geometry> torus2 = vl::makeTorus( vec3( 0, -9, 0), 8.0f, 2.0f, 10, 10 ); ref<Geometry> torus3 = vl::makeTorus( vec3(+10, -9, 0), 8.0f, 3.0f, 7, 7 ); // merge vertices ref<ArrayFloat3> vert = new ArrayFloat3; ref<ArrayFloat3> torus1_vert = vl::cast<ArrayFloat3>(torus1->vertexArray()); ref<ArrayFloat3> torus2_vert = vl::cast<ArrayFloat3>(torus2->vertexArray()); ref<ArrayFloat3> torus3_vert = vl::cast<ArrayFloat3>(torus3->vertexArray()); vert->resize( torus1_vert->size() + torus2_vert->size() + torus3_vert->size() ); memcpy( vert->ptr(), torus1_vert->ptr(), torus1_vert->bytesUsed() ); memcpy( vert->ptr() + torus1_vert->bytesUsed(), torus2_vert->ptr(), torus2_vert->bytesUsed() ); memcpy( vert->ptr() + torus1_vert->bytesUsed() + torus2_vert->bytesUsed(), torus3_vert->ptr(), torus3_vert->bytesUsed() ); // merge indices ref<MultiDrawElementsUInt> mde = new MultiDrawElementsUInt(PT_QUADS); ref<DrawCall> torus1_dc = torus1->drawCalls()->at(0); ref<DrawCall> torus2_dc = torus2->drawCalls()->at(0); ref<DrawCall> torus3_dc = torus3->drawCalls()->at(0); int torus1_index_count = (int)torus1_dc->countIndices(); int torus2_index_count = (int)torus2_dc->countIndices(); int torus3_index_count = (int)torus3_dc->countIndices(); mde->indexBuffer()->resize( torus1_index_count + torus2_index_count + torus3_index_count ); MultiDrawElementsUInt::index_type* p_idx = mde->indexBuffer()->begin(); for( IndexIterator it = torus1_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx ) *p_idx = it.index(); for( IndexIterator it = torus2_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx ) *p_idx = it.index() + (int)torus1_vert->size(); for( IndexIterator it = torus3_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx ) *p_idx = it.index() + (int)torus1_vert->size() + (int)torus2_vert->size(); VL_CHECK(p_idx == mde->indexBuffer()->end()); // define how many indices for each draw call GLsizei count_vector[] = { torus1_index_count, torus2_index_count, torus3_index_count }; mde->setCountVector( count_vector, 3 ); ref<Geometry> geom = new Geometry; geom->setVertexArray( vert.get() ); geom->drawCalls()->push_back( mde.get() ); // compute normals must be done after the draw calls have been added. geom->computeNormals(); ref<Effect> fx = new Effect; fx->shader()->setRenderState( new Light, 0 ); fx->shader()->enable(vl::EN_LIGHTING); fx->shader()->enable(vl::EN_DEPTH_TEST); fx->shader()->gocMaterial()->setDiffuse( vl::pink ); sceneManager()->tree()->addActor( geom.get(), fx.get(), NULL ); }
TEST_F(RangeTest, testRangeIterator) { NumericRangeTree *t = NewNumericRangeTree(); ASSERT_TRUE(t != NULL); const size_t N = 100000; std::vector<double> lookup; std::vector<uint8_t> matched; lookup.resize(N + 1); matched.resize(N + 1); for (size_t i = 0; i < N; i++) { t_docId docId = i + 1; double value = (double)(1 + prng() % (N / 5)); lookup[docId] = value; // printf("Adding %d > %f\n", docId, value); NumericRangeTree_Add(t, docId, value); } for (size_t i = 0; i < 5; i++) { double min = (double)(1 + prng() % (N / 5)); double max = (double)(1 + prng() % (N / 5)); memset(&matched[0], 0, sizeof(uint8_t) * (N + 1)); NumericFilter *flt = NewNumericFilter(std::min(min, max), std::max(min, max), 1, 1); // count the number of elements in the range size_t count = 0; for (size_t i = 1; i <= N; i++) { if (NumericFilter_Match(flt, lookup[i])) { matched[i] = 1; count++; } } // printf("Testing range %f..%f, should have %d docs\n", min, max, count); IndexIterator *it = createNumericIterator(NULL, t, flt); int xcount = 0; RSIndexResult *res = NULL; while (IITER_HAS_NEXT(it)) { int rc = it->Read(it->ctx, &res); if (rc == INDEXREAD_EOF) { break; } ASSERT_EQ(matched[res->docId], 1); if (res->type == RSResultType_Union) { res = res->agg.children[0]; } matched[res->docId] = (uint8_t)2; // printf("rc: %d docId: %d, n %f lookup %f, flt %f..%f\n", rc, res->docId, res->num.value, // lookup[res->docId], flt->min, flt->max); ASSERT_EQ(res->num.value, lookup[res->docId]); ASSERT_TRUE(NumericFilter_Match(flt, lookup[res->docId])); ASSERT_EQ(res->type, RSResultType_Numeric); // ASSERT_EQUAL(res->agg.typeMask, RSResultType_Virtual); ASSERT_TRUE(!RSIndexResult_HasOffsets(res)); ASSERT_TRUE(!RSIndexResult_IsAggregate(res)); ASSERT_TRUE(res->docId > 0); ASSERT_EQ(res->fieldMask, RS_FIELDMASK_ALL); xcount++; } for (int i = 1; i <= N; i++) { if (matched[i] == 1) { printf("Miss: %d\n", i); } } // printf("The iterator returned %d elements\n", xcount); ASSERT_EQ(xcount, count); it->Free(it); NumericFilter_Free(flt); } ASSERT_EQ(t->numRanges, 14); ASSERT_EQ(t->numEntries, N); NumericRangeTree_Free(t); }
TyFS get() const { assert(isValid()); return iv_pIterator->get(); }
//----------------------------------------------------------------------------- void DoubleVertexRemover::removeDoubles(Geometry* geom) { mMapNewToOld.clear(); mMapOldToNew.clear(); std::vector<unsigned int> verti; verti.resize(geom->vertexArray()->size()); mMapOldToNew.resize(verti.size()); for(unsigned int i=0; i<verti.size(); ++i) { verti[i] = i; mMapOldToNew[i] = 0xFFFFFFFF; } mMapNewToOld.reserve(verti.size()); std::sort(verti.begin(), verti.end(), CompareVertex(geom)); if (verti.empty()) return; unsigned int unique_vert_idx = 0; for(unsigned i=1; i<verti.size(); ++i) { if ( !CompareVertex(geom).equals(verti[unique_vert_idx],verti[i]) ) { for(unsigned j=unique_vert_idx; j<i; ++j) mMapOldToNew[verti[j]] = mMapNewToOld.size(); mMapNewToOld.push_back(verti[unique_vert_idx]); unique_vert_idx = i; } } for(unsigned j=unique_vert_idx; j<verti.size(); ++j) { mMapOldToNew[verti[j]] = mMapNewToOld.size(); mMapNewToOld.push_back(verti[unique_vert_idx]); } // regenerate vertices geom->regenerateVertices(mMapNewToOld); // regenerate DrawCall std::vector< ref<DrawCall> > draw_cmd; for(int idraw=0; idraw<geom->drawCalls()->size(); ++idraw) draw_cmd.push_back( geom->drawCalls()->at(idraw) ); geom->drawCalls()->clear(); for(size_t idraw=0; idraw<draw_cmd.size(); ++idraw) { ref<DrawElementsUInt> tris = new DrawElementsUInt( draw_cmd[idraw]->primitiveType() ); geom->drawCalls()->push_back(tris.get()); const int idx_count = draw_cmd[idraw]->countIndices(); tris->indices()->resize(idx_count); int i=0; for(IndexIterator it = draw_cmd[idraw]->indexIterator(); !it.isEnd(); it.next(), ++i) tris->indices()->at(i) = mMapOldToNew[it.index()]; } #if 0 printf("DoubleVertexRemover = %d/%d, saved = %d, shrink=%.2f\n", (int)mMapNewToOld.size(), (int)verti.size(), (int)verti.size()-(int)mMapNewToOld.size(), (float)mMapNewToOld.size()/verti.size() ); #endif }