keyMdamEx::keyMdamEx(const keyRangeGen & keyRangeGen, const short in_version, sql_buffer_pool *pool, ex_globals *glob, const ex_tcb *tcb) : keyRangeEx(keyRangeGen,glob,in_version,pool), network_built_(FALSE), stop_lists_built_(FALSE), current_column_(0), current_column_index_(-1), productiveFetchRangeCounter_(0), mdamRefListEntryHeap_(sizeof(MdamRefListEntry), getGenInfo().getMaxMdamRefs()), mdamRefListEntrysForStopListsHeap_(sizeof(MdamRefListEntry), getGenInfo().getMaxMdamRefsForStopLists()), mdamIntervalHeap_(sizeof(MdamInterval), getGenInfo().getMaxMdamIntervals()), complementKeysBeforeReturning_( getGenInfo().complementKeysBeforeReturning()) { number_of_key_cols_ = 0; first_column_ = last_column_ = 0; const keyMdamGen & keyM = (const keyMdamGen &)keyRangeGen; for (MdamColumnGen *cg = keyM.getFirst(); cg != 0; cg = cg->getNext()) { last_column_ = new(glob->getSpace()) MdamColumn(last_column_, cg, glob, pool, workAtp_, // $$$ will this work? workAtp_, keyM.getValueAtpIndex(), tcb); if (first_column_ == 0) first_column_ = last_column_; number_of_key_cols_++; } NABoolean refListEntrysForStopListsHeapAcquired = mdamRefListEntrysForStopListsHeap_.acquireHeapMemory( globals_->getDefaultHeap()); }
void keyMdamEx::reportProbeResult(char *keyData) { ex_assert(current_column_, "keyMdamEx::reportProbeResult() called outside traverse"); if (complementKeysBeforeReturning_) { if (keyData) { // for reverse scans, complement the encoding so it is consistent // with what is stored in the MDAM network str_complement(getGenInfo().getKeyLength(),keyData); } } current_column_->reportProbeResult(keyData); }
/** * Add an attribute to the general info artifact for this file * @param attr attribute to be added */ void TskFile::addGenInfoAttribute(TskBlackboardAttribute attr){ getGenInfo().addAttribute(attr); }
ExeErrorCode keyMdamEx::buildNetwork(sql_buffer_pool *pool,atp_struct *atp0) { destroyNetwork(); // clean out any old network still hanging around keyMdamGen & mdamGen = (keyMdamGen &)tdbKey_; // Acquire memory for MdamRefListEntry's. ExeErrorCode refListEntryHeapErrorCode = mdamRefListEntryHeap_.acquireHeapMemory(globals_->getDefaultHeap()); if (refListEntryHeapErrorCode != (ExeErrorCode)0) return refListEntryHeapErrorCode; // Acquire memory for MdamInterval's. ExeErrorCode intervalHeapErrorCode = mdamIntervalHeap_.acquireHeapMemory(globals_->getDefaultHeap()); if (intervalHeapErrorCode != (ExeErrorCode)0) return intervalHeapErrorCode; MdamPredIterator predIterator(first_column_, mdamGen.getMaxDisjunctNumber()); Lng32 disjunct_number; while ((disjunct_number = predIterator.getNextDisjunctNumber()) >= 0) { NABoolean disjunct_number_in_stop_list = stop_lists_built_; NABoolean empty_disjunct = FALSE; Lng32 column_number = number_of_key_cols_-1; // $$$ remove later for (MdamColumn * m = last_column_; m != 0; m = m->previousColumn()) { ex_assert(column_number >= 0, "keyMdamEx::Mdam -- bad column_number"); // $$$ remove later disjunct_number_in_stop_list = m->buildDisjunct(predIterator, pool, atp0, workAtp_, getGenInfo().getValueAtpIndex(), disjunct_number, disjunct_number_in_stop_list, mdamIntervalHeap_, mdamRefListEntryHeap_, mdamRefListEntrysForStopListsHeap_, dataConvErrorFlag_); if (m->disjunctIsEmpty()) empty_disjunct = TRUE; column_number--; // $$$ remove later } // end for ex_assert(column_number == -1, "keyMdamEx::Mdam -- wrong number of columns"); // $$$ remove later ex_assert(disjunct_number_in_stop_list, "keyMdamEx::Mdam -- disjunct number not in any stop list"); // if the disjunct is empty for some column (i.e. if some column // has contradictory predicates for this disjunct), throw the disjunct // away; otherwise merge it in if (empty_disjunct) { for (MdamColumn * c = first_column_; c != 0; c = c->nextColumn()) { c->tossDisjunct(mdamIntervalHeap_, mdamRefListEntryHeap_); } } else { for (MdamColumn * c = first_column_; c != 0; c = c->nextColumn()) { c->mergeDisjunct(disjunct_number, mdamIntervalHeap_, mdamRefListEntryHeap_); } } } // end while network_built_ = TRUE; stop_lists_built_ = TRUE; // for testing... display the network #if defined ( NA_MDAM_EXECUTOR_DEBUG ) print(); #endif /* NA_MDAM_EXECUTOR_DEBUG */ return (ExeErrorCode)0; // No error. }
keyRangeEx::getNextKeyRangeReturnType keyMdamEx::getNextKeyRange (atp_struct *,NABoolean fetchRangeHadRows, NABoolean detectNullRange) { // This logic + MdamColumn::getNextValue are essentially a re-coding // of the SQL/MP procedure evac^next^traverse. One fundamental // difference is that unlike SQL/MP, sparse probes are done in the // layer on top of Mdam, instead of below. So, this procedure, for // example, might return a key range for probing or for fetching. // In SQL/MP, evac^next^traverse returns only key ranges for // fetching. The probing is done inside the scope of the // evac^next^traverse procedure call. if (fetchRangeHadRows) productiveFetchRangeCounter_++; getNextKeyRangeReturnType rc = NO_MORE_RANGES; // assume no more ranges NABoolean not_done = TRUE; char *bktarget = bkData_.getDataPointer(); char *ektarget = ekData_.getDataPointer(); ULng32 keyLength = getGenInfo().getKeyLength(); // LCOV_EXCL_START if (getGenInfo().getKeytag() > 0) { unsigned short keytag = getGenInfo().getKeytag(); str_cpy_all(bktarget, (char *)&keytag, sizeof(short)); str_cpy_all(ektarget, (char *)&keytag, sizeof(short)); bktarget += sizeof(short); ektarget += sizeof(short); keyLength -= sizeof(short); } // LCOV_EXCL_STOP if (complementKeysBeforeReturning_) { // if reverse scan, need to swap where we put begin and end keys char *temp = bktarget; bktarget = ektarget; ektarget = temp; } // Part of fix for Genesis case 10-971031-9814: // Keep track of the offset of the left-most column traversed. ULng32 minOffset = 0; if (current_column_) minOffset = current_column_->getOffset(); // End of this part of the fix. while ((current_column_) && (not_done)) { MdamColumn::getNextValueReturnType status = current_column_->getNextValue(productiveFetchRangeCounter_, bktarget, ektarget, bkExcludeFlag_, ekExcludeFlag_, mdamRefListEntryHeap_); switch (status) { case MdamColumn::TRAVERSE_DOWN: { current_column_ = current_column_->nextColumn(); current_column_index_++; ex_assert(current_column_ != 0, "keyMdamEx::getNextKeyRange() traversed off end"); current_column_->initNextValue(); break; } case MdamColumn::TRAVERSE_UP: { current_column_ = current_column_->previousColumn(); current_column_index_--; // Part of fix for Genesis case 10-971031-9814: // Keep track of the offset of the left-most column traversed. ULng32 offset = 0; if (current_column_) // note current_column_ is 0 at end of all traversal offset = current_column_->getOffset(); if (offset < minOffset) minOffset = offset; // End of this part of the fix. ex_assert(current_column_index_ >= -1, "keyMdamEx::getNextKeyRange() column index wrong"); break; } case MdamColumn::SUBSET: case MdamColumn::PROBE: { MdamColumn * col; Lng32 index = current_column_index_ + 1; for (col = current_column_->nextColumn(); col != 0; col = col->nextColumn()) { col->completeKey(bktarget, ektarget, bkExcludeFlag_, ekExcludeFlag_); index++; } ex_assert(index == number_of_key_cols_, "keyMdamEx::getNextKeyRange() completeKey failure"); not_done = FALSE; rc = FETCH_RANGE; if (status == MdamColumn::PROBE) rc = PROBE_RANGE; if (complementKeysBeforeReturning_) { // On reverse scans, the keys in the Mdam network have // been complemented; we must undo this complementing // before returning the keys to the caller. // Part of fix for Genesis case 10-971031-9814: // Complement only that part of the key that was computed // on this call to getNextKeyRange(); the preceding parts // of the key have already been complemented on prior calls. str_complement(keyLength-minOffset,bktarget+minOffset); str_complement(keyLength-minOffset,ektarget+minOffset); // End of fix. // also we need to swap the exclude flags (just as we // did the key buffers earlier) short temp; temp = bkExcludeFlag_; bkExcludeFlag_ = ekExcludeFlag_; ekExcludeFlag_ = temp; } break; } default: { ex_assert(0,"keyMdamEx::getNextKeyRange() invalid getNextValue rc"); // LCOV_EXCL_LINE break; } } } return rc; }