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