Contiki 2.6

timetable-aggregate.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Swedish Institute of Computer Science.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  * $Id: timetable-aggregate.c,v 1.2 2008/03/13 14:27:34 fros4943 Exp $
00032  */
00033 
00034 /**
00035  * \file
00036  *         A brief description of what this file is.
00037  * \author
00038  *         Adam Dunkels <adam@sics.se>
00039  */
00040 
00041 #include "sys/timetable-aggregate.h"
00042 
00043 #define XXX_HACK_MAX_CATEGORIES 32
00044 
00045 #include <stdio.h>
00046 
00047 /*---------------------------------------------------------------------------*/
00048 /*
00049  *
00050  * Find an aggregation category in the list of aggregates. If the
00051  * category could not be found, the function returns a pointer to an
00052  * empty entry. If the list is full, the function returns NULL.
00053  *
00054  */
00055 static struct timetable_aggregate_entry *
00056 find_aggregate_category(struct timetable_aggregate *a,
00057                         const uint16_t cat)
00058 {
00059   int i;
00060   uint16_t acat;
00061 
00062   for(i = 0; i < a->ptr; ++i) {
00063     acat = (a->entries[i].id[0] << 8) + a->entries[i].id[1];
00064     if(acat == cat) {
00065 
00066       return &a->entries[i];
00067     }
00068   }
00069 
00070   if(i == a->size) {
00071     return NULL;
00072   }
00073   
00074   a->entries[a->ptr].id = NULL;
00075   return &a->entries[a->ptr++];
00076 }
00077 /*---------------------------------------------------------------------------*/
00078 /*
00079  *
00080  * Find a specific aggregate ID in the list of aggregates.
00081  *
00082  */
00083 static struct timetable_aggregate_entry *
00084 find_aggregate(struct timetable_aggregate *a,
00085                const char *id)
00086 {
00087   int i;
00088   for(i = 0; i < a->ptr; ++i) {
00089     if(a->entries[i].id == id) {
00090       return &a->entries[i];
00091     }
00092   }
00093   if(i == a->size) {
00094     return NULL;
00095   }
00096   a->entries[a->ptr].id = NULL;
00097   return &a->entries[a->ptr++];
00098 }
00099 /*---------------------------------------------------------------------------*/
00100 void
00101 timetable_aggregate_print_detailed(struct timetable_aggregate *a)
00102 {
00103   int i;
00104   /*  printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/
00105   for(i = 0; i < a->ptr; ++i) {
00106     printf("-- %s: %lu / %u = %lu\n", a->entries[i].id,
00107            a->entries[i].time,
00108            a->entries[i].episodes,
00109            a->entries[i].time / a->entries[i].episodes);
00110   }
00111   
00112   printf("Memory for entries: %d * %d = %d\n",
00113          (int)sizeof(struct timetable_aggregate), a->ptr,
00114          (int)sizeof(struct timetable_aggregate) * a->ptr);
00115 }
00116 /*---------------------------------------------------------------------------*/
00117 void
00118 timetable_aggregate_reset(struct timetable_aggregate *a)
00119 {
00120   int i;
00121   for(i = 0; i < a->ptr; ++i) {
00122     a->entries[i].time = 0;
00123     a->entries[i].episodes = 0;
00124   }
00125 }
00126 /*---------------------------------------------------------------------------*/
00127 void
00128 timetable_aggregate_print_categories(struct timetable_aggregate *a)
00129 {
00130   int i;
00131 
00132   /*  printf("timetable_aggregate_print_categories: a ptr %d\n", a->ptr);*/
00133   for(i = 0; i < a->ptr; ++i) {
00134     printf("-- %c%c: %lu / %u = %lu\n",
00135            a->entries[i].id[0], a->entries[i].id[1],
00136            a->entries[i].time,
00137            a->entries[i].episodes,
00138            a->entries[i].time / a->entries[i].episodes);
00139   }
00140 
00141   printf("Memory for entries: %d * %d = %d\n",
00142          (int)sizeof(struct timetable_aggregate), a->ptr,
00143          (int)sizeof(struct timetable_aggregate) * a->ptr);
00144 }
00145 /*---------------------------------------------------------------------------*/
00146 void
00147 timetable_aggregate_compute_detailed(struct timetable_aggregate *a,
00148                                      struct timetable *timetable)
00149 {
00150   unsigned int i;
00151   rtimer_clock_t t;
00152   
00153   t = timetable->timestamps[0].time;
00154   
00155   for(i = 1; i < *timetable->ptr; ++i) {
00156     struct timetable_aggregate_entry *entry;
00157     entry = find_aggregate(a, timetable->timestamps[i - 1].id);
00158     if(entry == NULL) {
00159       /* The list is full, skip this entry */
00160       /*      printf("detailed_timetable_aggregate_compute: list full\n");*/
00161     } else if(entry->id == NULL) {
00162       /* The id was found in the list, so we add it. */
00163       entry->id = timetable->timestamps[i - 1].id;
00164       entry->time = (unsigned long)(timetable->timestamps[i].time - t -
00165                                     timetable_timestamp_time);
00166       entry->episodes = 1;
00167       /*      printf("New entry %s %lu\n", entry->id, entry->time);*/
00168     } else {
00169       entry->time += (unsigned long)(timetable->timestamps[i].time - t -
00170                                      timetable_timestamp_time);
00171                                      entry->episodes++;
00172     }
00173     t = timetable->timestamps[i].time;
00174     /*    printf("a ptr %d\n", a->ptr);*/
00175   }
00176 }
00177 /*---------------------------------------------------------------------------*/
00178 void
00179 timetable_aggregate_compute_categories(struct timetable_aggregate *a,
00180                                        struct timetable *timetable)
00181 {
00182   unsigned int i;
00183   int j;
00184   rtimer_clock_t t;
00185   uint16_t categories[XXX_HACK_MAX_CATEGORIES];
00186   int categories_ptr = 0;
00187   
00188   t = timetable->timestamps[0].time;
00189   
00190   for(i = 1; i < *timetable->ptr; ++i) {
00191     struct timetable_aggregate_entry *entry;
00192     uint16_t cat;
00193 
00194     /*    printf("category_timetable_aggregate_compute %s %d\n",
00195           timetable->timestamps[i - 1].id, i);*/
00196     cat = (timetable->timestamps[i - 1].id[0] << 8) +
00197       (timetable->timestamps[i - 1].id[1] & 0xff);
00198     entry = find_aggregate_category(a, cat);
00199     if(entry == NULL) {
00200       /* The list is full, skip this entry */
00201       /*      printf("category_timetable_aggregate_compute: list full\n");*/
00202     } else if(entry->id == NULL) {
00203       /* The category was not found in the list, so we add it. */
00204       entry->id = timetable->timestamps[i - 1].id;
00205       entry->time = (unsigned long)(timetable->timestamps[i].time - t -
00206                                     timetable_timestamp_time);
00207       entry->episodes = 1;
00208       /*      printf("New category %c%c time %lu\n",
00209              timetable->timestamps[i - 1].id[0],
00210              timetable->timestamps[i - 1].id[1], entry->time);*/
00211     } else {
00212       
00213       entry->time += (unsigned long)(timetable->timestamps[i].time - t -
00214                                      timetable_timestamp_time);
00215       /*      printf("Adding time to %c%c time %lu\n",
00216              timetable->timestamps[i - 1].id[0],
00217              timetable->timestamps[i - 1].id[1], entry->time);*/
00218 
00219       /* Make sure that we only update the episodes of each category
00220          once per run. We keep track of all updated categories in the
00221          "categories" array. If the category is already present in the
00222          array, we do not update it. Otherwise, we insert the category
00223          in the array and update the episodes counter of the
00224          category. */
00225       
00226       for(j = 0; j < categories_ptr; ++j) {
00227         if(categories[j] == cat) {
00228           break;
00229         }
00230       }
00231       if(j == categories_ptr) {
00232         categories[j] = cat;
00233         categories_ptr++;
00234         entry->episodes++;
00235       }
00236     }
00237     t = timetable->timestamps[i].time;
00238   }
00239 }
00240 /*---------------------------------------------------------------------------*/