static void createVariantUnionRecord( PVDatabasePtr const &master, string const &recordName) { StructureConstPtr top = fieldCreate->createFieldBuilder()-> add("value",fieldCreate->createVariantUnion())-> createStructure(); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top); PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure); bool result = master->addRecord(pvRecord); if(!result) cout<< "record " << recordName << " not added" << endl; }
namespace epics { namespace pvaClient { static FieldCreatePtr fieldCreate = getFieldCreate(); static const string pvaClientName = "pvaClient"; static const string defaultProvider = "pva"; static UnionConstPtr variantUnion = fieldCreate->createVariantUnion(); namespace pvaClientPvt { static size_t numberPvaClient = 0; static bool firstTime = true; static Mutex mutex; class StartStopClientFactory { public: static void PvaClientBeingConstructed() { bool saveFirst = false; { Lock xx(mutex); ++numberPvaClient; saveFirst = firstTime; firstTime = false; } if(saveFirst) { ClientFactory::start(); CAClientFactory::start(); } } static void PvaClientBeingDestroyed() { size_t numLeft = 0; { Lock xx(mutex); --numberPvaClient; numLeft = numberPvaClient; } if(numLeft<=0) { ClientFactory::stop(); CAClientFactory::stop(); } } }; } // namespace pvaClientPvt class PvaClientChannelCache { public: PvaClientChannelCache(){} ~PvaClientChannelCache(){ destroy(); } void destroy() { pvaClientChannelMap.clear(); } PvaClientChannelPtr getChannel( string const & channelName, string const & providerName); void addChannel(PvaClientChannelPtr const & pvaClientChannel); void removeChannel(string const & channelName,string const & providerName); void showCache(); size_t cacheSize(); private: map<string,PvaClientChannelPtr> pvaClientChannelMap; }; PvaClientChannelPtr PvaClientChannelCache::getChannel( string const & channelName, string const & providerName) { string name = channelName + providerName; map<string,PvaClientChannelPtr>::iterator iter = pvaClientChannelMap.find(name); if(iter!=pvaClientChannelMap.end()) return iter->second; return PvaClientChannelPtr(); } void PvaClientChannelCache::addChannel(PvaClientChannelPtr const & pvaClientChannel) { Channel::shared_pointer channel = pvaClientChannel->getChannel(); string name = channel->getChannelName() + channel->getProvider()->getProviderName(); pvaClientChannelMap.insert(std::pair<string,PvaClientChannelPtr>( name,pvaClientChannel)); } void PvaClientChannelCache::removeChannel( string const & channelName, string const & providerName) { string name = channelName + providerName; map<string,PvaClientChannelPtr>::iterator iter = pvaClientChannelMap.find(name); if(iter!=pvaClientChannelMap.end()) pvaClientChannelMap.erase(iter); } void PvaClientChannelCache::showCache() { map<string,PvaClientChannelPtr>::iterator iter; for(iter = pvaClientChannelMap.begin(); iter != pvaClientChannelMap.end(); ++iter) { PvaClientChannelPtr pvaChannel = iter->second; Channel::shared_pointer channel = pvaChannel->getChannel(); string channelName = channel->getChannelName(); string providerName = channel->getProvider()->getProviderName(); cout << "channel " << channelName << " provider " << providerName << endl; cout << " get and put cacheSize " << pvaChannel->cacheSize() << endl; pvaChannel->showCache(); } } size_t PvaClientChannelCache::cacheSize() { return pvaClientChannelMap.size(); } using namespace epics::pvaClient::pvaClientPvt; PvaClientPtr PvaClient::create() { PvaClientPtr xx(new PvaClient()); StartStopClientFactory::PvaClientBeingConstructed(); return xx; } PvaClient::PvaClient() : pvaClientChannelCache(new PvaClientChannelCache()), isDestroyed(false) { } PvaClient::~PvaClient() { destroy(); } void PvaClient::destroy() { { Lock xx(mutex); if(isDestroyed) return; isDestroyed = true; } pvaClientChannelCache.reset(); StartStopClientFactory::PvaClientBeingDestroyed(); } string PvaClient:: getRequesterName() { static string name("pvaClient"); RequesterPtr req = requester.lock(); if(req) { return req->getRequesterName(); } return name; } void PvaClient::message( string const & message, MessageType messageType) { RequesterPtr req = requester.lock(); if(req) { req->message(message,messageType); return; } cout << getMessageTypeName(messageType) << " " << message << endl; } PvaClientChannelPtr PvaClient::channel( std::string const & channelName, std::string const & providerName, double timeOut) { PvaClientChannelPtr pvaClientChannel = pvaClientChannelCache->getChannel(channelName,providerName); if(pvaClientChannel) return pvaClientChannel; pvaClientChannel = createChannel(channelName,providerName); pvaClientChannel->connect(timeOut); pvaClientChannelCache->addChannel(pvaClientChannel); return pvaClientChannel; } PvaClientChannelPtr PvaClient::createChannel(string const & channelName, string const & providerName) { return PvaClientChannel::create(getPtrSelf(),channelName,providerName); } void PvaClient::setRequester(RequesterPtr const & requester) { this->requester = requester; } void PvaClient::clearRequester() { requester = Requester::weak_pointer(); } void PvaClient::showCache() { pvaClientChannelCache->showCache(); } size_t PvaClient::cacheSize() { return pvaClientChannelCache->cacheSize(); } }}
StructureConstPtr NTNDArrayBuilder::createStructure() { enum { DISCRIPTOR_INDEX, TIMESTAMP_INDEX, ALARM_INDEX, DISPLAY_INDEX }; const size_t NUMBER_OF_INDICES = DISPLAY_INDEX+1; const size_t NUMBER_OF_STRUCTURES = 1 << NUMBER_OF_INDICES; Lock xx(mutex); static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES]; static UnionConstPtr valueType; static StructureConstPtr codecStruc; static StructureConstPtr dimensionStruc; static StructureConstPtr attributeStruc; StructureConstPtr returnedStruc; size_t index = 0; if (descriptor) index |= 1 << DISCRIPTOR_INDEX; if (timeStamp) index |= 1 << TIMESTAMP_INDEX; if (alarm) index |= 1 << ALARM_INDEX; if (display) index |= 1 << DISPLAY_INDEX; bool isExtended = !extraFieldNames.empty(); if (isExtended || !ntndarrayStruc[index]) { StandardFieldPtr standardField = getStandardField(); FieldBuilderPtr fb = fieldCreate->createFieldBuilder(); if (!valueType) { for (int i = pvBoolean; i < pvString; ++i) { ScalarType st = static_cast<ScalarType>(i); fb->addArray(std::string(ScalarTypeFunc::name(st)) + "Value", st); } valueType = fb->createUnion(); } if (!codecStruc) { codecStruc = fb->setId("codec_t")-> add("name", pvString)-> add("parameters", fieldCreate->createVariantUnion())-> createStructure(); } if (!dimensionStruc) { dimensionStruc = fb->setId("dimension_t")-> add("size", pvInt)-> add("offset", pvInt)-> add("fullSize", pvInt)-> add("binning", pvInt)-> add("reverse", pvBoolean)-> createStructure(); } if (!attributeStruc) { attributeStruc = NTNDArrayAttribute::createBuilder()->createStructure(); } fb->setId(NTNDArray::URI)-> add("value", valueType)-> add("codec", codecStruc)-> add("compressedSize", pvLong)-> add("uncompressedSize", pvLong)-> addArray("dimension", dimensionStruc)-> add("uniqueId", pvInt)-> add("dataTimeStamp", standardField->timeStamp())-> addArray("attribute", attributeStruc); if (descriptor) fb->add("descriptor", pvString); if (alarm) fb->add("alarm", standardField->alarm()); if (timeStamp) fb->add("timeStamp", standardField->timeStamp()); if (display) fb->add("display", standardField->display()); size_t extraCount = extraFieldNames.size(); for (size_t i = 0; i< extraCount; i++) fb->add(extraFieldNames[i], extraFields[i]); returnedStruc = fb->createStructure(); if (!isExtended) ntndarrayStruc[index] = returnedStruc; } else { return ntndarrayStruc[index]; } return returnedStruc; }