Check out the new USENIX Web site. Previous Contents

A   The Usage signature

#define NUMBINS 16
int bucketToSec[NUMBINS]= { ... };
char secToBucket(int v) { ... };

record uField(ufSig, ufApprox) {
  int <=> char;
  ufSig(b) = bucketToSec[b];
  ufApprox(s) = secToBucket(s);
}

record uLine(uSig, uApprox) {
  uField in;
  uField out;
  uField outTF;
  uField outIntl;
}
  
map uMap {
  key line_t; 
  value uApprox; 
  default {0,0,0};
}
 


#define LAMBDA .15
#define blend(new, old) (((new) * LAMBDA) + ((old)*(1 - LAMBDA)))



#include calls.h   
int getvalidcall(PCallRec_t *pc, 
                   callRec_t *c){...}
stream callStream
  {getvalidcall: pCallRec_t => callRec_t}

char noIntlOrIncomplete(callRec_t *c) {
  return !(c->isIncomplete) &&
         !(c->isIntl);
}

char noIncomplete(callRec_t *c) {
  return !(c->isIncomplete);
}

phase out(callStream calls, uMap usage) {
  iterate 
    over calls 
    sortedby origin 
    filteredby noIncomplete
    withevents line, call;

  event line(line_t pn) {
    uSig cumSec;       

    begin {
      cumSec.outTF = 0;
      cumSec.outIntl = 0;
      cumSec.out = 0;
    }

    end {
      uSig us = usage<:pn:>$uSig;
      us.outTF = blend(cumSec.outTF, us.outTF);
      us.outIntl = blend(cumSec.outIntl, us.outIntl);
      us.out = blend(cumSec.out, us.out);
      usage<:pn:> = us$uApprox;
    }
 }

  event call(callRec_t c) {
    uSig line::cumSec;

    if (c.isTollFree)
      cumSec.outTF += c.duration; 
    else if (c.isIntl)
      cumSec.outIntl += c.duration;
    else
      cumSec.out += c.duration;
  } /* end call event */
}/* end out phase */


phase in(callStream calls, uMap usage){ 
  iterate 
    over calls 
    sortedby dialed 
    filteredby noIntlOrIncomplete
    withevents line, call;

  event line(line_t pn) {
    uSig cumSec;       

    begin {
      cumSec.in = 0;
    }

    end {
      uSig us = usage<:pn:>$uSig;
      us.in = blend(cumSec.in, us.in);
      usage<:pn:> = us$uApprox;
    }
 }

  event call(callRec_t c) {
    uSig line::cumSec;

    cumSec.in += c.duration;
  } /* end call event */
}/* end in phase */




void sig_main(       const callStream calls <c:>),
              exists const uMap y_usage <u:>,
              new          uMap usage <U:>) {

   usage :=: y_usage;
   out(calls, usage);
   in(calls, usage);    
}

Previous Contents