void HashExtensible::del( Key_Node &key) { int Dir = fHash(key); //Obtengo el bucket al que apunta la direcci�n que devolvi� la funci�n de Hash. int nB = directory.getNBlockBucket(Dir); buckets.deleteKey(nB, key); //Si el bucket est� vac�o y tiene una sola referencia, reorganizo el directorio y los buckets. if ( (buckets.getBucket(nB).empty()) && (buckets.getBucket(nB).getRef() == 1) ) { int newDir = this->getPrevDir(Dir); int nuevoBucket = directory.getNBlockBucket(newDir); directory.updateDir(Dir,nuevoBucket); buckets.addRef(nuevoBucket); buckets.deleteBucket(nB); //Si el m�nimo de referencias a todos los bucketes es 2, saco un bit y reorganizo el directorio. if (buckets.minRef(directory.getDirectory()) == 2) { this->actualbits--; directory.updateBits(actualbits); directory.reduceDirectory(); buckets.divRef(directory.getDirectory()); } } }
/* InsertarVocab(): Inserta una palabra en el vocabulario Recibe: tipo, lexema y c¢digo de la palabra (si ‚ste es == -1, se indica el siguiente c¢digo libre) Devuelve: 1 si no hay errores; 0 en caso contrario */ int InsertarVocab(TIPO_PALABRA tipoPal, char *lex, int cod) { PALABRA *aux, *i; int pos; int j; if (CodigoVocab(lex) == -1) { /* Si no existe ya esa palabra */ if ((aux = (PALABRA*) Memoria((long) sizeof(PALABRA))) == NULL) return 0; if (cod == -1) { /* Insertamos con un nuevo c¢digo */ for (j = 0; j < INDICE_PALABRA && indicePal[j] != NULL; j++); if (j >= INDICE_PALABRA) return 0; else cod = j; } aux->codigo = cod; aux->tipo = tipoPal; aux->lexema = (char *) Memoria((long) (strlen(lex) + 1)); strcpy(aux->lexema, lex); aux->sinonimos = NULL; aux->siguiente = NULL; /* B£squeda por lexema */ pos = fHash(lex); i = tablaPal[pos]; if (i == NULL) tablaPal[pos] = aux; /* Actualizaci¢n del vector hash */ else { while (i->siguiente != NULL) i = i->siguiente; i->siguiente = aux; } /* B£squeda por c¢digo */ i = indicePal[cod]; if (i == NULL) { indicePal[cod] = aux; /* Actualizaci¢n del ¡ndice */ } else { while (i->sinonimos != NULL) i = i->sinonimos; i->sinonimos = aux; } numPal++; return 1; } else return 0; }
Refs * HashExtensible::get( Key_Node &key) { int Dir = fHash(key); //Obtengo el bucket al que apunta la direcci�n que devolvi� la funci�n de Hash. int nB = directory.getNBlockBucket(Dir); //Cargo el bucket y busco la clave. return buckets.getBucket(nB).getValue(key); }
bool HashExtensible::contains ( Key_Node &key) { int Dir = fHash(key); if (directory.exists(Dir)) { int nB = directory.getNBlockBucket(Dir); return (buckets.getBucket(nB).exists(key)); } else return false; }
/* DarPalabra(): Devuelve un puntero a la direcci¢n de la palabra Recibe: El lexema de la palabra Devuelve: El puntero a la palabra, o NULL si no exist¡a */ PALABRA *DarPalabraVocab(char *lex) { PALABRA *aux; int encontrado; aux = tablaPal[fHash(lex)]; encontrado = 0; while (aux != NULL && !encontrado) { if (!strcmp(lex, aux->lexema)) encontrado = 1; else aux = aux->siguiente; } return (encontrado) ? aux : NULL; }
/* DarRespuesta(): Devuelve la respuesta dada para ese verbo y nombre Recibe: Verbo y nombre de la respuesta Devuelve: El puntero a la respuesta, o NULL si no existe */ RESPUESTA *DarRespuesta(int verb, int nomb) { RESPUESTA *aux; int encontrado; aux = tablaResp[fHash(verb, nomb)]; encontrado = 0; while (aux != NULL && !encontrado) { if (aux->verbo == verb && aux->nombre == nomb) encontrado = 1; else aux = aux->siguiente; } return (encontrado) ? aux : NULL; }
/* InsertarRespuesta(): Inserta una respuesta en la tabla de respuestas Recibe: Respuesta (verbo y nombre) y direcci¢n de primera instrucci¢n a ejecutar en el vector de c¢digo Devuelve: 1 si no hay errores; 0 en caso contrario */ int InsertarRespuesta(int verb, int nomb, int dir) { RESPUESTA *aux, *i; char *p; int pos, cod; int j; /* Si no existe ya esa respuesta */ if (DarRespuesta(verb, nomb) == NULL) { if ((aux = (RESPUESTA*) Memoria((long) sizeof(RESPUESTA))) == NULL) return 0; aux->verbo = verb; aux->nombre = nomb; aux->direccion = dir; aux->siguiente = NULL; /* B£squeda por nombre y adjetivo */ pos = fHash(verb, nomb); i = tablaResp[pos]; if (i == NULL) tablaResp[pos] = aux; /* Actualizaci¢n del vector hash */ else { while (i->siguiente != NULL) i = i->siguiente; i->siguiente = aux; } numResp++; return 1; } else return 0; }
void HashExtensible::add(Key_Node &key, Refs value) { //load(); //cout << "HashExtensible::add: " << key.toInt() << endl; if (!contains(key)) { int Dir = fHash(key); //Obtengo el bucket al que apunta la direcci�n que devolvi� la funci�n de Hash. int nBucket = directory.getNBlockBucket(Dir); if (nBucket == -1) { //No existe la direccion -> creo un Bucket, creo una nueva direcci�n que lo apunte e inserto la clave int nBlockBucket = buckets.createBucket(); directory.insertDir(Dir,nBlockBucket); buckets.addRef(nBlockBucket); buckets.insertKey(nBlockBucket, key, value); } else { while (buckets.isFull(nBucket)) { //Si no se puede dividir -> duplico el directorio if (buckets.getBucket(nBucket).getRef() == 1) { buckets.duplicateRef(directory.getDirectory()); directory.duplicateDirectory(); this->actualbits++; directory.updateBits(actualbits); } //Creo un nuevo Bucket y redistribuyo int newBlockBucket = buckets.createBucket(); //Redirecciono al nuevo Bucket y actualizo las referencias directory.redirect(nBucket, newBlockBucket, buckets.getBucket(nBucket).getRef()); int nRef = buckets.getBucket(nBucket).getRef()/2; buckets.updateRef(nBucket,nRef); buckets.updateRef(newBlockBucket, nRef); //Inserto las claves que colisionaron y redistribuyo. Bucket TempBuck = buckets.getBucket(nBucket); buckets.clearBucket(nBucket); for (int n= 0; n < TempBuck.size(); n++) { Key_Node k=Key_Node(TempBuck.at(n).first); Dir = fHash(k); nBucket = directory.getNBlockBucket(Dir); buckets.insertKey(nBucket, k, TempBuck.at(n).second ); //this->add(k,TempBuck.at(n).second); } //Obtengo la nueva direccion Dir = fHash(key); //Obtengo el bucket al que apunta la direcci�n que devolvi� la funci�n de Hash. nBucket = directory.getNBlockBucket(Dir); } buckets.insertKey(nBucket, key, value); } } else { cout<<"Error la clave ya existe"<<endl;; } }
nat TablaHashAbierto<C,V,FHash>::H(const C& c) const { const FuncionHash<C>& fHash = FHash(); return fHash(c) % arreglo.Largo; }