/**************************************************************************** Desc: Reinsert all entries given a new root block. Caller will release 'this'. Used ONLY for building the first ROOT and two leaves of the tree. ****************************************************************************/ RCODE F_BtreeLeaf::split( F_BtreeRoot * pNewRoot) // New Non-leaf root { RCODE rc = NE_FLM_OK; FLMBYTE * pucEntry; FLMUINT uiPos; FLMUINT uiEntryCount = entryCount(); FLMUINT uiMid = (uiEntryCount + 1) >> 1; if (RC_BAD( rc = pNewRoot->setupTree( ENTRY_POS(uiMid), ACCESS_BTREE_LEAF, NULL, NULL))) { goto Exit; } for (uiPos = 0; uiPos < uiEntryCount; uiPos++) { pucEntry = ENTRY_POS( uiPos); if ((rc = pNewRoot->search( pucEntry)) != NE_FLM_NOT_FOUND) { rc = RC_SET_AND_ASSERT( NE_FLM_FAILURE); goto Exit; } if (RC_BAD( rc = pNewRoot->insert( pucEntry))) { goto Exit; } } Exit: return( rc); }
std::vector<TargetValue> ResultSet::getRowAtNoTranslations(const size_t logical_index) const { if (logical_index >= entryCount()) { return {}; } const auto entry_idx = permutation_.empty() ? logical_index : permutation_[logical_index]; return getRowAt(entry_idx, false, false, false); }
/**************************************************************************** Desc: Return the next entry in the result set. If the result set is not positioned then the first entry will be returned. ****************************************************************************/ RCODE F_BtreeBlk::getNext( void * pvEntryBuffer) { RCODE rc = NE_FLM_OK; FLMUINT uiPos = m_uiPosition; // Position to the next/first entry. if (uiPos == DYNSSET_POSITION_NOT_SET) { uiPos = 0; } else { if (++uiPos > entryCount()) { rc = RC_SET( NE_FLM_EOF_HIT); goto Exit; } } f_memcpy( pvEntryBuffer, ENTRY_POS(uiPos), m_uiEntrySize); m_uiPosition = uiPos; Exit: return( rc); }
std::vector<TargetValue> ResultSet::getNextRowImpl(const bool translate_strings, const bool decimal_to_double) const { auto entry_buff_idx = advanceCursorToNextEntry(); if (keep_first_ && fetched_so_far_ >= drop_first_ + keep_first_) { return {}; } if (crt_row_buff_idx_ >= entryCount()) { CHECK_EQ(entryCount(), crt_row_buff_idx_); return {}; } auto row = getRowAt(entry_buff_idx, translate_strings, decimal_to_double, false); CHECK(!row.empty()); ++crt_row_buff_idx_; ++fetched_so_far_; return row; }
bool ResultSet::isRowAtEmpty(const size_t logical_index) const { if (logical_index >= entryCount()) { return true; } const auto entry_idx = permutation_.empty() ? logical_index : permutation_[logical_index]; const auto storage_lookup_result = findStorage(entry_idx); const auto storage = storage_lookup_result.storage_ptr; const auto local_entry_idx = storage_lookup_result.fixedup_entry_idx; return storage->isEmptyEntry(local_entry_idx); }
/**************************************************************************** Desc: Insert the entry into the buffer. ****************************************************************************/ RCODE F_BtreeBlk::insertEntry( void * pvEntry, FLMUINT uiChildAddr) { RCODE rc = NE_FLM_OK; FLMBYTE * pucCurEntry; FLMUINT uiShiftBytes; // Always shift down if( entryCount() >= m_uiNumSlots) { rc = RC_SET( NE_FLM_FAILURE); goto Exit; } flmAssert( m_uiPosition != DYNSSET_POSITION_NOT_SET); pucCurEntry = ENTRY_POS( m_uiPosition); if ((uiShiftBytes = (entryCount() - m_uiPosition) * (m_uiEntrySize + m_uiEntryOvhd)) != 0) { // Big hairy assert. Finds coding bugs and corruptions. flmAssert( m_uiPosition * (m_uiEntrySize + m_uiEntryOvhd) + uiShiftBytes < DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)); f_memmove( pucCurEntry + m_uiEntrySize + m_uiEntryOvhd, pucCurEntry, uiShiftBytes); } f_memcpy( pucCurEntry, pvEntry, m_uiEntrySize); if( m_uiEntryOvhd) { UD2FBA( (FLMUINT32)uiChildAddr, &pucCurEntry[m_uiEntrySize]); } entryCount( entryCount() + 1); m_uiPosition++; m_bDirty = TRUE; Exit: return( rc); }
// Not all entries in the buffer represent a valid row. Advance the internal cursor // used for the getNextRow method to the next row which is valid. size_t ResultSet::advanceCursorToNextEntry() const { while (crt_row_buff_idx_ < entryCount()) { const auto entry_idx = permutation_.empty() ? crt_row_buff_idx_ : permutation_[crt_row_buff_idx_]; const auto storage_lookup_result = findStorage(entry_idx); const auto storage = storage_lookup_result.storage_ptr; const auto fixedup_entry_idx = storage_lookup_result.fixedup_entry_idx; if (!storage->isEmptyEntry(fixedup_entry_idx)) { break; } ++crt_row_buff_idx_; } if (permutation_.empty()) { return crt_row_buff_idx_; } CHECK_LE(crt_row_buff_idx_, permutation_.size()); return crt_row_buff_idx_ == permutation_.size() ? crt_row_buff_idx_ : permutation_[crt_row_buff_idx_]; }
/**************************************************************************** Desc: Setup the block as a new block ****************************************************************************/ void F_BtreeBlk::reset( eDynRSetBlkTypes eBlkType) { m_eBlkType = eBlkType; if (eBlkType == ACCESS_BTREE_ROOT || eBlkType == ACCESS_BTREE_NON_LEAF) { m_uiEntryOvhd = 4; } else { m_uiEntryOvhd = 0; } m_uiNumSlots = (DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)) / ( m_uiEntrySize + m_uiEntryOvhd); entryCount( 0); m_uiPosition = DYNSSET_POSITION_NOT_SET; m_bDirty = FALSE; }
/**************************************************************************** Desc: Return the last entry in the result set. ****************************************************************************/ RCODE F_BtreeBlk::getLast( void * pvEntryBuffer) { RCODE rc = NE_FLM_OK; FLMUINT uiPos = entryCount(); // Position to the next/first entry. if (uiPos == 0) { rc = RC_SET( NE_FLM_EOF_HIT); goto Exit; } uiPos--; f_memcpy( pvEntryBuffer, ENTRY_POS(uiPos), m_uiEntrySize); m_uiPosition = uiPos; Exit: return( rc); }
/**************************************************************************** Desc: Split the root block and make two new non-leaf blocks. The secret here is that the root block never moves (cheers!). This takes a little longer but is worth the work because the root block never goes out to disk and is not in the cache. ****************************************************************************/ RCODE F_BtreeRoot::split( void * pvCurEntry, FLMUINT uiCurChildAddr) { RCODE rc = NE_FLM_OK; FLMBYTE * pucEntry; FLMBYTE * pucChildAddr; F_BtreeBlk * pLeftBlk; F_BtreeBlk * pRightBlk; F_BtreeBlk * pBlk; FLMUINT uiChildAddr; FLMUINT uiPos; FLMUINT uiEntryCount = entryCount(); FLMUINT uiMid = (uiEntryCount + 1) >> 1; if (RC_BAD( rc = setupTree( NULL, ACCESS_BTREE_NON_LEAF, &pLeftBlk, &pRightBlk))) { goto Exit; } // Call search entry once just to setup for insert. (void) pLeftBlk->searchEntry( ENTRY_POS( 0)); // Take the entries from the root block and move into leafs. for (uiPos = 0; uiPos <= uiMid; uiPos++) { pucEntry = ENTRY_POS( uiPos); pucChildAddr = pucEntry + m_uiEntrySize; uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); if (RC_BAD( rc = pLeftBlk->insertEntry( pucEntry, uiChildAddr))) { goto Exit; } } // Call search entry once just to setup for insert. (void) pRightBlk->searchEntry( ENTRY_POS( 0)); for (uiPos = uiMid + 1; uiPos < uiEntryCount; uiPos++) { pucEntry = ENTRY_POS( uiPos); pucChildAddr = pucEntry + m_uiEntrySize; uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); if ((rc = pRightBlk->searchEntry( pucEntry )) != NE_FLM_NOT_FOUND) { rc = RC_SET_AND_ASSERT( NE_FLM_FAILURE); goto Exit; } if (RC_BAD( rc = pRightBlk->insertEntry( pucEntry, uiChildAddr))) { goto Exit; } } // Reset the root block and insert new midpoint. entryCount( 0); lemBlk( pRightBlk->blkAddr()); // Duplicated just in case. pucEntry = ENTRY_POS( uiMid); if ((rc = searchEntry( pucEntry )) != NE_FLM_NOT_FOUND) { rc = RC_SET_AND_ASSERT( NE_FLM_FAILURE); goto Exit; } if (RC_BAD( rc = insertEntry( pucEntry, pLeftBlk->blkAddr() ))) { goto Exit; } // Insert the current entry (parameters) into the left or right blk. // This could be done a number of different ways. (void) searchEntry( pvCurEntry, &uiChildAddr); if (RC_BAD( rc = readBlk( uiChildAddr, ACCESS_BTREE_NON_LEAF, &pBlk))) { goto Exit; } (void) pBlk->searchEntry( pvCurEntry); if (RC_BAD( rc = pBlk->insertEntry( pvCurEntry, uiCurChildAddr))) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Move first half of entries into new block. Reset previous block to point to new block. Add new last entry in new block to parent. Fixup prev/next linkages. ****************************************************************************/ RCODE F_BtreeBlk::split( F_BtreeRoot * pRoot, FLMBYTE * pucCurEntry, // (in) Contains entry to insert FLMUINT uiCurBlkAddr, // (in) Blk addr if non-leaf FLMBYTE * pucParentEntry, // (out) Entry to insert into parent. FLMUINT * puiNewBlkAddr) // (out) New blk addr to insert into parent. { RCODE rc = NE_FLM_OK; F_BtreeBlk * pPrevBlk; F_BtreeBlk * pNewBlk = NULL; FLMBYTE * pucEntry = NULL; FLMBYTE * pucMidEntry; FLMBYTE * pucChildAddr; FLMUINT uiChildAddr; FLMUINT uiPrevBlkAddr; FLMUINT uiMid; FLMUINT uiPos; FLMUINT uiMoveBytes; FLMBOOL bInserted = FALSE; // Allocate a new block for the split. if (RC_BAD( rc = pRoot->newBlk( &pNewBlk, blkType() ))) { goto Exit; } pNewBlk->AddRef(); // Pin the block - may get flushed out. // the last half into the new block, but that would force the parent // entry to be changed. This may take a little longer, but it is much // more easier to code. // Call search entry once just to setup for insert. (void) pNewBlk->searchEntry( ENTRY_POS( 0)); // get the count and move more then half into the new block. uiMid = (entryCount() + 5) >> 1; uiChildAddr = FBTREE_END; for (uiPos = 0; uiPos < uiMid; uiPos++) { pucEntry = ENTRY_POS( uiPos); if (blkType() != ACCESS_BTREE_LEAF) { pucChildAddr = pucEntry + m_uiEntrySize; uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); } // m_uiPosition automatically gets incremented. if (RC_BAD( rc = pNewBlk->insertEntry( pucEntry, uiChildAddr))) { RC_UNEXPECTED_ASSERT( rc); goto Exit; } } if (m_uiPosition < uiMid) { // Insert this entry now bInserted = TRUE; (void) pNewBlk->searchEntry( pucCurEntry); if (RC_BAD( rc = pNewBlk->insertEntry( pucCurEntry, uiCurBlkAddr))) { goto Exit; } } // Let caller insert into parent entry. This rids us of recursion. f_memcpy( pucParentEntry, pucEntry, m_uiEntrySize); // Move the rest down pucEntry = ENTRY_POS( 0); pucMidEntry = ENTRY_POS( uiMid); entryCount( entryCount() - uiMid); uiMoveBytes = entryCount() * (m_uiEntrySize + m_uiEntryOvhd); flmAssert( uiMoveBytes < DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)); f_memmove( pucEntry, pucMidEntry, uiMoveBytes); if( !bInserted) { // m_uiPosition -= uiMid; (void) searchEntry( pucCurEntry); if (RC_BAD( rc = insertEntry( pucCurEntry, uiCurBlkAddr))) { goto Exit; } } // VISIT: Could position stack to point to current element to insert. // Fixup the prev/next block linkages. if (prevBlk() != FBTREE_END) { if (RC_BAD( rc = pRoot->readBlk( prevBlk(), blkType(), &pPrevBlk ))) { goto Exit; } pPrevBlk->nextBlk( pNewBlk->blkAddr()); uiPrevBlkAddr = pPrevBlk->blkAddr(); } else { uiPrevBlkAddr = FBTREE_END; } pNewBlk->prevBlk( uiPrevBlkAddr); pNewBlk->nextBlk( blkAddr()); prevBlk( pNewBlk->blkAddr()); *puiNewBlkAddr = pNewBlk->blkAddr(); Exit: if (pNewBlk) { pNewBlk->Release(); } return( rc); }
/**************************************************************************** Desc: Search a single block tree. Position for get* or for insert. Do a binary search on all of the entries to find a match. If no match then position to the entry where an insert will take place. ****************************************************************************/ RCODE F_BtreeBlk::searchEntry( void * pvEntry, FLMUINT * puiChildAddr, void * pvFoundEntry) { RCODE rc = RC_SET( NE_FLM_NOT_FOUND); FLMUINT uiLow; FLMUINT uiMid; FLMUINT uiHigh; FLMUINT uiTblSize; FLMINT iCompare; // check for zero entries. if (!entryCount()) { uiMid = 0; goto Exit; } uiHigh = uiTblSize = entryCount() - 1; uiLow = 0; for(;;) { uiMid = (uiLow + uiHigh) >> 1; // (uiLow + uiHigh) / 2 // Use compare routine if (m_fnCompare) { iCompare = m_fnCompare( pvEntry, ENTRY_POS( uiMid), m_pvUserData); } else { iCompare = f_memcmp( pvEntry, ENTRY_POS( uiMid), m_uiEntrySize); } if (iCompare == 0) { if (pvFoundEntry) { f_memcpy( pvFoundEntry, ENTRY_POS( uiMid), m_uiEntrySize); } rc = NE_FLM_OK; goto Exit; } // Check if we are done - where wLow equals uiHigh or mid is at end. if (iCompare < 0) { if (uiMid == uiLow || uiLow == uiHigh) { break; } uiHigh = uiMid - 1; // Too high } else { if (uiMid == uiHigh || uiLow == uiHigh) { // Go up one for the correct position? uiMid++; break; } uiLow = uiMid + 1; // Too low } } Exit: m_uiPosition = uiMid; if (puiChildAddr && blkType() != ACCESS_BTREE_LEAF) { if (uiMid == entryCount()) { *puiChildAddr = lemBlk(); } else { FLMBYTE * pucChildAddr = ENTRY_POS(uiMid) + m_uiEntrySize; *puiChildAddr = (FLMUINT)FB2UD( pucChildAddr); } } return( rc); }
bool CameraMetadata::isEmpty() const { return entryCount() == 0; }
void testSymbolVersionDefinitions() { ElfFileSet set; set.addFile(QStringLiteral(LIBDIR "libversioned-symbols.so")); QVERIFY(set.size() > 1); auto f = set.file(0); QVERIFY(f); const auto symDefIndex = f->indexOfSection(".gnu.version_d"); const auto symbolVersionDefs = f->section<ElfGNUSymbolVersionDefinitionsSection>(symDefIndex); QVERIFY(symbolVersionDefs); QCOMPARE(symbolVersionDefs->entryCount(), 3u); ElfGNUSymbolVersionDefinition *defV1 = nullptr, *defV2 = nullptr; auto def = symbolVersionDefs->definition(1); QVERIFY(def); QCOMPARE(def->versionIndex(), (uint16_t)2); QCOMPARE(symbolVersionDefs->definitionForVersionIndex(2), def); if (def->auxiliarySize() == 1) defV1 = def; else defV2 = def; def = symbolVersionDefs->definition(2); QVERIFY(def); QCOMPARE(def->versionIndex(), (uint16_t)3); QCOMPARE(symbolVersionDefs->definitionForVersionIndex(3), def); if (def->auxiliarySize() == 1) defV1 = def; else defV2 = def; QVERIFY(defV1); QVERIFY(defV2); QCOMPARE(defV2->auxiliarySize(), (uint16_t)2); auto defEntry = defV2->auxiliaryEntry(0); QVERIFY(defEntry); QCOMPARE(defEntry->name(), "VER2"); defEntry = defV2->auxiliaryEntry(1); QVERIFY(defEntry); QCOMPARE(defEntry->name(), "VER1"); QCOMPARE(defV1->auxiliarySize(), (uint16_t)1); defEntry = defV1->auxiliaryEntry(0); QVERIFY(defEntry); QCOMPARE(defEntry->name(), "VER1"); const auto symVerIndex = f->indexOfSection(".gnu.version"); const auto symbolVersionTable = f->section<ElfGNUSymbolVersionTable>(symVerIndex); QVERIFY(symbolVersionTable); const auto dynTabIndex = f->indexOfSection(".dynsym"); QVERIFY(dynTabIndex > 0); const auto symTab = f->section<ElfSymbolTableSection>(dynTabIndex); QVERIFY(symTab); QCOMPARE(symTab->header()->entryCount(), symbolVersionTable->header()->entryCount()); ElfSymbolTableEntry *f1 = nullptr, *f2 = nullptr, *f_ver1 = nullptr, *f_ver2 = nullptr; for (uint i = 0; i < symTab->header()->entryCount(); ++i) { auto sym = symTab->entry(i); QVERIFY(sym); if (strcmp(sym->name(), "function1") == 0) f1 = sym; else if (strcmp(sym->name(), "function2") == 0) f2 = sym; else if (strcmp(sym->name(), "function") == 0) { qDebug() << symbolVersionTable->versionIndex(i); if (symbolVersionTable->versionIndex(i) == defV2->versionIndex()) f_ver2 = sym; else if (symbolVersionTable->versionIndex(i) == defV1->versionIndex()) f_ver1 = sym; } } QVERIFY(f1); QVERIFY(f2); QVERIFY(f_ver1); QVERIFY(f_ver2); QCOMPARE(f1->value(), f_ver1->value()); QCOMPARE(f2->value(), f_ver2->value()); }
/** **************************************************************************** * Name: IccVCGTTag::Read * * Purpose: Read in the tag contents into a data block * * Args: * size - # of bytes in tag, * pIO - IO object to read tag from * * Return: * true = successful, false = failure ***************************************************************************** */ bool IccVCGTTag::Read(icUInt32Number size, CIccIO *pIO) { qDebug() << "IccVCGTTag::Read"; icTagTypeSignature sig; if (sizeof(icTagTypeSignature) + 2*sizeof(icUInt32Number) + 3*sizeof(icUInt16Number) > size) return false; if (!pIO) { qDebug() << "if (!pIO)"; return false; } if (!pIO->Read32(&sig)) { qDebug() << "if (!pIO->Read32(&sig))"; return false; } qDebug() << "sig = " << (unsigned int)sig; if (!pIO->Read32(&m_nReserved)) { qDebug() << "if (!pIO->Read32(&m_nReserved))"; return false; } qDebug() << "m_nReserved = " << (unsigned int)m_nReserved; icUInt32Number type; if (!pIO->Read32(&type)) { qDebug() << "if (!pIO->Read32(&type))"; return false; } qDebug() << "type =" << (int)type; if(type==cmVideoCardGammaTableType) { //sizes icUInt16Number ch, ec, esz; if (!pIO->Read16(&ch)) return false; if (!pIO->Read16(&ec)) return false; if (!pIO->Read16(&esz)) return false; SetSize(ch, ec); if (curves_) free(curves_); curves_ = (icUInt16Number*)malloc(channels_*entryCount_*sizeof(icUInt16Number)); if(esz == sizeof(icUInt16Number)) { if (pIO->Read16(curves_, channels_*entryCount_)!=(icInt32Number)(channels_*entryCount_)) return false; } else { icInt8Number t; const unsigned long ONE_COEF_16 = 1<<16; const unsigned long ONE_COEF_esz = 1<<(8*esz); for(unsigned i=0;i<channels();++i) for(unsigned j=0;j<entryCount();++j) { unsigned long long v = 0; for(unsigned k=0;k<esz;++k) { if (pIO->Read8(&t, 1)!=1) return false; v = v*2 + t; } curves_[i*entryCount_+j] = icUInt16Number((long double)(v)/(ONE_COEF_esz-1)*(ONE_COEF_16-1)); } } } else if (type == cmVideoCardGammaFormulaType) { SetSize(3, 256); double vcgt[3][3]; // red gamma, red min, red max; green ...; blue ... const unsigned long ONE_COEF = 1<<16; for (unsigned ch = 0; ch < 3; ch++) for (unsigned i = 0; i < 3; i++) { unsigned long value; if (!pIO->Read32(&value)) { qDebug() << "if (!pIO->Read32(&value))" << ch << i; return false; } vcgt[ch][i] = value / static_cast<double>(ONE_COEF); } if (curves_) free(curves_); curves_ = (icUInt16Number*)malloc(channels_*entryCount_*sizeof(icUInt16Number)); for (int ch=0;ch<3;ch++) { if (vcgt[ch][0] < 0.1 || vcgt[ch][0] > 10.0) { qDebug() << "vcgt gamma incorrect value:" << vcgt[ch][0] << "channel:" << ch; return false; } double range = vcgt[ch][2] - vcgt[ch][1]; if (range <= 0.0) { qDebug() << "vcgt incorrect min/max values:" << vcgt[ch][1] << vcgt[ch][2]; } for (int i = 0; i < entryCount_; i++) { double y = vcgt[ch][1] + range * std::pow(i/255.0, vcgt[ch][0]); y = std::min(y, 1.0); curves_[ch*entryCount_ + i] = static_cast<icUInt16Number>(y*(ONE_COEF - 1) ); } } } else { qDebug() << "Unknown VCGT type" << type; return false; } return true; }