CQ3ObjectRef Duplicator::Duplicate( TQ3Object inObject ) { CQ3ObjectRef theDupe; if (ShouldDupe( inObject )) { // If we have already recorded a duplicate for this guy, return a new // reference to it. TQ3Object prevDup = GetDuplicate( inObject ); if (prevDup != NULL) { theDupe = CQ3ObjectRef( Q3Shared_GetReference( prevDup ) ); } else { // Clear the element set for the moment so that if we use // Q3Object_Duplicate, the set will not be duplicated StPullOffElementSet origSet( inObject ); if (Q3Object_IsType( inObject, kQ3GroupTypeDisplay )) { theDupe = DuplicateDisplayGroup( inObject ); } else if (Q3Object_IsType( inObject, kQ3SetTypeAttribute )) { theDupe = DuplicateAttributeSet( inObject ); } else if (Q3Object_IsType( inObject, kQ3SurfaceShaderTypeTexture )) { theDupe = DuplicateTextureShader( inObject ); } else if (Q3Object_IsType( inObject, kQ3ShapeTypeGeometry )) { theDupe = DuplicateGeometry( inObject ); } else { theDupe = CQ3ObjectRef( Q3Object_Duplicate( inObject ) ); } // Duplicate the element set if (origSet.GetSet() != NULL) { CQ3ObjectRef dupSet( Duplicate( origSet.GetSet() ) ); Q3Object_SetSet( theDupe.get(), dupSet.get() ); } RecordDuplicate( inObject, theDupe.get() ); } } else { theDupe = CQ3ObjectRef( Q3Shared_GetReference( inObject ) ); } return theDupe; }
void Why::UtilInterface::getPerfCounters(Firebird::CheckStatusWrapper* status, Firebird::IAttachment* att, const char* countersSet, ISC_INT64* counters) { try { // Parse countersSet unsigned cntLink[TOTAL_COUNTERS]; memset(cntLink, 0xFF, sizeof cntLink); Firebird::string dupSet(countersSet); char* set = dupSet.begin(); char* save = NULL; const char* delim = " \t,;"; unsigned typeMask = 0; unsigned n = 0; UCHAR info[TOTAL_COUNTERS]; // will never use all, but do not care about few bytes UCHAR* pinfo = info; #ifdef WIN_NT #define strtok_r strtok_s #endif for (char* nm = strtok_r(set, delim, &save); nm; nm = strtok_r(NULL, delim, &save)) { Firebird::NoCaseString name(nm); for (unsigned i = 0; i < TOTAL_COUNTERS; ++i) { if (name == knownCounters[i].name) { if (cntLink[i] != ~0u) (Firebird::Arg::Gds(isc_random) << "Duplicated name").raise(); //report name & position cntLink[i] = n++; typeMask |= knownCounters[i].type; if (knownCounters[i].type == CNT_DB_INFO) *pinfo++ = knownCounters[i].code; goto found; } } (Firebird::Arg::Gds(isc_random) << "Unknown name").raise(); //report name & position found: ; } #ifdef WIN_NT #undef strtok_r #endif // Force reset counters memset(counters, 0, n * sizeof(ISC_INT64)); // Fill time counters if (typeMask & CNT_TIMER) { SINT64 tr = fb_utils::query_performance_counter() * 1000 / fb_utils::query_performance_frequency(); SINT64 uTime, sTime; fb_utils::get_process_times(uTime, sTime); for (unsigned i = 0; i < TOTAL_COUNTERS; ++i) { if (cntLink[i] == ~0u) continue; if (knownCounters[i].type == CNT_TIMER) { clock_t v = 0; switch(knownCounters[i].code) { case CNT_TIME_REAL: v = tr; break; case CNT_TIME_USER: v = uTime; break; case CNT_TIME_SYSTEM: v = sTime; break; default: fb_assert(false); break; } counters[cntLink[i]] = v; } } } // Fill DB counters if (typeMask & CNT_DB_INFO) { UCHAR buffer[BUFFER_LARGE]; att->getInfo(status, pinfo - info, info, sizeof(buffer), buffer); if (status->getState() & Firebird::IStatus::STATE_ERRORS) return; const UCHAR* p = buffer; while (true) { SINT64 v = 0; UCHAR ipb = *p++; switch (ipb) { case isc_info_reads: case isc_info_writes: case isc_info_marks: case isc_info_fetches: case isc_info_num_buffers: case isc_info_page_size: case isc_info_current_memory: case isc_info_max_memory: v = get_parameter(&p); break; case isc_info_end: goto parsed; case isc_info_error: { const SINT64 temp = isc_portable_integer(p, 2); fb_assert(temp <= MAX_SSHORT); p += temp + 2; continue; } default: (Firebird::Arg::Gds(isc_random) << "Unknown info code").raise(); //report char code } for (unsigned i = 0; i < TOTAL_COUNTERS; ++i) { if (knownCounters[i].type == CNT_DB_INFO && knownCounters[i].code == ipb) { if (cntLink[i] != ~0u) counters[cntLink[i]] = v; break; } } } parsed: ; } } catch (const Firebird::Exception& ex) { ex.stuffException(status); } }