implementing a large table over a database
Martin Janzen
janzen____pixelmetrix.com
Fri Nov 1 09:52:36 CET 2002
[Not sure this was sent earlier; sorry if you see it twice...]
Our resident external-tables expert, Alex Finogenov, wrote:
> [...]
> 2. I implemented GetBulk in terms of GetNext. You will have to override
> MibTable::find_succ(), which is called by during the processing of either
> method, if I remember correctly.
I've also found that this works pretty well. It's a lot easier than
trying to make the update() method anticipate the exact set of rows
that will be needed by a complex GETBULK request.
However, I notice that if I override find_succ(), my update() method
still has to check for the case in which a GETNEXT/GETBULK from a
previous table has run over into the current table. If this happens,
it must load the first row of the table, so that Agent++ knows there's
something there.
(The first row is sufficient: Once it knows that it must descend into
the current table, Agent++ will continue to call find_succ() as needed.)
In other words, here's a pseudocode version of what I'm doing now:
void
MyTable::update(Agentpp::Request* pReq)
{
// Don't do more work than necessary. (Note that it's good practice
// to check both the request address and the transaction ID, since
// the request address is at the whim of the implementations of
// Agent++ and of your new/delete operators.)
if ((pReq == mCurrentRequest) &&
(pReq->get_transaction_id() == mLastTransactionID)
return;
mCurrentRequest = 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. (I agree with Alex: stateless
// agents are the way to go!)
clear();
for (int sub = 0; sub < pReq->subrequests(); sub++)
{
Agentpp::Oidx subrequestOID = pReq->get_oid(sub);
switch (pReq->get_type())
{
case sNMP_PDU_GET:
// If the requested OID is in this table, create a row for
// the requested index value.
if (base(subrequestOID) == *key())
loadRow(index(subrequestOID));
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,
// load the first row of this table, so that Agent++ knows
// it needs to descend into this subtree.
if (base(subrequestOID) != *key())
loadNextRow(Oidx());
break;
[...]
}
}
}
Agentpp::Oidx
MyTable::find_succ(const Agentpp::Oidx& oid, Agentpp::Request* pReq)
{
// Load the row which follows the requested index value, then let
// the Agent++ tree traversal code find it as usual.
loadNextRow(index(oid));
return MibTable::find_succ(oid, pReq);
}
Comments/suggestions welcome, of course.
> 3. Get methods are peanuts comparing to the Set, especially in when
> implementing tables with AUGMENT clause, etc.
Oh, good. I can hardly wait...
--
Martin Janzen
janzen at pixelmetrix.com
--
Martin Janzen
janzen at pixelmetrix.com
More information about the AGENTPP
mailing list