/***************************************************************************
hash.cpp - description
-------------------
begin : Thu Aug 17 2000
copyright : (C) 2000 by Waldemar Baraldi
email : baraldi@lacasilla.com.ar
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "hash.h"
#include <stdio.h>
Hash::Bucket::Bucket(Str * str, Object * obj){
this->str=str;
this->obj=obj;
}
Hash::Bucket::~Bucket(){
delete str;
}
void Hash::Bucket::setStr(Str * str){
if (this->str) delete this->str;
this->str=str;
}
void Hash::Bucket::setObject(Object * obj){
this->obj=obj;
}
Str * Hash::Bucket::getStr(){
return str;
}
Object * Hash::Bucket::getObject(){
return obj;
}
int Hash::function(Str * str){
int i=0, sum=0;
const char * aux=str->get();
while (aux[i]!='\0') sum+=aux[i++];
return(sum % nbuckets);
}
Hash::Hash(int bs){
int i;
nbuckets=bs;
lbuckets=new List *[nbuckets];
for (i=0;i<nbuckets;i++)
lbuckets[i]=new List();
}
Hash::~Hash(){
int i;
List * list;
for (i=0;i<nbuckets;i++){
list=lbuckets[i];
list->empty(false);
delete list;
}
delete[] lbuckets;
}
Hash::Result Hash::add(Str * str, Object * obj){
if (str){
// Index * i;
List * list;
list=lbuckets[function(str)];
if (list->nObjects()>0){
/*
for (i=list->getFirst();i!=list->getEnd();i=list->getNext(i)){
if (((Bucket*)list->getObject(i))->getStr()->isEqual(str)){
((Bucket*)list->getObject(i))->setObject(obj);
return AddedOverwrite;
}
}
*/
list->insert(list->getFirst(), new Bucket(str, obj));
return AddedCollision;
}else{
list->insert(list->getFirst(), new Bucket(str, obj));
return AddedNoCollision;
}
}
return NotAdded;
}
Hash::Result Hash::remove(Str * str, bool del){
if (str){
Index * i;
List * list=lbuckets[function(str)];
for (i=list->getFirst();i!=list->getEnd();i=list->getNext(i))
if (((Bucket *)list->getObject(i))->getStr()->isEqual(str)){
if (del)
delete ((Bucket *)list->getObject(i))->getObject();
list->remove(i, true);
delete str;
return Removed;
}
delete str;
}
return NotFound;
}
Object * Hash::find(Str * str){
if (str){
Index * i;
List * list=lbuckets[function(str)];
i=list->getFirst();
while (i!=list->getEnd()){
if (((Bucket *)list->getObject(i))->getStr()->isEqual(str)){
delete str;
return ((Bucket *)list->getObject(i))->getObject();
}
i=list->getNext(i);
}
delete str;
}
return NULL;
}
void Hash::empty(bool del){
int i;
List * list;
for (i=0;i<nbuckets;i++){
list=lbuckets[i];
if (del){
Index * idx=list->getFirst();
while (idx!=list->getEnd()){
delete ((Bucket*)list->getObject(idx))->getObject();
idx=list->getNext(idx);
}
}
list->empty(del);
}
}