updateMaster was putting to every client field instead of only changed fields

This commit is contained in:
mrkraimer
2019-05-18 10:11:00 -04:00
parent 2715f585e0
commit e1adfe30df
2 changed files with 91 additions and 41 deletions

View File

@ -204,10 +204,16 @@ private:
epics::pvData::PVFieldPtr const &pvCopy, epics::pvData::PVFieldPtr const &pvCopy,
CopyNodePtr const &node, CopyNodePtr const &node,
epics::pvData::BitSetPtr const &bitSet); epics::pvData::BitSetPtr const &bitSet);
void updateMaster( void updateMasterField(
epics::pvData::PVFieldPtr const &pvCopy, CopyNodePtr const & node,
CopyNodePtr const &node, epics::pvData::PVFieldPtr const & pvCopy,
epics::pvData::PVFieldPtr const &pvMaster,
epics::pvData::BitSetPtr const &bitSet); epics::pvData::BitSetPtr const &bitSet);
void updateMasterCheckBitSet(
epics::pvData::PVStructurePtr const &copyPVStructure,
epics::pvData::BitSetPtr const &bitSet,
size_t nextSet);
CopyNodePtr getCopyNode(std::size_t fieldOffset);
PVCopy(epics::pvData::PVStructurePtr const &pvMaster); PVCopy(epics::pvData::PVStructurePtr const &pvMaster);
bool init(epics::pvData::PVStructurePtr const &pvRequest); bool init(epics::pvData::PVStructurePtr const &pvRequest);

View File

@ -212,19 +212,93 @@ bool PVCopy::updateCopyFromBitSet(
return checkIgnore(copyPVStructure,bitSet); return checkIgnore(copyPVStructure,bitSet);
} }
void PVCopy::updateMasterField(
CopyNodePtr const & node,
PVFieldPtr const & pvCopy,
PVFieldPtr const &pvMaster,
BitSetPtr const &bitSet)
{
bool result = false;
for(size_t i=0; i< node->pvFilters.size(); ++i) {
PVFilterPtr pvFilter = node->pvFilters[i];
if(pvFilter->filter(pvCopy,bitSet,false)) result = true;
}
if(result) return;
pvMaster->copyUnchecked(*pvCopy);
}
void PVCopy::updateMasterCheckBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet,
size_t nextSet)
{
if(!bitSet->get(nextSet)) {
size_t next = bitSet->nextSetBit(nextSet);
if(next==string::npos) return;
updateMasterCheckBitSet(copyPVStructure,bitSet,next);
return;
}
PVFieldPtr pvField = copyPVStructure;
if(nextSet!=0) pvField = copyPVStructure->getSubField(nextSet);
if(pvField->getField()->getType()==epics::pvData::structure) {
bitSet->clear(nextSet);
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField);
PVFieldPtrArray pvFieldArray = pv->getPVFields();
for(size_t i=0; i>pvFieldArray.size(); ++i) {
PVFieldPtr pvField = pvFieldArray[i];
bitSet->set(pvField->getFieldOffset());
}
}
size_t next = bitSet->nextSetBit(nextSet+1);
if(next==string::npos) return;
updateMasterCheckBitSet(copyPVStructure,bitSet,next);
}
CopyNodePtr PVCopy::getCopyNode(std::size_t fieldOffset)
{
if(fieldOffset==0) return headNode;
CopyNodePtr node = headNode;
while(true) {
size_t soff = node->structureOffset;
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) return node;
if(!node->isStructure) return node;
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
bool okToContinue = false;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
size_t soff = node->structureOffset;
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
okToContinue = true;
break;
}
}
if(okToContinue) continue;
}
throw std::logic_error("PVCopy::getCopyNode fieldOffset not valid");
}
void PVCopy::updateMaster( void PVCopy::updateMaster(
PVStructurePtr const &copyPVStructure, PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet) BitSetPtr const &bitSet)
{ {
if(bitSet->get(0)) { updateMasterCheckBitSet(copyPVStructure,bitSet,0);
for(size_t i=0; i< copyPVStructure->getNumberFields(); ++i) { size_t nextSet =0;
bitSet->set(i,true); while(true) {
nextSet = bitSet->nextSetBit(nextSet);
if(nextSet==string::npos) return;
PVFieldPtr pvCopy = copyPVStructure->getSubField(nextSet);
PVFieldPtr pvMaster = headNode->masterPVField;
if(pvMaster->getField()->getType()==epics::pvData::structure) {
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvMaster);
pvMaster = pv->getSubField(pvCopy->getFullName());
} }
updateMasterField(getCopyNode(nextSet),pvCopy,pvMaster,bitSet);
bitSet->clear(nextSet);
} }
updateMaster(copyPVStructure,headNode,bitSet);
} }
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset) PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
{ {
if(fieldOffset==0) return headNode->options; if(fieldOffset==0) return headNode->options;
@ -248,7 +322,7 @@ PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
} }
} }
if(okToContinue) continue; if(okToContinue) continue;
throw std::logic_error("PVCopy logic error: fieldOffset not valid"); throw std::logic_error("PVCopy::getOptions logic error: fieldOffset not valid");
} }
} }
@ -349,36 +423,6 @@ void PVCopy::updateCopyFromBitSet(
updateCopyFromBitSet(pvCopyFields[i],(*structureNode->nodes)[i],bitSet); updateCopyFromBitSet(pvCopyFields[i],(*structureNode->nodes)[i],bitSet);
} }
} }
void PVCopy::updateMaster(
PVFieldPtr const & pvCopy,
CopyNodePtr const & node,
BitSetPtr const & bitSet)
{
bool result = false;
bool update = bitSet->get(pvCopy->getFieldOffset());
if(update) {
for(size_t i=0; i< node->pvFilters.size(); ++i) {
PVFilterPtr pvFilter = node->pvFilters[i];
if(pvFilter->filter(pvCopy,bitSet,false)) result = true;
}
}
if(!node->isStructure) {
if(result) return;
PVFieldPtr pvMaster = node->masterPVField;
pvMaster->copy(*pvCopy);
return;
}
CopyStructureNodePtr structureNode = static_pointer_cast<CopyStructureNode>(node);
size_t offset = structureNode->structureOffset;
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return;
if(offset>=pvCopy->getNextFieldOffset()) return;
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
for(size_t i=0; i<pvCopyFields.size(); ++i) {
updateMaster(pvCopyFields[i],(*structureNode->nodes)[i],bitSet);
}
}
PVCopy::PVCopy( PVCopy::PVCopy(
PVStructurePtr const &pvMaster) PVStructurePtr const &pvMaster)
@ -493,7 +537,7 @@ CopyNodePtr PVCopy::createStructureNodes(
requestPVStructure->getSubField<PVStructure>("_options"); requestPVStructure->getSubField<PVStructure>("_options");
PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName); PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName);
if(!pvMasterField) { if(!pvMasterField) {
throw std::logic_error("PVCopy logic error: did not find field in master"); throw std::logic_error("PVCopy::createStructureNodes did not find field in master");
} }
size_t numberRequest = requestPVStructure->getPVFields().size(); size_t numberRequest = requestPVStructure->getPVFields().size();
bool haveOptions = false; bool haveOptions = false;