How to sync a MibTable with an STL::vector?

Martin Janzen janzen____pixelmetrix.com
Mon Apr 21 11:29:15 CEST 2003


 > [long discussion about how/when tables are updated]
 >
> Still, it would be great to have more demonstration
> code to get an impression about how others have come to a solution.


Well, as a quick optimization the first thing I do is to skip duplicate 
requests.  Also, when processing each subrequest I check for the same 
index OID as on the last subrequest, since (depending on your NMS or 
other clients) a GetNext or GetBulk request is likely to ask for each 
column of the same table row.  You could imagine more sophisticated 
schemes, but I've found that this does an adequate job of keeping my 
processing load down to a reasonable level.

Some (slightly edited) code fragments might help to explain; use your 
imagination to fill in the methods, member variables, etc. that I've 
omitted:


void
MyTableImpl::update(Agentpp::Request* pReq)
{
     if ((pReq == mpCurrentRequest) &&
         (pReq->get_transaction_id() == mLastTransactionID))
         return;

     mpCurrentRequest = pReq;
     mLastTransactionID = (pReq == 0) ? 0 : pReq->get_transaction_id();

     // Since this is a new request, throw away all rows generated in
     // response to the previous request.
     mMyTable.clear();
     mPreviousIndexOID.clear();

     for (u_int sub = 0; sub < pReq->subrequests(); sub++)
     {
         // Extract the index value for this subrequest.
         Agentpp::Oidx subrequestOID(pReq->get_oid(sub));
         Agentpp::Oidx indexOID(mMyTable.index(subrequestOID));

         switch (pReq->get_type())
         {
         case sNMP_PDU_GET:
         case sNMP_PDU_SET:
             // Check that the requested OID is in this table.
             if (mMyTable.base(subrequestOID) != *mMyTable.key())
                 break;

             // See whether we have a valid index OID.
             if (!mMyTable.is_index_valid(indexOID))
                 break;

             // Create a row for this index OID, if found.
             [...]
             break;

         case sNMP_PDU_GETNEXT:
         case sNMP_PDU_GETBULK:
             // If this table's update() method was called in response
             // to a GETNEXT request on the last object in a previous
             // table, try to load the first row of the table, so that
             // Agent++ knows it needs to descend into this subtree.
             if (mMyTable.base(subrequestOID) < *mMyTable.key())
             {
                 // As an optimization, see whether we just filled in
                 // the row corresponding to this index OID.
                 if ((mPreviousIndexOID.len() == 0) ||
                     (indexOID != mPreviousIndexOID))
                 {
                     mPreviousIndexOID = indexOID;
                     // Load the first row of the table.
                     [...]
                 }
             }

             // Now the overridden MibTable::find_succ() method will call
             // the method which loads each row as Agent++ traverses the
             // table's subtree.
             break;

         default:
             [...]
         }
     }
}


Agentpp::Oidx
MyTableImpl::find_succ(const Agentpp::Oidx& oid, Agentpp::Request* pReq)
{
     onFindSucc(oid, pReq);
     return MibTable::find_succ(oid, pReq);
}

bool
MyTableImpl::onFindSucc(const Agentpp::Oidx& oid, Agentpp::Request*)
{
     // As an optimization, see whether we just filled in the row
     // corresponding to this index OID.  (This frequently will be
     // the case when processing GETBULK requests.)
     Agentpp::Oidx indexOID(mMyTable.index(oid));
     if ((mPreviousIndexOID.len() > 0) &&
         (indexOID == mPreviousIndexOID))
         return false;
     mPreviousIndexOID = indexOID;

     // Now load the appropriate row for the new index.
     [...]
}


HTH...

-- 
Martin Janzen
janzen at pixelmetrix dot com




More information about the AGENTPP mailing list