aboutsummaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2004-01-18 09:01:45 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2004-01-18 09:01:45 +0000
commitdab42916caf4aa7950c01f5d3c298ea274d466d1 (patch)
tree28db6924b1f974ac99a8d5a67fecae8a8cbc325a /hash.c
parentbe7822ae1c0d3dd37cb371ec030defef0cb739ba (diff)
downloadlcd4linux-dab42916caf4aa7950c01f5d3c298ea274d466d1.tar.gz
[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
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c139
1 files changed, 118 insertions, 21 deletions
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; i<FILTER_SLOTS; i++) {
+ if (Item->Slot[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;i<Hash->nItems; 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