Howdy, I am curious if there is a way to build an associative array using dynamic keys? I would like to do something like this: [ .... ] { /* Grab the Remote IP address from the conn_rec structure */ remote_ip = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) copyin(self->rraddr * sizeof(uintptr_t)); /* Grab the request from the client */ request = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) copyin(self->rraddr + 1 * sizeof(uintptr_t)); requests[remote_ip,request]++; } profile:::tick-10sec { /* print all of the requests */ printf(); /* Nuke the requests associative array */ requests = 0; } I read through the DTrace users guide in an attempt to locate an example, but the arrays and pointers/Variables chapter assumes you know the name of the keys (I didn''t see a reference to a key name that was generated at execution time). Is this possible? Thanks for any insight, - Ryan -- UNIX Administrator http://daemons.net/~matty
Philip Beevers
2005-Nov-17 18:01 UTC
[dtrace-discuss] Associative arrays with arbitrary keys?
Hi Ryan,> Is this possible?I think the effect you''re looking for should be achieved by using an aggregation rather than an array. So you''d actually do something like: @requests[remote_ip,request] = count(); ... and then: profile:::tick-10sec { /* print all of the requests */ printa(@requests); /* Nuke the requests aggregation */ trunc(@requests); } -- Philip Beevers Fidessa Infrastructure Development mailto:philip.beevers at fidessa.com phone: +44 1483 206571> -----Original Message----- > From: dtrace-discuss-bounces at opensolaris.org > [mailto:dtrace-discuss-bounces at opensolaris.org]On Behalf Of Matty > Sent: 17 November 2005 17:50 > To: Solaris DTRACE Discussions > Subject: [dtrace-discuss] Associative arrays with arbitrary keys? > > > > Howdy, > > I am curious if there is a way to build an associative array using > dynamic keys? I would like to do something like this: > > [ .... ] > { > /* Grab the Remote IP address from the conn_rec structure */ > remote_ip = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) > copyin(self->rraddr * sizeof(uintptr_t)); > > /* Grab the request from the client */ > request = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) > copyin(self->rraddr + 1 * sizeof(uintptr_t)); > > requests[remote_ip,request]++; > } > > profile:::tick-10sec > { > /* print all of the requests */ > printf(); > > /* Nuke the requests associative array */ > requests = 0; > } > > I read through the DTrace users guide in an attempt to locate an > example, but the arrays and pointers/Variables chapter > assumes you know > the name of the keys (I didn''t see a reference to a key name that was > generated at execution time). Is this possible? > > Thanks for any insight, > - Ryan > -- > UNIX Administrator > http://daemons.net/~matty > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org >****************************************************************** This message is intended only for the stated addressee(s) and may be confidential. Access to this email by anyone else is unauthorised. Any opinions expressed in this email do not necessarily reflect the opinions of royalblue. Any unauthorised disclosure, use or dissemination, either whole or in part is prohibited. If you are not the intended recipient of this message, please notify the sender immediately. ******************************************************************
Bryan Cantrill
2005-Nov-17 18:13 UTC
[dtrace-discuss] Associative arrays with arbitrary keys?
On Thu, Nov 17, 2005 at 12:49:49PM -0500, Matty wrote:> > Howdy, > > I am curious if there is a way to build an associative array using > dynamic keys? I would like to do something like this:It''s certainly possible, but you should be using aggregations here; see below.> [ .... ] > { > /* Grab the Remote IP address from the conn_rec structure */ > remote_ip = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) > copyin(self->rraddr * sizeof(uintptr_t)); > > /* Grab the request from the client */ > request = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) > copyin(self->rraddr + 1 * sizeof(uintptr_t)); > > requests[remote_ip,request]++; > } > > profile:::tick-10sec > { > /* print all of the requests */ > printf(); > > /* Nuke the requests associative array */ > requests = 0; > }You should be aggregating on remote_ip and request, and then using printa() and clear() or trunc() in the tick probe. Also, not that you should make these clause-local to preven two threads from interfering with one another. So the modified version looks like this: { /* Grab the Remote IP address from the conn_rec structure */ this->remote_ip = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) copyin(self->rraddr * sizeof(uintptr_t)); /* Grab the request from the client */ this->request = copyinstr(*(uintptr_t *)copyin(*(uintptr_t *) copyin(self->rraddr + 1 * sizeof(uintptr_t)); @requests[this->remote_ip, this->request] = count(); } profile:::tick-10sec { /* print all of the requests */ printa(@requests); /* * (The above could be pretty-printed by setting the quiet option, * and changing the printa to "printa("%35s %35s %@d\n", @requests)" * or similar. */ /* Clear the requests aggregation */ clear(@requests); } - Bryan -------------------------------------------------------------------------- Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc
Bryan Cantrill
2005-Nov-17 18:16 UTC
[dtrace-discuss] Associative arrays with arbitrary keys?
On Thu, Nov 17, 2005 at 06:01:04PM -0000, Philip Beevers wrote:> Hi Ryan, > > > Is this possible? > > I think the effect you''re looking for should be achieved by using an > aggregation rather than an array. So you''d actually do something like: > > @requests[remote_ip,request] = count(); > > ... and then: > > profile:::tick-10sec > { > /* print all of the requests */ > printa(@requests); > > /* Nuke the requests aggregation */ > trunc(@requests); > }Damn; it''s not enough to beat Jonathan to the punch -- now I have to beat Phil, too! ;) Note that the difference between trunc() and clear() is that trunc() will also toss the metadata. So if you see an IP/request pair in one ten-second period but not in a subsequent period, with trunc() you won''t see the pair in the subsequent periods; with clear() you''ll see the pair but the value will be "0". For stat-like tools, I find it a bit easier to use clear(), especially if the data is changing around a lot -- but trunc() may be more appropriate. See the doc for details, at any rate... - Bryan -------------------------------------------------------------------------- Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc