view name_dictionary.cc @ 101:67c843471b77

add name_dictionary.cc
author Atuto SHIROMA <e095729@ie.u-ryukyu.ac.jp>
date Thu, 02 Jun 2011 19:50:06 +0900
parents
children
line wrap: on
line source

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

#define NAME_HASH_SIZE 127  // 127 is prime number
#define REHASH_NUM (NAME_HASH_SIZE / 10)

typedef struct name_dic {
    int ref_num;
    const char *name;
} NAME_DIC;

static NAME_DIC *name_hash=NULL;

int hash_func(const char *string, int hash_size)
{
    int sum;

    for (sum=0;*string;string++) {
        sum += *string;
    }
    sum %= hash_size;
    if (sum < 0) {
        sum += hash_size;
    }

    return(sum);
}

// if error occured return NULL
const char *refer_name_dictionary(const char *string)
{
    int number;
    NAME_DIC *dic_ptr;

    if (string == NULL) return(NULL);

    number = hash_func(string,NAME_HASH_SIZE);

    // detect string or regist space
    for (dic_ptr=name_hash+number; dic_ptr->name ; dic_ptr=name_hash+number) {
        if (!strcmp(string,dic_ptr->name)) {
            dic_ptr->ref_num++;
            return(dic_ptr->name);
        }
        number += REHASH_NUM;
        if (number > NAME_HASH_SIZE) number -= NAME_HASH_SIZE;
    }

    dic_ptr->ref_num = 1;
    dic_ptr->name = (char *)malloc(sizeof(char)*strlen(string)+1);
    if (dic_ptr->name == NULL) {
        fprintf(stderr,"malloc failed at refer_name_dictionary\n");
        return(NULL);
    }
    strcpy((char*)dic_ptr->name,string);

    return(dic_ptr->name);
}

void delete_name_dictionary(const char *string)
{
  int number;
  NAME_DIC *dic_ptr;

  if (string == NULL) return;

  number = hash_func(string,NAME_HASH_SIZE);

  for (dic_ptr=name_hash+number;dic_ptr->name;dic_ptr=name_hash+number) {
    if (!strcmp(string,dic_ptr->name)) {
      dic_ptr->ref_num--;
      if (dic_ptr->ref_num == 0) {
	free((void*)dic_ptr->name);
	dic_ptr->name = NULL;
      }
      return;
    } else {
      number += REHASH_NUM;
      if (number > NAME_HASH_SIZE) number -= NAME_HASH_SIZE;
    }
  }
}

// if error occured return -1
int init_name_dictionary()
{
  int n;
  NAME_DIC *dic;

  free(name_hash);
  name_hash = (NAME_DIC *)malloc(sizeof(NAME_DIC)*NAME_HASH_SIZE);
  if (name_hash == NULL) {
    fprintf(stderr,"malloc failed at init_name_dictionary\n");
    return(-1);
  }

  for (n=0,dic=name_hash;n < NAME_HASH_SIZE;n++,dic++) dic->name = NULL;

  return(1);
}