Why handle the first case completely separate from the other two cases? If we have no filters then dbChannelRunPre/PostChain should be a no-op. Furthermore, shouldn't the actions done in the last case (the final "else" branch) also be done in the first case i.e. when we have filters?
The second case ("else if") is clearly an optimization. The code tells me that this optimization is not valid when there are filters, but it is unclear (to me at least) why this is the case.
I think this code should be re-written from scratch, after careful consideration of the expected behavior and possible optimization/caching.
I have an additional comment/question about the code in dbDbLink.c, function dbDbGetValue, particularly the following case distinction:
/* If filters are involved in a read, create field log and run filters */ &chan-> filters) ) {
db_field_ log *pfl;
if (ellCount(
/* filters/ arr.c for details. Elements( chan) <= 0) /* empty array request */ read_log( chan); Chain(chan, pfl); tChain( chan, pfl);
db_delete_ field_log( pfl); >lastGetdbrType == dbrType) { >getCvt( dbChannelField( chan), pbuffer, paddr); ieldType( chan);
* For the moment, empty arrays are not supported by EPICS.
* See the remark in src/std/
*/
if (dbChannelFinal
return S_db_badField;
pfl = db_create_
if (!pfl)
return S_db_noMemory;
pfl = dbChannelRunPre
pfl = dbChannelRunPos
status = dbChannelGet(chan, dbrType, pbuffer, NULL, pnRequest, pfl);
if (status)
return status;
if (pnRequest && *pnRequest <= 0) /* empty array result */
return S_db_badField;
} else if (ppv_link->getCvt && ppv_link-
status = ppv_link-
} else {
unsigned short dbfType = dbChannelFinalF
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
return S_db_badDbrtype;
if (dbChannelFinal Elements( chan) == 1 && (!pnRequest || *pnRequest == 1) l(chan) != SPC_DBADDR l(chan) != SPC_ATTRIBUTE) {
ppv_ link->getCvt = dbFastGetConver tRoutine[ dbfType] [dbrType] ; >getCvt( dbChannelField( chan), pbuffer, paddr);
ppv_ link->getCvt = NULL;
ppv_link- >lastGetdbrType = dbrType;
&& dbChannelSpecia
&& dbChannelSpecia
status = ppv_link-
} else {
status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL);
}
}
Why handle the first case completely separate from the other two cases? If we have no filters then dbChannelRunPre /PostChain should be a no-op. Furthermore, shouldn't the actions done in the last case (the final "else" branch) also be done in the first case i.e. when we have filters?
The second case ("else if") is clearly an optimization. The code tells me that this optimization is not valid when there are filters, but it is unclear (to me at least) why this is the case.
I think this code should be re-written from scratch, after careful consideration of the expected behavior and possible optimization/ caching.