Changeset 0d57541 for lib/format_erf.c


Ignore:
Timestamp:
02/28/06 13:44:36 (16 years ago)
Author:
Perry Lorier <perry@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
5b66921
Parents:
c26ca86
Message:

Add preliminary seek support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_erf.c

    r5fb2251 r0d57541  
    9595        } input;
    9696
     97        struct {
     98                enum { INDEX_UNKNOWN=0, INDEX_NONE, INDEX_EXISTS } exists;
     99                LIBTRACE_FILE index;
     100                off_t index_len;
     101        } seek;
     102
    97103#if HAVE_DAG
    98104        struct {
     
    142148} libtrace_packet_status_t;
    143149
     150typedef struct erf_index_t {
     151        uint64_t timestamp;
     152        uint64_t offset;
     153} erf_index_t;
    144154
    145155#ifdef HAVE_DAG
     
    205215}
    206216
    207 static int erf_start_input(struct libtrace_t *libtrace)
     217static int erf_start_input(libtrace_t *libtrace)
    208218{
    209219        INPUT.file = trace_open_file(libtrace);
     
    213223
    214224        return 0; /* success */
     225}
     226
     227/* Binary search through the index to find the closest point before
     228 * the packet.  Consider in future having a btree index perhaps?
     229 */
     230static int erf_fast_seek_start(libtrace_t *libtrace,uint64_t erfts)
     231{
     232        size_t max_off = DATA(libtrace)->seek.index_len/sizeof(erf_index_t);
     233        size_t min_off = 0;
     234        off_t current;
     235        erf_index_t record;
     236        do {
     237                current=(max_off+min_off)>>2;
     238
     239                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
     240                                current*sizeof(record),
     241                                SEEK_SET);
     242                LIBTRACE_READ(DATA(libtrace)->seek.index,
     243                                &record,sizeof(record));
     244                if (record.timestamp < erfts) {
     245                        min_off=current;
     246                }
     247                if (record.timestamp > erfts) {
     248                        max_off=current;
     249                }
     250                if (record.timestamp == erfts)
     251                        break;
     252        } while(min_off<max_off);
     253
     254        /* If we've passed it, seek backwards.  This loop shouldn't
     255         * execute more than twice.
     256         */
     257        do {
     258                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
     259                                current*sizeof(record),SEEK_SET);
     260                LIBTRACE_READ(DATA(libtrace)->seek.index,
     261                                &record,sizeof(record));
     262                current--;
     263        } while(record.timestamp>erfts);
     264
     265        /* We've found our location in the trace, now use it. */
     266        LIBTRACE_SEEK(INPUT.file,record.offset,SEEK_SET);
     267
     268        return 0; /* success */
     269}
     270
     271/* There is no index.  Seek through the entire trace from the start, nice
     272 * and slowly.
     273 */
     274static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts)
     275{
     276        if (INPUT.file) {
     277                LIBTRACE_CLOSE(INPUT.file);
     278        }
     279        INPUT.file = trace_open_file(libtrace);
     280        if (!INPUT.file)
     281                return -1;
     282        return 0;
     283}
     284
     285static int erf_seek_erf(libtrace_t *libtrace,uint64_t erfts)
     286{
     287        libtrace_packet_t *packet;
     288        off_t off = 0;
     289
     290        if (DATA(libtrace)->seek.exists==INDEX_UNKNOWN) {
     291                char buffer[PATH_MAX];
     292                snprintf(buffer,sizeof(buffer),"%s.idx",libtrace->uridata);
     293                DATA(libtrace)->seek.index=LIBTRACE_OPEN(buffer,"r");
     294                if (DATA(libtrace)->seek.index) {
     295                        DATA(libtrace)->seek.exists=INDEX_EXISTS;
     296                }
     297                else {
     298                        DATA(libtrace)->seek.exists=INDEX_NONE;
     299                }
     300        }
     301
     302        /* If theres an index, use it to find the nearest packet that isn't
     303         * after the time we're looking for.  If there is no index we need
     304         * to seek slowly through the trace from the beginning.  Sigh.
     305         */
     306        switch(DATA(libtrace)->seek.exists) {
     307                case INDEX_EXISTS:
     308                        erf_fast_seek_start(libtrace,erfts);
     309                        break;
     310                case INDEX_NONE:
     311                        erf_slow_seek_start(libtrace,erfts);
     312                        break;
     313                case INDEX_UNKNOWN:
     314                        assert(0);
     315                        break;
     316        }
     317
     318        /* Now seek forward looking for the correct timestamp */
     319        packet=trace_create_packet();
     320        do {
     321                trace_read_packet(libtrace,packet);
     322                if (trace_get_erf_timestamp(packet)==erfts)
     323                        break;
     324                off=LIBTRACE_TELL(INPUT.file);
     325        } while(trace_get_erf_timestamp(packet)<erfts);
     326
     327        LIBTRACE_SEEK(INPUT.file,off,SEEK_SET);
     328
     329        return 0;
    215330}
    216331
     
    350465
    351466#if HAVE_DAG
     467/* FIXME: dag_read_packet shouldn't update the pointers, dag_fin_packet
     468 * should do that.
     469 */
    352470static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
    353471        int numbytes;
     
    791909        NULL,                           /* get_timeval */
    792910        NULL,                           /* get_seconds */
    793         NULL,                           /* seek_erf */
     911        erf_seek_erf,                   /* seek_erf */
    794912        NULL,                           /* seek_timeval */
    795913        NULL,                           /* seek_seconds */
Note: See TracChangeset for help on using the changeset viewer.