view TaskManager/kernel/memory/MemHash.cc @ 873:3b9536925fb8

fix hash problem ( unsigned int-> long overflow )
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 04 Jul 2010 19:01:24 +0900
parents 60aa3f241b10
children 8df4323f9fdb
line wrap: on
line source

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "MemHash.h"

static unsigned short PRIME[8] = {
    0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd,
};

int
MemHash::hash(memaddr data0)
{
    unsigned long data = (unsigned long)data0;
    int value = 0;
    int n = 0;
    long key;

    for (uint32 i = 0; i < sizeof(memaddr) * 2; i ++) {
        key = data & 0xf;
        value += key * PRIME[n++ & 7];
        data >>= 4;
    }
printf("hash value %0x => %0x\n",data0, value);

    return value % hashSize;
}

MemHash::MemHash()
{
    table = (MemorySegmentPtr*)malloc(tableSize);
    clear();
}

int
MemHash::put(memaddr key, MemorySegmentPtr data)
{
    int hashval = hash(key);

    for (int i = 0; i < hashSize/2; i++) {
        int index = (hashval + i*i)%hashSize;

        if (table[index] == 0) { // 空の table に入れる
            table[index] = data;
            return index;
        }
    }

    return -1;
}

MemorySegmentPtr
MemHash::get(memaddr key)
{
    int hashval = hash(key);

    for (int i = 0; i < hashSize/2; i++) {
        int index = (hashval + i*i)%hashSize;

        if (table[index] != NULL &&
            table[index]->address == key) {
printf("get hash value %0x\n",index);
            return table[index];
        }
    }

    return NULL;
}

void
MemHash::remove(memaddr key)
{
    int hashval = hash(key);

    for (int i = 0; i < hashSize/2; i++) {
        int index = (hashval + i*i)%hashSize;

        if (table[index] != NULL &&
            table[index]->address == key) {
            table[index] = NULL;
        }
    }
}

void
MemHash::clear(void)
{
    bzero(table, tableSize);
}

/* end */