From dab42916caf4aa7950c01f5d3c298ea274d466d1 Mon Sep 17 00:00:00 2001 From: reinelt Date: Sun, 18 Jan 2004 09:01:45 +0000 Subject: [lcd4linux @ 2004-01-18 09:01:45 by reinelt] /proc/stat parsing finished git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@319 3ae390bd-cb1e-0410-b409-cd5a39f66f1f --- hash.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 118 insertions(+), 21 deletions(-) (limited to 'hash.c') diff --git a/hash.c b/hash.c index 56a6330..235a9bc 100644 --- a/hash.c +++ b/hash.c @@ -1,4 +1,4 @@ -/* $Id: hash.c,v 1.4 2004/01/18 06:54:08 reinelt Exp $ +/* $Id: hash.c,v 1.5 2004/01/18 09:01:45 reinelt Exp $ * * hashes (associative arrays) * @@ -23,6 +23,9 @@ * * * $Log: hash.c,v $ + * Revision 1.5 2004/01/18 09:01:45 reinelt + * /proc/stat parsing finished + * * Revision 1.4 2004/01/18 06:54:08 reinelt * bug in expr.c fixed (thanks to Xavier) * some progress with /proc/stat parsing @@ -60,6 +63,9 @@ #include "hash.h" +#define FILTER_SLOTS 64 + + // bsearch compare function for hash entries static int hash_lookup_f (const void *a, const void *b) { @@ -80,21 +86,21 @@ static int hash_sort_f (const void *a, const void *b) } - -// insert a key/val pair into the hash table +// search an entry in the hash table: // If the table is flagged "sorted", the entry is looked // up using the bsearch function. If the table is -// unsorted, it will be searched in a linear way if the entry -// does already exist. -// If the entry does already exist, it will be overwritten, -// and the table stays sorted (if it has been before). -// Otherwise, the entry is appended at the end, and -// the table will be flagged 'unsorted' afterwards +// unsorted, it will be searched in a linear way -void hash_set (HASH *Hash, char *key, char *val) +static HASH_ITEM* hash_lookup (HASH *Hash, char *key, int sortit) { HASH_ITEM *Item=NULL; + // maybe sort the array + if (sortit && !Hash->sorted) { + qsort(Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_sort_f); + Hash->sorted=1; + } + // lookup using bsearch if (Hash->sorted) { Item=bsearch(key, Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_lookup_f); @@ -110,37 +116,127 @@ void hash_set (HASH *Hash, char *key, char *val) } } } + + return Item; + +} + + +// insert a key/val pair into the hash table +// If the entry does already exist, it will be overwritten, +// and the table stays sorted (if it has been before). +// Otherwise, the entry is appended at the end, and +// the table will be flagged 'unsorted' afterwards + +static HASH_ITEM* hash_set_string (HASH *Hash, char *key, char *val) +{ + HASH_ITEM *Item; + + Item=hash_lookup (Hash, key, 0); // entry already exists? if (Item!=NULL) { if (Item->val) free (Item->val); - Item->val=strdup(val); - return; + Item->val = strdup(val); + return Item; } // add entry Hash->sorted=0; Hash->nItems++; Hash->Items=realloc(Hash->Items,Hash->nItems*sizeof(HASH_ITEM)); - Hash->Items[Hash->nItems-1].key=strdup(key); - Hash->Items[Hash->nItems-1].val=strdup(val); + + Item=&(Hash->Items[Hash->nItems-1]); + + Item->key = strdup(key); + Item->val = strdup(val); + Item->Slot = NULL; + + return Item; } -char *hash_get (HASH *Hash, char *key) +// insert a string into the hash table +void hash_set (HASH *Hash, char *key, char *val) +{ + hash_set_string (Hash, key, val); +} + + +// insert a string into the hash table +// convert it into a number, and store it in the +// filter table, too +void hash_set_filter (HASH *Hash, char *key, char *val) { + double number=atof(val); HASH_ITEM *Item; - if (!Hash->sorted) { - qsort(Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_sort_f); - Hash->sorted=1; + Item=hash_set_string (Hash, key, val); + + // allocate filter table + if (Item->Slot==NULL) { + Item->Slot = malloc(FILTER_SLOTS*sizeof(HASH_SLOT)); + memset(Item->Slot, 0, FILTER_SLOTS*sizeof(HASH_SLOT)); } - Item=bsearch(key, Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_lookup_f); + // shift filter table + memmove (Item->Slot+1, Item->Slot, (FILTER_SLOTS-1)*sizeof(HASH_SLOT)); + + // set first entry + gettimeofday(&(Item->Slot[0].time), NULL); + Item->Slot[0].val=number; +} + +// get a string from the hash table +char *hash_get (HASH *Hash, char *key) +{ + HASH_ITEM *Item=hash_lookup(Hash, key, 1); return Item?Item->val:NULL; } +// get a delta value from the filter table +double hash_get_filter (HASH *Hash, char *key, int delay) +{ + HASH_ITEM *Item; + struct timeval now, end; + int i; + double dv, dt; + + // lookup item + Item=hash_lookup(Hash, key, 1); + if (Item==NULL) return 0.0; + if (Item->Slot==NULL) return 0.0; + + // prepare timing values + now=Item->Slot[0].time; + end.tv_sec = now.tv_sec; + end.tv_usec = now.tv_usec-1000*delay; + if (end.tv_usec<0) { + end.tv_sec--; + end.tv_usec += 1000000; + } + + // search filter slot + for (i=1; iSlot[i].time.tv_sec==0) break; + if (timercmp(&Item->Slot[i].time, &end, <)) break; + } + + // empty slot => use the one before + if (Item->Slot[i].time.tv_sec==0) i--; + + // not enough slots available... + if (i==0) return 0.0; + + // delta value, delta time + dv = Item->Slot[0].val - Item->Slot[i].val; + dt = (now.tv_sec - Item->Slot[i].time.tv_sec) + (now.tv_usec - Item->Slot[i].time.tv_usec)/1000000.0; + + if (dt > 0.0 && dv >= 0.0) return dv/dt; + return 0.0; +} + void hash_destroy (HASH *Hash) { @@ -150,8 +246,9 @@ void hash_destroy (HASH *Hash) // free all entries for (i=0;inItems; i++) { - if (Hash->Items[i].key) free (Hash->Items[i].key); - if (Hash->Items[i].val) free (Hash->Items[i].val); + if (Hash->Items[i].key) free (Hash->Items[i].key); + if (Hash->Items[i].val) free (Hash->Items[i].val); + if (Hash->Items[i].Slot) free (Hash->Items[i].Slot); } // free hash table -- cgit v1.2.3