rehash when table size changes
This commit is contained in:
		
							parent
							
								
									8bc0f0d245
								
							
						
					
					
						commit
						f2d6a8f3b1
					
				@ -1,7 +1,7 @@
 | 
			
		||||
#include "sigar.h"
 | 
			
		||||
#include "sigar_private.h"
 | 
			
		||||
#include "sigar_util.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
/*
 | 
			
		||||
 * hash table to cache values where key is a unique number
 | 
			
		||||
 * such as:
 | 
			
		||||
@ -30,13 +30,69 @@ sigar_cache_t *sigar_cache_new(int size)
 | 
			
		||||
    return table;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CACHE
 | 
			
		||||
/* see how well entries are distributed */
 | 
			
		||||
static void sigar_cache_dump(sigar_cache_t *table)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    sigar_cache_entry_t **entries = table->entries;
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<table->size; i++) {
 | 
			
		||||
        sigar_cache_entry_t *entry = *entries++;
 | 
			
		||||
 | 
			
		||||
        printf("|");
 | 
			
		||||
        while (entry) {
 | 
			
		||||
            printf("%lld", entry->id);
 | 
			
		||||
            if (entry->next) {
 | 
			
		||||
                printf(",");
 | 
			
		||||
            }
 | 
			
		||||
            entry = entry->next;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    printf("\n");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void sigar_cache_rehash(sigar_cache_t *table)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    unsigned int new_size = table->size * 2 + 1;
 | 
			
		||||
    sigar_cache_entry_t **entries = table->entries;
 | 
			
		||||
    sigar_cache_entry_t **new_entries =
 | 
			
		||||
        malloc(ENTRIES_SIZE(new_size));
 | 
			
		||||
 | 
			
		||||
    memset(new_entries, '\0', ENTRIES_SIZE(new_size));
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<table->size; i++) {
 | 
			
		||||
        sigar_cache_entry_t *entry = *entries++;
 | 
			
		||||
 | 
			
		||||
        while (entry) {
 | 
			
		||||
            sigar_cache_entry_t *next = entry->next;
 | 
			
		||||
            sigar_uint64_t hash = entry->id % new_size;
 | 
			
		||||
 | 
			
		||||
            entry->next = new_entries[hash];
 | 
			
		||||
            new_entries[hash] = entry;
 | 
			
		||||
            entry = next;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(table->entries);
 | 
			
		||||
    table->entries = new_entries;
 | 
			
		||||
    table->size = new_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SIGAR_CACHE_IX(t, k) \
 | 
			
		||||
    t->entries + (k % t->size)
 | 
			
		||||
 | 
			
		||||
sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
 | 
			
		||||
                                     sigar_uint64_t key)
 | 
			
		||||
{
 | 
			
		||||
    sigar_cache_entry_t *entry, **ptr;
 | 
			
		||||
 | 
			
		||||
    for (ptr = table->entries + (key % table->size), entry = *ptr;
 | 
			
		||||
         entry; ptr = &entry->next, entry = *ptr)
 | 
			
		||||
    for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
 | 
			
		||||
         entry;
 | 
			
		||||
         ptr = &entry->next, entry = *ptr)
 | 
			
		||||
    {
 | 
			
		||||
        if (entry->id == key) {
 | 
			
		||||
            return entry;
 | 
			
		||||
@ -44,15 +100,13 @@ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (table->count++ > table->size) {
 | 
			
		||||
        unsigned int new_size = table->size * 2;
 | 
			
		||||
        sigar_cache_rehash(table);
 | 
			
		||||
 | 
			
		||||
        table->entries =
 | 
			
		||||
            realloc(table->entries, ENTRIES_SIZE(new_size));
 | 
			
		||||
 | 
			
		||||
        memset(table->entries + table->size, '\0',
 | 
			
		||||
               ENTRIES_SIZE(new_size - table->size));
 | 
			
		||||
 | 
			
		||||
        table->size = new_size;
 | 
			
		||||
        for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
 | 
			
		||||
             entry;
 | 
			
		||||
             ptr = &entry->next, entry = *ptr)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *ptr = entry = malloc(sizeof(*entry));
 | 
			
		||||
@ -68,6 +122,10 @@ void sigar_cache_destroy(sigar_cache_t *table)
 | 
			
		||||
    int i;
 | 
			
		||||
    sigar_cache_entry_t **entries = table->entries;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CACHE
 | 
			
		||||
    sigar_cache_dump(table);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<table->size; i++) {
 | 
			
		||||
        sigar_cache_entry_t *entry, *ptr;
 | 
			
		||||
        entry = *entries++;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user