void DatasetTableTailer::refreshProjectIds(const NdbDictionary::Dictionary* database, NdbTransaction* transaction, UISet dataset_ids, ProjectDatasetINodeCache* cache) { const NdbDictionary::Index * index= getIndex(database, TABLE.mTableName, _dataset_cols[0]); vector<NdbIndexScanOperation*> indexScanOps; UIRowMap rows; for (UISet::iterator it = dataset_ids.begin(); it != dataset_ids.end(); ++it) { NdbIndexScanOperation* op = getNdbIndexScanOperation(transaction, index); op->readTuples(NdbOperation::LM_CommittedRead); op->equal(_dataset_cols[DS_INODE_ID].c_str(), *it); NdbRecAttr* id_col = getNdbOperationValue(op, _dataset_cols[DS_INODE_ID]); NdbRecAttr* proj_id_col = getNdbOperationValue(op, _dataset_cols[DS_PROJ_ID]); NdbRecAttr* shared_col = getNdbOperationValue(op, _dataset_cols[DS_SHARED]); rows[*it].push_back(id_col); rows[*it].push_back(proj_id_col); rows[*it].push_back(shared_col); indexScanOps.push_back(op); } executeTransaction(transaction, NdbTransaction::NoCommit); int i = 0; for (UIRowMap::iterator it = rows.begin(); it != rows.end(); ++it, i++) { stringstream projs; int res=0; while (indexScanOps[i]->nextResult(true) == 0) { if (it->first != it->second[0]->int32_value()) { LOG_ERROR("Dataset [" << it->first << "] doesn't exists"); continue; } bool originalDs = it->second[2]->int8_value() == 0; if(!originalDs){ continue; } int projectId = it->second[1]->int32_value(); if(res == 0){ cache->addDatasetToProject(it->first, projectId); } projs << projectId << ","; res++; } if(res > 1){ LOG_FATAL("Got " << res << " rows of the original Dataset [" << it->first << "] in projects [" << projs.str() << "], only one was expected"); } } }
void TableTailer::recover(int recoverFromId) { const NdbDictionary::Dictionary* database = getDatabase(mNdbConnection); const NdbDictionary::Index* index = getIndex(database, mTable.mTableName, mTable.mRecoveryIndex); NdbTransaction* transaction = startNdbTransaction(mNdbConnection); NdbIndexScanOperation* scanOp = getNdbIndexScanOperation(transaction, index); scanOp->readTuples(NdbOperation::LM_CommittedRead, NdbScanOperation::SF_OrderBy); scanOp->setBound(mTable.mRecoveryColumn.c_str(), NdbIndexScanOperation::BoundLT, (char*) & recoverFromId); NdbRecAttr * row[mTable.mNoColumns]; for (int i = 0; i < mTable.mNoColumns; i++) { row[i] = scanOp->getValue(mTable.mColumnNames[i].c_str()); } executeTransaction(transaction, NdbTransaction::Commit); while (scanOp->nextResult(true) == 0) { handleEvent(NdbDictionary::Event::TE_INSERT, NULL, row); } transaction->close(); }
int run_read() { int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; const Uint32 rows = g_paramters[P_ROWS].value; const Uint32 range = g_paramters[P_RANGE].value; start1 = NdbTick_CurrentMillisecond(); NdbConnection * pTrans = g_ndb->startTransaction(); if(!pTrans) { g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } NdbOperation * pOp; NdbScanOperation * pSp; NdbIndexOperation * pUp; NdbIndexScanOperation * pIp; Uint32 start_row = rand() % (rows - range); Uint32 stop_row = start_row + range; /** * 0 - serial pk * 1 - batch pk * 2 - serial uniq * 3 - batch uniq * 4 - index eq * 5 - range scan * 6 - interpreted scan */ int check = 0; void* res = (void*)~0; const Uint32 pk = 0; Uint32 cnt = 0; for(; start_row < stop_row; start_row++) { switch(g_paramters[P_OPER].value) { case 0: pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 1: for(; start_row<stop_row; start_row++) { pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } } break; case 2: pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 3: for(; start_row<stop_row; start_row++) { pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } } break; case 4: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row); break; case 5: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 6: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 7: pOp = pSp = pTrans->getNdbScanOperation(g_table); pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); NdbScanFilter filter(pOp) ; filter.begin(NdbScanFilter::AND); filter.ge(pk, start_row); filter.lt(pk, stop_row); filter.end(); start_row = stop_row; break; } assert(res); if(check != 0) { ndbout << pOp->getNdbError() << endl; ndbout << pTrans->getNdbError() << endl; } assert(check == 0); for(int j = 0; j<g_tab->getNoOfColumns(); j++) { res = pOp->getValue(j); assert(res); } check = pTrans->execute(NoCommit); if(check != 0) { ndbout << pTrans->getNdbError() << endl; } assert(check == 0); if(g_paramters[P_OPER].value >= 4) { while((check = pSp->nextResult(true)) == 0) { cnt++; } if(check == -1) { err(pTrans->getNdbError()); return -1; } assert(check == 1); pSp->close(); } } assert(g_paramters[P_OPER].value < 4 || (cnt == range)); pTrans->close(); stop = NdbTick_CurrentMillisecond(); g_times[g_paramters[P_OPER].value] += (stop - start1); return 0; }
int UtilTransactions::verifyOrderedIndex(Ndb* pNdb, const NdbDictionary::Index* pIndex, int parallelism, bool transactional){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; NdbIndexScanOperation * iop = 0; NDBT_ResultRow scanRow(tab); NDBT_ResultRow pkRow(tab); NDBT_ResultRow indexRow(tab); const char * indexName = pIndex->getName(); int res; parallelism = 1; while (true){ if (retryAttempt >= retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(get_values(pOp, scanRow)) { abort(); } check = pTrans->execute(NoCommit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } int eof; int rows = 0; while(check == 0 && (eof = pOp->nextResult()) == 0){ rows++; bool null_found= false; for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); if (scanRow.attributeStore(col->getName())->isNULL()) { null_found= true; break; } } // Do pk lookup NdbOperation * pk = pTrans->getNdbOperation(tab.getName()); if(!pk || pk->readTuple()) goto error; if(equal(&tab, pk, scanRow) || get_values(pk, pkRow)) goto error; if(!null_found) { if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName, tab.getName()))) { if(iop->readTuples(NdbScanOperation::LM_CommittedRead, parallelism)) goto error; iop->interpret_exit_ok(); if(get_values(iop, indexRow)) goto error; } else if(!iop || iop->reset_bounds()) { goto error; } if(equal(pIndex, iop, scanRow)) goto error; } check = pTrans->execute(NoCommit, AbortOnError); if(check) goto error; if(scanRow.c_str() != pkRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(!null_found) { if((res= iop->nextResult()) != 0){ g_err << "Failed to find row using index: " << res << endl; ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(scanRow.c_str() != indexRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(iop->nextResult() == 0){ g_err << "Found extra row!!" << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } } } if (eof == -1 || check == -1) { error: const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); iop = 0; closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; rows--; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; }
int run_scan(){ int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; Uint32 sample_rows = 0; int tot_rows = 0; NDB_TICKS sample_start = NdbTick_CurrentMillisecond(); Uint32 tot = g_paramters[P_ROWS].value; if(g_paramters[P_BOUND].value >= 2 || g_paramters[P_FILT].value == 2) iter *= g_paramters[P_ROWS].value; NdbScanOperation * pOp = 0; NdbIndexScanOperation * pIOp = 0; NdbConnection * pTrans = 0; int check = 0; for(int i = 0; i<iter; i++){ start1 = NdbTick_CurrentMillisecond(); pTrans = pTrans ? pTrans : g_ndb->startTransaction(); if(!pTrans){ g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } int par = g_paramters[P_PARRA].value; int bat = g_paramters[P_BATCH].value; NdbScanOperation::LockMode lm; switch(g_paramters[P_LOCK].value){ case 0: lm = NdbScanOperation::LM_CommittedRead; break; case 1: lm = NdbScanOperation::LM_Read; break; case 2: lm = NdbScanOperation::LM_Exclusive; break; default: abort(); } NdbScanOperation::ScanOptions options; bzero(&options, sizeof(options)); options.optionsPresent= NdbScanOperation::ScanOptions::SO_SCANFLAGS | NdbScanOperation::ScanOptions::SO_PARALLEL | NdbScanOperation::ScanOptions::SO_BATCH; bool ord= g_paramters[P_ACCESS].value == 2; bool mrr= (g_paramters[P_ACCESS].value != 0) && (g_paramters[P_BOUND].value == 3); options.scan_flags|= ( ord ? NdbScanOperation::SF_OrderBy:0 ) | ( mrr ? NdbScanOperation::SF_MultiRange:0 ); options.parallel= par; options.batch= bat; switch(g_paramters[P_FILT].value){ case 0: // All break; case 1: // None break; case 2: // 1 row default: { assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far abort(); #if 0 int tot = g_paramters[P_ROWS].value; int row = rand() % tot; NdbInterpretedCode* ic= new NdbInterpretedCode(g_table); NdbScanFilter filter(ic); filter.begin(NdbScanFilter::AND); filter.eq(0, row); filter.end(); options.scan_flags|= NdbScanOperation::SF_Interpreted; options.interpretedCode= ⁣ break; #endif } } if(g_paramters[P_ACCESS].value == 0){ pOp = pTrans->scanTable(g_table_record, lm, NULL, // Mask &options, sizeof(NdbScanOperation::ScanOptions)); assert(pOp); } else { pOp= pIOp= pTrans->scanIndex(g_index_record, g_table_record, lm, NULL, // Mask NULL, // First IndexBound &options, sizeof(NdbScanOperation::ScanOptions)); if (pIOp == NULL) { err(pTrans->getNdbError()); abort(); } assert(pIOp); switch(g_paramters[P_BOUND].value){ case 0: // All break; case 1: // None check= setEqBound(pIOp, g_index_record, 0, 0); assert(check == 0); break; case 2: { // 1 row default: assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far int tot = g_paramters[P_ROWS].value; int row = rand() % tot; check= setEqBound(pIOp, g_index_record, row, 0); assert(check == 0); break; } case 3: { // read multi int multi = g_paramters[P_MULTI].value; int tot = g_paramters[P_ROWS].value; int rangeStart= i; for(; multi > 0 && i < iter; --multi, i++) { int row = rand() % tot; /* Set range num relative to this set of bounds */ check= setEqBound(pIOp, g_index_record, row, i- rangeStart); if (check != 0) { err(pIOp->getNdbError()); abort(); } assert(check == 0); } break; } } } assert(pOp); assert(check == 0); int rows = 0; check = pTrans->execute(NoCommit); assert(check == 0); int fetch = g_paramters[P_FETCH].value; const char * result_row_ptr; while((check = pOp->nextResult(&result_row_ptr, true, false)) == 0){ do { rows++; } while(!fetch && ((check = pOp->nextResult(&result_row_ptr, false, false)) == 0)); if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 2); } if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 1); pTrans->close(); pTrans = 0; stop = NdbTick_CurrentMillisecond(); int time_passed= (int)(stop - start1); sample_rows += rows; sum_time+= time_passed; tot_rows+= rows; if(sample_rows >= tot) { int sample_time = (int)(stop - sample_start); g_info << "Found " << sample_rows << " rows" << endl; g_err.println("Time: %d ms = %u rows/sec", sample_time, (1000*sample_rows)/sample_time); sample_rows = 0; sample_start = stop; } } g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows, (1000*tot_rows)/sum_time); return 0; }
int HugoTransactions::scanReadRecords(Ndb* pNdb, const NdbDictionary::Index * pIdx, int records, int abortPercent, int parallelism, NdbOperation::LockMode lm, int scan_flags) { int retryAttempt = 0; int check, a; NdbIndexScanOperation *pOp; while (true){ if (retryAttempt >= m_retryMax){ g_err << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbIndexScanOperation(pIdx->getName(), tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp ->readTuples(lm, scan_flags, parallelism) ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } for(a = 0; a<tab.getNoOfColumns(); a++){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } check = pTrans->execute(NoCommit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } // Abort after 1-100 or 1-records rows int ranVal = rand(); int abortCount = ranVal % (records == 0 ? 100 : records); bool abortTrans = false; if (abort > 0){ // Abort if abortCount is less then abortPercent if (abortCount < abortPercent) abortTrans = true; } int eof; int rows = 0; while((eof = pOp->nextResult(true)) == 0){ rows++; if (calc.verifyRowValues(&row) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } if (abortCount == rows && abortTrans == true){ ndbout << "Scan is aborted" << endl; g_info << "Scan is aborted" << endl; pOp->close(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); return NDBT_OK; } } if (eof == -1) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR_INFO(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); switch (err.code){ case 488: case 245: case 490: // Too many active scans, no limit on number of retry attempts break; default: retryAttempt++; } continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); g_info << rows << " rows have been read" << endl; if (records != 0 && rows != records){ g_err << "Check expected number of records failed" << endl << " expected=" << records <<", " << endl << " read=" << rows << endl; return NDBT_FAILED; } return NDBT_OK; } return NDBT_FAILED; }
int HugoTransactions::indexReadRecords(Ndb* pNdb, const char * idxName, int records, int batch){ int reads = 0; int r = 0; int retryAttempt = 0; int check, a; NdbOperation *pOp; NdbIndexScanOperation *sOp; const NdbDictionary::Index* pIndex = pNdb->getDictionary()->getIndex(idxName, tab.getName()); const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex); if (batch == 0) { g_info << "ERROR: Argument batch == 0 in indexReadRecords(). " << "Not allowed." << endl; return NDBT_FAILED; } if (ordered) { batch = 1; } allocRows(batch); while (r < records){ if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } for(int b=0; (b<batch) && (r+b < records); b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTuple(); } else { pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (sOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = sOp->readTuples(); } if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(Commit, AbortOnError); check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true)); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } switch(err.code){ case 626: // Tuple did not exist g_info << r << ": " << err.code << " " << err.message << endl; r++; break; default: ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } else{ for (int b=0; (b<batch) && (r+b<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } reads++; r++; } if(ordered && sOp->nextResult(true) == 0){ ndbout << "Error when comparing records " << " - index op next_result to many" << endl; closeTransaction(pNdb); return NDBT_FAILED; } } closeTransaction(pNdb); } deallocRows(); g_info << reads << " records read" << endl; return NDBT_OK; }
int run_scan(){ int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; int sample_rows = 0; int tot_rows = 0; NDB_TICKS sample_start = NdbTick_CurrentMillisecond(); Uint32 tot = g_paramters[P_ROWS].value; if(g_paramters[P_BOUND].value >= 2 || g_paramters[P_FILT].value == 2) iter *= g_paramters[P_ROWS].value; NdbScanOperation * pOp = 0; NdbIndexScanOperation * pIOp = 0; NdbConnection * pTrans = 0; int check = 0; for(int i = 0; i<iter; i++){ start1 = NdbTick_CurrentMillisecond(); pTrans = pTrans ? pTrans : g_ndb->startTransaction(); if(!pTrans){ g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } int par = g_paramters[P_PARRA].value; int bat = 0; // g_paramters[P_BATCH].value; NdbScanOperation::LockMode lm; switch(g_paramters[P_LOCK].value){ case 0: lm = NdbScanOperation::LM_CommittedRead; break; case 1: lm = NdbScanOperation::LM_Read; break; case 2: lm = NdbScanOperation::LM_Exclusive; break; default: abort(); } if(g_paramters[P_ACCESS].value == 0){ pOp = pTrans->getNdbScanOperation(g_tablename); assert(pOp); pOp->readTuples(lm, bat, par); } else { if(g_paramters[P_RESET].value == 0 || pIOp == 0) { pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename); bool ord = g_paramters[P_ACCESS].value == 2; pIOp->readTuples(lm, bat, par, ord); } else { pIOp->reset_bounds(); } switch(g_paramters[P_BOUND].value){ case 0: // All break; case 1: // None pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0); break; case 2: { // 1 row default: assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far int tot = g_paramters[P_ROWS].value; int row = rand() % tot; #if 0 fix_eq_bound(pIOp, row); #else pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row); #endif if(g_paramters[P_RESET].value == 2) goto execute; break; } case 3: { // read multi int multi = g_paramters[P_MULTI].value; int tot = g_paramters[P_ROWS].value; for(; multi > 0 && i < iter; --multi, i++) { int row = rand() % tot; pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row); pIOp->end_of_bound(i); } if(g_paramters[P_RESET].value == 2) goto execute; break; } } } assert(pOp); switch(g_paramters[P_FILT].value){ case 0: // All check = pOp->interpret_exit_ok(); break; case 1: // None check = pOp->interpret_exit_nok(); break; case 2: { // 1 row default: assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far abort(); #if 0 int tot = g_paramters[P_ROWS].value; int row = rand() % tot; NdbScanFilter filter(pOp) ; filter.begin(NdbScanFilter::AND); fix_eq(filter, pOp, row); filter.end(); break; #endif } } if(check != 0){ err(pOp->getNdbError()); return -1; } assert(check == 0); if(g_paramters[P_RESET].value == 1) g_paramters[P_RESET].value = 2; for(int i = 0; i<g_table->getNoOfColumns(); i++){ pOp->getValue(i); } if(g_paramters[P_RESET].value == 1) g_paramters[P_RESET].value = 2; execute: int rows = 0; check = pTrans->execute(NoCommit); assert(check == 0); int fetch = g_paramters[P_FETCH].value; while((check = pOp->nextResult(true)) == 0){ do { rows++; } while(!fetch && ((check = pOp->nextResult(false)) == 0)); if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 2); } if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 1); if(g_paramters[P_RESET].value == 0) { pTrans->close(); pTrans = 0; } stop = NdbTick_CurrentMillisecond(); int time_passed= (int)(stop - start1); sample_rows += rows; sum_time+= time_passed; tot_rows+= rows; if(sample_rows >= tot) { int sample_time = (int)(stop - sample_start); g_info << "Found " << sample_rows << " rows" << endl; g_err.println("Time: %d ms = %u rows/sec", sample_time, (1000*sample_rows)/sample_time); sample_rows = 0; sample_start = stop; } } g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows, (1000*tot_rows)/sum_time); return 0; }
int main(void){ ndb_init(); Ndb_cluster_connection con; if(con.connect(12, 5, 1) != 0) { return 1; } Ndb g_ndb(&con, "test"); g_ndb.init(1024); require(g_ndb.waitUntilReady() == 0); while(true){ g_trans = g_ndb.startTransaction(); require(g_trans); size_t i, j; const size_t cnt = sizeof(g_scans)/sizeof(g_scans[0]); start = NdbTick_CurrentMillisecond(); for(i = 0; i<cnt; i++){ ndbout_c("starting scan on: %s %s", g_scans[i].m_table, g_scans[i].m_index); g_scans[i].m_scan = g_trans->getNdbIndexScanOperation(g_scans[i].m_index, g_scans[i].m_table); NdbIndexScanOperation* scan = g_scans[i].m_scan; require(scan); require(scan->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true) == 0); } require(!g_scans[0].m_scan->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &g_affiliateid, sizeof(g_affiliateid))); #if 0 require(!g_scans[1].m_scan->setBound((Uint32)0, NdbIndexScanOperation::BoundLE, &g_formatids[0], sizeof(g_formatids[0]))); #endif NdbScanFilter sf(g_scans[1].m_scan); sf.begin(NdbScanFilter::OR); sf.eq(2, g_formatids[0]); sf.eq(2, g_formatids[1]); sf.eq(2, g_formatids[2]); sf.end(); // affiliatestometa require(g_scans[0].m_scan->getValue("uniquekey")); require(g_scans[0].m_scan->getValue("xml")); // media require(g_scans[1].m_scan->getValue("path")); require(g_scans[1].m_scan->getValue("mediaid")); require(g_scans[1].m_scan->getValue("formatid")); // meta require(g_scans[2].m_scan->getValue("name")); require(g_scans[2].m_scan->getValue("xml")); // artiststometamap require(g_scans[3].m_scan->getValue("artistid", (char*)&g_artistid)); // subgenrestometamap require(g_scans[4].m_scan->getValue("subgenreid", (char*)&g_subgenreid)); for(i = 0; i<cnt; i++){ g_scans[i].m_scan->getValue("metaid", (char*)&g_scans[i].metaid); } g_trans->execute(NoCommit, AbortOnError, 1); Uint32 max_val = 0; Uint32 match_val = 0; S_Scan * F [5], * Q [5], * nextF [5]; Uint32 F_sz = 0, Q_sz = 0; for(i = 0; i<cnt; i++){ F_sz++; F[i] = &g_scans[i]; } Uint32 match_count = 0; while(F_sz > 0){ Uint32 prev_F_sz = F_sz; F_sz = 0; bool found = false; //for(i = 0; i<cnt; i++) //ndbout_c("%s - %d", g_scans[i].m_table, g_scans[i].metaid); for(i = 0; i<prev_F_sz; i++){ int res = F[i]->m_scan->nextResult(); if(res == -1) abort(); if(res == 1){ continue; } Uint32 metaid = F[i]->metaid; F[i]->row_count++; if(metaid == match_val){ //ndbout_c("flera"); nextF[F_sz++] = F[i]; require(F_sz >= 0 && F_sz <= cnt); F[i]->match_count++; Uint32 comb = 1; for(j = 0; j<cnt; j++){ comb *= (&g_scans[j] == F[i] ? 1 : g_scans[j].match_count); } match_count += comb; found = true; continue; } if(metaid < max_val){ nextF[F_sz++] = F[i]; require(F_sz >= 0 && F_sz <= cnt); continue; } if(metaid > max_val){ for(j = 0; j<Q_sz; j++) nextF[F_sz++] = Q[j]; require(F_sz >= 0 && F_sz <= cnt); Q_sz = 0; max_val = metaid; } Q[Q_sz++] = F[i]; require(Q_sz >= 0 && Q_sz <= cnt); } if(F_sz == 0 && Q_sz > 0){ match_val = max_val; for(j = 0; j<Q_sz; j++){ nextF[F_sz++] = Q[j]; Q[j]->match_count = 1; } require(F_sz >= 0 && F_sz <= cnt); require(Q_sz >= 0 && Q_sz <= cnt); Q_sz = 0; match_count++; lookup(); } else if(!found && F_sz + Q_sz < cnt){ F_sz = 0; } require(F_sz >= 0 && F_sz <= cnt); for(i = 0; i<F_sz; i++) F[i] = nextF[i]; } start = NdbTick_CurrentMillisecond() - start; ndbout_c("Elapsed: %lldms", start); ndbout_c("rows: %d", match_count); for(i = 0; i<cnt; i++){ ndbout_c("%s : %d", g_scans[i].m_table, g_scans[i].row_count); } g_trans->close(); } }