| /*========================================================================= |
| * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| |
| #include "../gfcpp_globals.hpp" |
| |
| #include <ace/ACE.h> |
| #include <ace/Thread_Mutex.h> |
| #include <ace/Task.h> |
| #include <ace/OS_NS_sys_utsname.h> |
| #include <ace/OS_NS_time.h> |
| #include <ace/OS_NS_sys_time.h> |
| |
| #include "StatArchiveWriter.hpp" |
| #include "GemfireStatisticsFactory.hpp" |
| #include "../impl/NanoTimer.hpp" |
| |
| using namespace gemfire; |
| using namespace gemfire_statistics; |
| |
| // Constructor and Member functions of StatDataOutput class |
| |
| StatDataOutput::StatDataOutput(std::string filename) { |
| if ( filename.length() == 0 ) { |
| std::string s("undefined archive file name"); |
| throw IllegalArgumentException(s.c_str()); |
| } |
| outFile = filename; |
| closed = false; |
| bytesWritten = 0; |
| m_fp = fopen(outFile.c_str(),"a+b"); |
| if ( m_fp == NULL ) { |
| std::string s("error in opening archive file for writing"); |
| throw NullPointerException(s.c_str()); |
| } |
| } |
| |
| StatDataOutput::~StatDataOutput( ) |
| { |
| if (!closed && m_fp != NULL) |
| { |
| fclose(m_fp); |
| } |
| } |
| |
| int64 |
| StatDataOutput::getBytesWritten() { |
| return this->bytesWritten; |
| } |
| |
| void |
| StatDataOutput::flush() { |
| const uint8 * buffBegin = dataBuffer.getBuffer(); |
| if ( buffBegin == NULL ) { |
| std::string s("undefined stat data buffer beginning"); |
| throw NullPointerException(s.c_str()); |
| } |
| const uint8 * buffEnd = dataBuffer.getCursor(); |
| if ( buffEnd == NULL ) { |
| std::string s("undefined stat data buffer end"); |
| throw NullPointerException(s.c_str()); |
| } |
| int32 sizeOfUInt8 = sizeof(uint8); |
| int32 len = static_cast<int32> (buffEnd - buffBegin) ; |
| |
| if ( len > 0 ) { |
| if ( fwrite(buffBegin, sizeOfUInt8, len, m_fp) != (size_t)len ) { |
| LOGERROR("Could not write into the statistics file"); |
| throw GemfireIOException("Could not write into the statistics file"); |
| } |
| } |
| int rVal = fflush(m_fp); |
| if(rVal != 0) { |
| LOGERROR("Could not flush into the statistics file"); |
| throw GemfireIOException("Could not flush into the statistics file"); |
| } |
| } |
| |
| |
| void |
| StatDataOutput::resetBuffer() { |
| dataBuffer.reset(); |
| bytesWritten = 0; |
| } |
| |
| void |
| StatDataOutput::writeByte(int8 v) { |
| dataBuffer.write((int8_t)v); |
| bytesWritten += 1; |
| } |
| |
| void |
| StatDataOutput::writeBoolean(int8 v) { |
| writeByte(v); |
| } |
| |
| void |
| StatDataOutput::writeShort(int16 v) { |
| dataBuffer.writeInt(v); |
| bytesWritten += 2; |
| } |
| |
| void |
| StatDataOutput::writeInt(int32 v) { |
| dataBuffer.writeInt(v); |
| bytesWritten += 4; |
| } |
| |
| void |
| StatDataOutput::writeLong(int64 v) { |
| dataBuffer.writeInt(v); |
| bytesWritten += 8; |
| } |
| |
| void |
| StatDataOutput::writeString(std::string s) { |
| size_t len = s.length(); |
| dataBuffer.writeASCII(s.data(), (uint32_t)len); |
| bytesWritten += len; |
| } |
| |
| void |
| StatDataOutput::writeUTF(std::wstring s) { |
| size_t len = s.length(); |
| dataBuffer.writeUTF(s.data(), (uint32_t)len); |
| bytesWritten += len; |
| } |
| |
| void |
| StatDataOutput::close() { |
| fclose(m_fp); |
| m_fp=NULL; |
| closed=true; |
| } |
| |
| void StatDataOutput::openFile(std::string filename, int64 size) |
| { |
| m_fp = fopen(filename.c_str(),"a+b"); |
| if ( m_fp == NULL ) { |
| std::string s("error in opening archive file for writing"); |
| throw NullPointerException(s.c_str()); |
| } |
| closed=false; |
| bytesWritten = size; |
| } |
| |
| |
| // Constructor and Member functions of ResourceType class |
| |
| ResourceType::ResourceType(int32 idArg, StatisticsType * typeArg) { |
| StatisticsType * typeImpl = dynamic_cast<StatisticsType *> (typeArg); |
| if (typeImpl == NULL) { |
| std::string s("could not down cast to StatisticsType"); |
| throw NullPointerException(s.c_str()); |
| } |
| this->id = idArg; |
| this->stats = typeImpl->getStatistics(); |
| int32 desc = typeImpl->getDescriptorsCount(); |
| this->numOfDescriptors = desc; |
| } |
| |
| int32 |
| ResourceType::getId() { |
| return this->id; |
| } |
| |
| int32 |
| ResourceType::getNumOfDescriptors() { |
| return this->numOfDescriptors; |
| } |
| |
| StatisticDescriptor ** |
| ResourceType::getStats() { |
| return this->stats; |
| } |
| |
| // Constructor and Member functions of ResourceInst class |
| |
| ResourceInst::ResourceInst(int32 idArg, Statistics * resourceArg, ResourceType * typeArg, StatDataOutput * dataOutArg) { |
| this->id = idArg; |
| this->resource = resourceArg; |
| this->type = typeArg; |
| this->dataOut = dataOutArg; |
| int32 cnt = type->getNumOfDescriptors(); |
| archivedStatValues = new int64[cnt]; |
| // initialize to zero |
| for(int32 i=0;i<cnt;i++) { |
| archivedStatValues[i] = 0; |
| } |
| numOfDescps = cnt; |
| firstTime = true; |
| } |
| |
| ResourceInst::~ResourceInst() { |
| delete [] archivedStatValues; |
| } |
| |
| int32 |
| ResourceInst::getId() { |
| return this->id; |
| } |
| |
| Statistics * |
| ResourceInst::getResource() { |
| return this->resource; |
| } |
| |
| ResourceType * |
| ResourceInst::getType() { |
| return this->type; |
| } |
| |
| int64 |
| ResourceInst::getStatValue(StatisticDescriptor * f) { |
| return this->resource->getRawBits(f); |
| } |
| |
| void |
| ResourceInst::writeSample() { |
| bool wroteInstId = false; |
| bool checkForChange = true; |
| StatisticDescriptor ** stats = this->type->getStats(); |
| GF_D_ASSERT(stats != NULL); |
| GF_D_ASSERT(*stats != NULL); |
| if (this->resource->isClosed()) { |
| return; |
| } |
| if (firstTime) { |
| firstTime = false; |
| checkForChange = false; |
| } |
| for (int32 i = 0; i < numOfDescps; i++) { |
| int64 value = getStatValue(stats[i]); |
| if (!checkForChange || value != archivedStatValues[i]) { |
| int64 delta = value - archivedStatValues[i]; |
| archivedStatValues[i] = value; |
| if(!wroteInstId) { |
| wroteInstId = true; |
| writeResourceInst(this->dataOut, (int32)this->id); |
| } |
| this->dataOut->writeByte(i); |
| writeStatValue(stats[i], delta); |
| } |
| } |
| if (wroteInstId) { |
| this->dataOut->writeByte((unsigned char) ILLEGAL_STAT_OFFSET); |
| } |
| } |
| |
| void |
| ResourceInst::writeStatValue(StatisticDescriptor * sd, int64 v) { |
| StatisticDescriptorImpl* sdImpl = (StatisticDescriptorImpl *)sd; |
| if (sdImpl == NULL) { |
| throw NullPointerException("could not downcast to StatisticDescriptorImpl"); |
| } |
| FieldType typeCode = sdImpl->getTypeCode(); |
| |
| switch(typeCode) { |
| /* case GF_FIELDTYPE_BYTE: |
| this->dataOut->writeByte((int8)v); |
| break; */ |
| /* case GF_FIELDTYPE_SHORT: |
| this->dataOut->writeShort((int16)v); |
| break; */ |
| case INT_TYPE: |
| case LONG_TYPE: |
| // case GF_FIELDTYPE_FLOAT: |
| case DOUBLE_TYPE: |
| writeCompactValue(v); |
| break; |
| default: |
| std::string s = "Unexpected type code"; |
| throw IllegalArgumentException(s.c_str()); |
| break; |
| } |
| } |
| |
| void |
| ResourceInst::writeCompactValue(int64 v) { |
| if (v <= MAX_1BYTE_COMPACT_VALUE && v >= MIN_1BYTE_COMPACT_VALUE) { |
| this->dataOut->writeByte((int8)v); |
| } else if (v <= MAX_2BYTE_COMPACT_VALUE && v >= MIN_2BYTE_COMPACT_VALUE) { |
| this->dataOut->writeByte(COMPACT_VALUE_2_TOKEN); |
| this->dataOut->writeShort((int16)v); |
| } else { |
| int8 buffer[8]; |
| int32 idx = 0; |
| if (v < 0) { |
| while (v != -1 && v != 0) { |
| buffer[idx++] = (int8)(v & 0xFF); |
| v >>= 8; |
| } |
| // On windows v goes to zero somtimes; seems like a bug |
| if (v == 0) { |
| // when this happens we end up with a bunch of -1 bytes |
| // so strip off the high order ones |
| while (buffer[idx-1] == -1) { |
| idx--; |
| } |
| } |
| if ((buffer[idx-1] & 0x80) == 0) { |
| /* If the most significant byte does not have its high order bit set |
| * then add a -1 byte so we know this is a negative number |
| */ |
| buffer[idx++] = -1; |
| } |
| } else { |
| while (v != 0) { |
| buffer[idx++] = (int8)(v & 0xFF); |
| v >>= 8; |
| } |
| if ((buffer[idx-1] & 0x80) != 0) { |
| /* If the most significant byte has its high order bit set |
| * then add a zero byte so we know this is a positive number |
| */ |
| buffer[idx++] = 0; |
| } |
| } |
| int8 token = COMPACT_VALUE_2_TOKEN + (idx - 2); |
| this->dataOut->writeByte(token); |
| for (int32 i=idx-1; i >= 0; i--) { |
| this->dataOut->writeByte(buffer[i]); |
| } |
| } |
| } |
| |
| void |
| ResourceInst::writeResourceInst(StatDataOutput * dataOutArg, int32 instId) { |
| if (instId > MAX_BYTE_RESOURCE_INST_ID) { |
| if (instId > MAX_SHORT_RESOURCE_INST_ID) { |
| dataOutArg->writeByte((int8)INT_RESOURCE_INST_ID_TOKEN); |
| dataOutArg->writeInt((int32)instId); |
| } else { |
| dataOutArg->writeByte((int8)SHORT_RESOURCE_INST_ID_TOKEN); |
| dataOutArg->writeShort(instId); |
| } |
| } else { |
| dataOutArg->writeByte((int8)instId); |
| } |
| } |
| |
| |
| // Constructor and Member functions of StatArchiveWriter class |
| StatArchiveWriter::StatArchiveWriter(std::string outfile,HostStatSampler* samplerArg) { |
| |
| resourceTypeId = 0; |
| resourceInstId = 0; |
| statResourcesModCount = 0; |
| archiveFile = outfile; |
| bytesWrittenToFile = 0; |
| |
| /* adongre |
| * CID 28982: Uninitialized scalar field (UNINIT_CTOR) |
| */ |
| m_samplesize = 0; |
| |
| dataBuffer = new StatDataOutput(archiveFile); |
| this->sampler = samplerArg; |
| |
| // write the time, system property etc. |
| this->previousTimeStamp = NanoTimer::now(); |
| this->previousTimeStamp += NANOS_PER_MILLI/2; |
| this->previousTimeStamp /= NANOS_PER_MILLI; |
| ACE_Time_Value now = ACE_OS::gettimeofday(); |
| int64 epochsec = now.sec(); |
| int64 initialDate = (int64)epochsec * 1000; |
| |
| this->dataBuffer->writeByte(HEADER_TOKEN); |
| this->dataBuffer->writeByte(ARCHIVE_VERSION); |
| this->dataBuffer->writeLong(initialDate); |
| int64 sysId = sampler->getSystemId(); |
| this->dataBuffer->writeLong((int64)sysId); |
| int64 sysStartTime = sampler->getSystemStartTime(); |
| this->dataBuffer->writeLong(sysStartTime); |
| int32 tzOffset = ACE_OS::timezone(); |
| // offset in milli seconds |
| tzOffset = tzOffset * -1 * 1000; |
| // tzOffset = tzOffset * 1000; |
| this->dataBuffer->writeInt(tzOffset); |
| |
| struct tm* tm_val; |
| time_t clock = ACE_OS::time(); |
| tm_val = localtime(&clock); |
| char buf[512] = {0}; |
| ACE_OS::strftime(buf, sizeof(buf), "%Z", tm_val); |
| std::string tzId(buf); |
| this->dataBuffer->writeString(tzId); |
| |
| std::string sysDirPath = sampler->getSystemDirectoryPath(); |
| this->dataBuffer->writeString(sysDirPath); |
| std::string prodDesc = sampler->getProductDescription(); |
| |
| this->dataBuffer->writeString(prodDesc); |
| ACE_utsname u; |
| ACE_OS::uname(&u); |
| std::string os(u.sysname); |
| os += " "; |
| /* This version name returns date of release of the version which |
| creates confusion about the creation time of the vsd file. Hence |
| removing it now. Later I'll change it to just show version without |
| date. For now only name of the OS will be displayed. |
| */ |
| //os += u.version; |
| |
| this->dataBuffer->writeString(os); |
| std::string machineInfo(u.machine); |
| machineInfo += " "; |
| machineInfo += u.nodename; |
| this->dataBuffer->writeString(machineInfo); |
| |
| resampleResources(); |
| } |
| |
| StatArchiveWriter::~StatArchiveWriter() { |
| if ( dataBuffer != NULL ) { |
| delete dataBuffer; |
| dataBuffer = NULL; |
| } |
| std::map<StatisticsType*, ResourceType*>::iterator p; |
| for(p=resourceTypeMap.begin(); p!=resourceTypeMap.end(); p++) { |
| ResourceType * rt = (*p).second; |
| GF_SAFE_DELETE(rt); |
| } |
| } |
| |
| int64 |
| StatArchiveWriter::bytesWritten() { |
| return bytesWrittenToFile; |
| } |
| |
| int64 StatArchiveWriter::getSampleSize() |
| { |
| return m_samplesize; |
| } |
| |
| void |
| StatArchiveWriter::sample(int64 timeStamp) { |
| ACE_Guard<ACE_Recursive_Thread_Mutex> guard(sampler->getStatListMutex()); |
| m_samplesize = dataBuffer->getBytesWritten(); |
| |
| sampleResources(); |
| this->dataBuffer->writeByte(SAMPLE_TOKEN); |
| writeTimeStamp(timeStamp); |
| std::map<Statistics *, ResourceInst*>::iterator p; |
| for(p=resourceInstMap.begin(); p!=resourceInstMap.end(); p++) { |
| ResourceInst * ri = (*p).second; |
| if ( !!ri && (*p).first != NULL ) { |
| ri->writeSample(); |
| } |
| } |
| writeResourceInst(this->dataBuffer, (int32)ILLEGAL_RESOURCE_INST_ID); |
| m_samplesize = dataBuffer->getBytesWritten() - m_samplesize; |
| } |
| |
| void |
| StatArchiveWriter::sample() { |
| int64 timestamp = NanoTimer::now(); |
| sample(timestamp); |
| } |
| |
| void |
| StatArchiveWriter::close() { |
| sample(); |
| this->dataBuffer->flush(); |
| this->dataBuffer->close(); |
| } |
| |
| |
| void StatArchiveWriter::closeFile() |
| { |
| this->dataBuffer->close(); |
| } |
| |
| void StatArchiveWriter::openFile(std::string filename) |
| { |
| //this->dataBuffer->openFile(filename, m_samplesize); |
| |
| StatDataOutput * p_dataBuffer = new StatDataOutput(filename); |
| |
| /* |
| ACE_Time_Value now = ACE_OS::gettimeofday(); |
| int64 epochsec = now.sec(); |
| int64 initialDate = (int64)epochsec * 1000; |
| |
| p_dataBuffer->writeByte(HEADER_TOKEN); |
| p_dataBuffer->writeByte(ARCHIVE_VERSION); |
| p_dataBuffer->writeLong(initialDate); |
| int64 sysId = sampler->getSystemId(); |
| p_dataBuffer->writeLong((int64)sysId); |
| int64 sysStartTime = sampler->getSystemStartTime(); |
| p_dataBuffer->writeLong(sysStartTime); |
| int32 tzOffset = ACE_OS::timezone(); |
| // offset in milli seconds |
| tzOffset = tzOffset * -1 * 1000; |
| // tzOffset = tzOffset * 1000; |
| p_dataBuffer->writeInt(tzOffset); |
| |
| struct tm* tm_val; |
| time_t clock = ACE_OS::time(); |
| tm_val = localtime(&clock); |
| char buf[512] = {0}; |
| ACE_OS::strftime(buf, sizeof(buf), "%Z", tm_val); |
| std::string tzId(buf); |
| p_dataBuffer->writeString(tzId); |
| |
| std::string sysDirPath = sampler->getSystemDirectoryPath(); |
| p_dataBuffer->writeString(sysDirPath); |
| std::string prodDesc = sampler->getProductDescription(); |
| |
| p_dataBuffer->writeString(prodDesc); |
| ACE_utsname u; |
| ACE_OS::uname(&u); |
| std::string os(u.sysname); |
| os += " "; |
| |
| p_dataBuffer->writeString(os); |
| std::string machineInfo(u.machine); |
| machineInfo += " "; |
| machineInfo += u.nodename; |
| p_dataBuffer->writeString(machineInfo); |
| */ |
| |
| const uint8 * buffBegin = dataBuffer->dataBuffer.getBuffer(); |
| if ( buffBegin == NULL ) { |
| std::string s("undefined stat data buffer beginning"); |
| throw NullPointerException(s.c_str()); |
| } |
| const uint8 * buffEnd = dataBuffer->dataBuffer.getCursor(); |
| if ( buffEnd == NULL ) { |
| std::string s("undefined stat data buffer end"); |
| throw NullPointerException(s.c_str()); |
| } |
| int32 len = (int32)(buffEnd - buffBegin) ; |
| |
| for (int pos = 0; pos < len; pos++) |
| { |
| p_dataBuffer->writeByte(buffBegin[pos]); |
| } |
| |
| delete dataBuffer; |
| dataBuffer = p_dataBuffer; |
| |
| //sample(); |
| } |
| |
| void |
| StatArchiveWriter::flush() { |
| |
| this->dataBuffer->flush(); |
| bytesWrittenToFile += dataBuffer->getBytesWritten(); |
| this->dataBuffer->resetBuffer(); |
| /* |
| // have to figure out the problem with this code. |
| delete dataBuffer; |
| dataBuffer = NULL; |
| |
| dataBuffer = new StatDataOutput(archiveFile); |
| */ |
| } |
| |
| void |
| StatArchiveWriter::sampleResources() |
| { |
| //Allocate ResourceInst for newly added stats ( Locked lists already ) |
| std::vector<Statistics *>& newStatsList = sampler->getNewStatistics(); |
| std::vector<Statistics *>::iterator newlistIter; |
| for(newlistIter=newStatsList.begin(); newlistIter != newStatsList.end(); ++newlistIter) { |
| if (!resourceInstMapHas(*newlistIter)) { |
| allocateResourceInst(*newlistIter); |
| } |
| } |
| newStatsList.clear(); |
| |
| // for closed stats, write token and then delete from statlist and resourceInstMap. |
| std::map<Statistics *, ResourceInst*>::iterator mapIter; |
| std::vector<Statistics *>& statsList = sampler->getStatistics(); |
| std::vector<Statistics *>::iterator statlistIter = statsList.begin(); |
| while(statlistIter != statsList.end()) { |
| if((*statlistIter)->isClosed()){ |
| mapIter = resourceInstMap.find(*statlistIter); |
| if (mapIter != resourceInstMap.end()) { |
| //Write delete token to file and delete from map |
| ResourceInst * rinst = (*mapIter).second; |
| int32 id = rinst->getId(); |
| this->dataBuffer->writeByte(RESOURCE_INSTANCE_DELETE_TOKEN); |
| this->dataBuffer->writeInt(id); |
| resourceInstMap.erase(mapIter); |
| delete rinst; |
| } |
| //Delete stats object stat list |
| StatisticsManager::deleteStatistics(*statlistIter); |
| statsList.erase(statlistIter); |
| statlistIter = statsList.begin(); |
| }else { |
| ++statlistIter; |
| } |
| } |
| } |
| |
| void |
| StatArchiveWriter::resampleResources() |
| { |
| ACE_Guard<ACE_Recursive_Thread_Mutex> guard(sampler->getStatListMutex()); |
| std::vector<Statistics *>& statsList = sampler->getStatistics(); |
| std::vector<Statistics *>::iterator statlistIter = statsList.begin(); |
| while(statlistIter != statsList.end()) { |
| if(!(*statlistIter)->isClosed()){ |
| allocateResourceInst(*statlistIter); |
| } |
| ++statlistIter; |
| } |
| } |
| |
| void |
| StatArchiveWriter::writeTimeStamp(int64 timeStamp) { |
| timeStamp += NANOS_PER_MILLI/2; |
| timeStamp /= NANOS_PER_MILLI; |
| int64 delta = timeStamp - this->previousTimeStamp; |
| //printf("delta = %lld\n", delta); |
| if ( delta > MAX_SHORT_TIMESTAMP) { |
| dataBuffer->writeShort((int16_t) INT_TIMESTAMP_TOKEN); |
| dataBuffer->writeInt((int32)delta); |
| } else { |
| dataBuffer->writeShort((uint16)delta); |
| } |
| this->previousTimeStamp = timeStamp; |
| } |
| |
| bool |
| StatArchiveWriter::resourceInstMapHas(Statistics * sp) { |
| std::map<Statistics *, ResourceInst*>::iterator p; |
| p = resourceInstMap.find(sp); |
| if (p != resourceInstMap.end()) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| void |
| StatArchiveWriter::allocateResourceInst(Statistics * s) { |
| if(s->isClosed()) |
| return; |
| ResourceType * type = getResourceType(s); |
| |
| ResourceInst * ri = new ResourceInst(resourceInstId, s, type, dataBuffer); |
| if (ri == NULL) { |
| std::string s("could not create new resource instance"); |
| throw NullPointerException(s.c_str()); |
| } |
| resourceInstMap.insert(std::pair<Statistics *,ResourceInst*>(s,ri)); |
| this->dataBuffer->writeByte(RESOURCE_INSTANCE_CREATE_TOKEN); |
| this->dataBuffer->writeInt((int32)resourceInstId); |
| this->dataBuffer->writeString(s->getTextId()); |
| this->dataBuffer->writeLong((int64)s->getNumericId()); |
| this->dataBuffer->writeInt((int32)type->getId()); |
| |
| resourceInstId++; |
| } |
| |
| ResourceType * |
| StatArchiveWriter::getResourceType(Statistics * s) { |
| StatisticsType * type = s->getType(); |
| if ( type == NULL ) { |
| std::string s("could not know the type of the statistics object"); |
| throw NullPointerException(s.c_str()); |
| } |
| ResourceType * rt = NULL; |
| std::map<StatisticsType*, ResourceType*>::iterator p; |
| p = resourceTypeMap.find(type); |
| if ( p != resourceTypeMap.end() ) { |
| rt = (*p).second; |
| } else { |
| rt = new ResourceType(resourceTypeId, type); |
| if ( type == NULL ) { |
| std::string s("could not allocate memory for a new resourcetype"); |
| throw NullPointerException(s.c_str()); |
| } |
| resourceTypeMap.insert(std::pair<StatisticsType*, ResourceType*>(type, rt)); |
| // write the type to the archive |
| this->dataBuffer->writeByte(RESOURCE_TYPE_TOKEN); |
| this->dataBuffer->writeInt((int32)resourceTypeId); |
| this->dataBuffer->writeString(type->getName()); |
| this->dataBuffer->writeString(type->getDescription()); |
| StatisticDescriptor ** stats = rt->getStats(); |
| int32 descCnt = rt->getNumOfDescriptors(); |
| this->dataBuffer->writeShort((int16)descCnt); |
| for (int32 i=0;i<descCnt;i++) { |
| std::string statsName = stats[i]->getName(); |
| this->dataBuffer->writeString(statsName); |
| StatisticDescriptorImpl* sdImpl = (StatisticDescriptorImpl*)stats[i]; |
| if (sdImpl == NULL) { |
| std::string err("could not down cast to StatisticDescriptorImpl"); |
| throw NullPointerException(err.c_str()); |
| } |
| this->dataBuffer->writeByte((int8)sdImpl->getTypeCode()); |
| this->dataBuffer->writeBoolean(stats[i]->isCounter()); |
| this->dataBuffer->writeBoolean(stats[i]->isLargerBetter()); |
| this->dataBuffer->writeString(stats[i]->getUnit()); |
| this->dataBuffer->writeString(stats[i]->getDescription()); |
| } |
| // increment resourceTypeId |
| resourceTypeId++; |
| } |
| return rt; |
| } |
| |
| void |
| StatArchiveWriter::writeResourceInst(StatDataOutput * dataOut, int32 instId) { |
| if (instId > MAX_BYTE_RESOURCE_INST_ID) { |
| if (instId > MAX_SHORT_RESOURCE_INST_ID) { |
| dataOut->writeByte((int8)INT_RESOURCE_INST_ID_TOKEN); |
| dataOut->writeInt((int32)instId); |
| } else { |
| dataOut->writeByte((int8)SHORT_RESOURCE_INST_ID_TOKEN); |
| dataOut->writeShort(instId); |
| } |
| } else { |
| dataOut->writeByte((int8)instId); |
| } |
| } |