/*
 * Used to test the hashing function on some known data
 */
#include <stdio.h>
#include <string.h>

#define MAX(x,y) (x > y ? x : y)

#define LIB_BUCKETS 37
#define ROTR(x,bits) (((x << (16 - bits)) | (x >> bits)) & 0xffff)
#define ROTL(x,bits) (((x << bits) | (x >> (16 - bits))) & 0xffff)

typedef unsigned uint;
typedef unsigned short ushort;
typedef uint hv;
typedef struct {
  hv block_x,bucket_x,block_d,bucket_d;
} hash;
static void compute_hash(const char * name, int blocks, hash *h)
{
  int len = strlen(name);
  const char *pb = name, *pe = name + len;
  const ushort blank = ' ';

  hv block_x = len | blank, bucket_d = len | blank;
	hv block_d = 0, bucket_x = 0;

  while (1) {
    ushort cback = *(--pe) | blank;
		ushort cfront = *(pb++) | blank;
		bucket_x = ROTR(bucket_x, 2) ^ cback;
		block_d = ROTL(block_d, 2) ^ cback;
		if (--len == 0)
			break;
		block_x = ROTL(block_x,2) ^ cfront;
    bucket_d = ROTR(bucket_d,2) ^ cfront;
  }
  h->block_x = block_x % blocks;
  h->block_d = block_d % blocks;
	h->block_d = MAX(h->block_d, 1);
  h->bucket_x = bucket_x % LIB_BUCKETS;
  h->bucket_d = bucket_d % LIB_BUCKETS;
  h->bucket_d = MAX(h->bucket_d, 1);
}
void main(void)
{
  hash h;
  compute_hash("___lseek",0x59,&h);
  printf("Block_x : %x\n",h.block_x); 
  printf("Bucket_x: %x\n",h.bucket_x); 
  printf("Block_d : %x\n",h.block_d); 
  printf("Bucket_d: %x\n",h.bucket_d); 
}