hash 기본 구현.

2007/11/27 19:19

해쉬 구조를 알기 위해선 아래 문서를 읽어 보고...c로 해쉬를 구성해보자.
http://lxr.linux.no/source/include/linux/hash.h


1. 해쉬 함수는 여러가지 알고리즘이 있으나 커널에서는 간단하면서도 우수한 folding exclusive 방식을 사용.

#define PIDHASH_SZ  16
#define
pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))

pid_hashfn(777)

( ( 777 >> 8 ) ^ 777 ) & ( 16 - 1 )

777                                           => 1100001001
777 >> 8                                   => 0000000011
( 777 >> 8 ) ^ 777                      => 1100001010
16 - 1                                       => 0000001111
( ( 777 >> 8 ) ^ 777 ) & ( 16 - 1 )  => 0000001010

2. 해쉬는 탐색을 위한 자료구조라고도 할 수 있다. 자료를 효율적으로 분산하여 저장할 수 있게 된다.


전체 소스~
[ more.. | less.. ]
#include <stdio.h>
#include <time.h>
#include <windows.h>
struct task_struct
{
    int pid;
    struct task_struct *pidhash_next;
    struct task_struct **pidhash_pprev;
};

#define PIDHASH_SZ  16
#define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))

struct task_struct *pidhash[PIDHASH_SZ];


void hash_pid(struct task_struct *p)
{
    struct task_struct **htable = &pidhash[pid_hashfn(p->pid)]; if((p->pidhash_next = *htable) != NULL)
        (*htable)->pidhash_pprev = &p->pidhash_next;
    *htable = p;
    p->pidhash_pprev = htable;
}

void unhash_pid(struct task_struct *p)
{
    if(p->pidhash_next)
        p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
    *p->pidhash_pprev = p->pidhash_next;
}


struct task_struct *find_task_by_pid(int pid)
{
    struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];

    for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
        ;

    return p;
}

void display()
{
    int i;
    struct task_struct *p;

    system("cls");                                          
    for(i =0 ; i < PIDHASH_SZ; i++ )
    {
        printf("[%2d]", i);
        for(p = pidhash[i]; p; p = p->pidhash_next)
            printf("<->[%4d]", p->pid);
        printf("\n");
    }
}

int main()
{

    int temp,i;
    struct task_struct *task;
    srand((unsigned int)time(0));
    display();
    for(i=0; i<30; i++ )
    {
        getchar();
        while( temp = rand())
        {
            if( !find_task_by_pid( temp ))
                break;
        }
        task = (struct task_struct*)malloc(sizeof(struct task_struct));
        task->pid = temp;
        hash_pid( task);
        display();
    }
}

Tags

hash, 자료구조