Beispiel #1
0
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;
}
Beispiel #2
0
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);
	}
}