return 0;
}
-int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque)
+int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_FUNCION funcion, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque)
{
INDICE *tmp;
- tmp = emufs_indice_crear(emu, nombre, tipo, tipo_dato, offset, tam_bloque);
+ int error=0;
+
+ /* Verifico que no existe un indice con el mismo nombre */
+ /* y que no exista un indice primario */
+ tmp = emu->indices;
+ while (tmp) {
+ if (strcmp(tmp->nombre, nombre)==0) {
+ error = 1;
+ break;
+ }
+ if ((funcion == IND_PRIMARIO) && (tmp->funcion == funcion)) {
+ error = 2;
+ break;
+ }
+ }
+
+ if (tmp != NULL) {
+ switch (error) {
+ case 1:
+ PERR("Ya existe un indice con el mismo nombre!");
+ break;
+ case 2:
+ PERR("EMUFS ya tiene indice primario!!");
+ break;
+ default:
+ PERR("Error no esperado!!");
+ }
+ return 0;
+ }
+
+ /* Creo el nuevo indice */
+ tmp = emufs_indice_crear(emu, nombre, funcion, tipo, tipo_dato, offset, tam_bloque);
if (tmp == NULL) return 0;
return 1;
}
+INDICE_DATO *emufs_buscar_registros(EMUFS *emu, char *indice, CLAVE clave, int *cant)
+{
+ INDICE *tmp;
+ tmp = emu->indices;
+ while (tmp) {
+ if (strcmp(tmp->nombre, indice) == 0) break;
+ }
+
+ if (tmp == NULL) {
+ PERR("NO EXISTE EL INDICE");
+ cant = 0;
+ return NULL;
+ }
+
+ return tmp->buscar_entradas(tmp, clave, cant);
+}
+
/** muestra estadisticas, para debug. */
int debug_ver_estadisticas(EMUFS *emu);
-int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque);
+int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_FUNCION funcion, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque);
+INDICE_DATO *emufs_buscar_registros(EMUFS *emu, char *indice, CLAVE clave, int *cant);
#endif /* _EMUFS_H_ */
static void b_leer_header(char *src, B_NodoHeader *header);
static void b_actualizar_header(char *src, B_NodoHeader *header);
static B_NodoEntry *b_leer_claves(char *src, B_NodoHeader *header);
-static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2);
+static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, INDICE_DATO dato, int nodo_id, char *nodo, int hijo1, int hijo2);
const int b_elegir_izquierdo(INDICE *idx, int a, int b);
void emufs_indice_b_crear(INDICE *idx)
fclose(fp);
}
-int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, int ubicacion)
+int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, INDICE_DATO dato)
{
int i, nodo_id, padre_id;
B_NodoHeader header;
}
} else {
if (header.nivel != 0) {
- nodo = b_leer_nodo(idx, claves[i-1].ubicacion);
- nodo_id = claves[i-1].ubicacion;
+ nodo = b_leer_nodo(idx, claves[i-1].dato.bloque);
+ nodo_id = claves[i-1].dato.bloque;
} else {
nodo = NULL;
nodo_id = -1;
if (nodo) free(nodo);
nodo = padre;
nodo_id = padre_id;
- b_insertar_en_nodo(idx, clave, ubicacion, nodo_id, nodo, -1, -1);
+ b_insertar_en_nodo(idx, clave, dato, nodo_id, nodo, -1, -1);
return 1; /* Agregar OK! */
}
-int emufs_indice_b_buscar(INDICE *idx, CLAVE clave)
+INDICE_DATO emufs_indice_b_buscar(INDICE *idx, CLAVE clave)
{
- int i, ret;
+ int i;
+ INDICE_DATO ret;
B_NodoHeader header;
B_NodoEntry *claves;
char *nodo, *tmp;
i=0;
while ((i<header.cant) && (emufs_indice_es_menor(idx, claves[i].clave, clave))) i++;
if (emufs_indice_es_igual(idx, claves[i].clave, clave)) {
- ret = claves[i].ubicacion;
+ ret = claves[i].dato;
free(nodo);
return ret;
} else {
if (i == 0) {
nodo = b_leer_nodo(idx, header.hijo_izquierdo);
} else {
- nodo = b_leer_nodo(idx, claves[i-1].ubicacion);
+ nodo = b_leer_nodo(idx, claves[i-1].dato.bloque);
}
free(tmp);
}
}
/* Nodo no encontrado */
- return -1;
+ ret.id = ret.bloque = -1;
+ return ret;
}
static int b_ultimo_id(INDICE *idx)
return (B_NodoEntry *)(src+sizeof(B_NodoHeader));
}
-static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2)
+static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, INDICE_DATO dato, int nodo_id, char *nodo, int hijo1, int hijo2)
{
char *padre, *nuevo;
int nuevo_id;
i++;
}
tmp_claves[i].clave = clave;
- tmp_claves[i].ubicacion = ubicacion;
+ tmp_claves[i].dato = dato;
while (i < nodo_header.cant) {
tmp_claves[i+1] = claves[i];
i++;
if (nodo_id != 0) {
clave = tmp_claves[total/2].clave;
- ubicacion = nuevo_id;
+ dato.bloque = nuevo_id;
b_grabar_nodo(idx, nodo_id, nodo);
b_grabar_nodo(idx, nuevo_id, nuevo);
nodo = tmp_nuevo;
clave = tmp_claves[total/2].clave;
- ubicacion = nuevo_id;
+ dato.bloque = nuevo_id;
b_grabar_nodo(idx, nuevo_id+1, nodo);
b_grabar_nodo(idx, nuevo_id, nuevo);
}
nodo_header.cant++;
claves[i].clave = clave;
- claves[i].ubicacion = ubicacion;
+ claves[i].dato = dato;
nodo_header.hijo_izquierdo = b_elegir_izquierdo(idx, nodo_header.hijo_izquierdo, hijo1);
b_actualizar_header(nodo, &nodo_header);
return cual;
}
+INDICE_DATO *emufs_indice_b_buscar_muchos(INDICE *idx, CLAVE clave, int *cant)
+{
+ /* Si el indice es primario no tiene sentido hacer nada */
+ if (idx->funcion == IND_PRIMARIO) {
+ *cant = 0;
+ return NULL;
+ }
+
+ /* TODO Implementar indices con repeticion */
+ return NULL;
+}
+
* Si el nivel != 0, es el siguiente bloque dentro
* del archivo de indice donde buscar
*/
- long ubicacion;
+ INDICE_DATO dato;
} B_NodoEntry;
/* Crea un arbol */
void emufs_indice_b_crear(INDICE *idx);
/* Inserta un par clave-ubicacion */
-int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, int ubicacion);
+int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, INDICE_DATO dato);
/* Busca una clave, retorna ubicacion o -1 si no existe */
-int emufs_indice_b_buscar(INDICE *idx, CLAVE clave);
+INDICE_DATO emufs_indice_b_buscar(INDICE *idx, CLAVE clave);
+INDICE_DATO *emufs_indice_b_buscar_muchos(INDICE *idx, CLAVE clave, int *cant);
#endif
#include "indice_b.h"
static CLAVE obtenet_clave(INDICE *idx, char *data);
+static CLAVE obtenet_clave_desde_valor(INDICE *idx, char *data);
-INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque)
+INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_FUNCION funcion, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque)
{
int len;
INDICE *tmp;
tmp->tipo = tipo;
tmp->tipo_dato = tipo_dato;
tmp->tam_bloque = tam_bloque;
+ tmp->funcion = funcion;
tmp->offset = offset;
tmp->sig = NULL;
tmp->agregar_entrada = emufs_indice_b_insertar;
tmp->borrar_entrada = NULL;
tmp->existe_entrada = emufs_indice_b_buscar;
+ tmp->buscar_entradas = NULL;
break;
case IND_B_ASC:
/* llenar metodos */
free(i);
}
-void emufs_indice_agregar(INDICE *primero, char *data, int ubicacion)
+void emufs_indice_agregar(INDICE *primero, char *data, INDICE_DATO dato)
{
INDICE *iter = primero;
while (iter) {
- iter->agregar_entrada(iter, obtenet_clave(iter, data), ubicacion);
+ iter->agregar_entrada(iter, obtenet_clave(iter, data), dato);
iter = iter->sig;
}
}
+INDICE_DATO emufs_indice_buscar(INDICE *primero, char *data)
+{
+ return primero->existe_entrada(primero, obtenet_clave_desde_valor(primero, data));
+}
+
+static CLAVE obtenet_clave_desde_valor(INDICE *idx, char *data)
+{
+ CLAVE k;
+ switch (idx->tipo_dato) {
+ case IDX_FLOAT:
+ k.f_clave= *((float *)(data));
+ break;
+ case IDX_INT:
+ k.i_clave = *((int *)(data));
+ }
+
+ return k;
+}
+
static CLAVE obtenet_clave(INDICE *idx, char *data)
{
CLAVE k;
typedef struct _emu_fs_t EMUFS;
+typedef struct _reg_def_ {
+ unsigned long id;
+ unsigned long bloque;
+} INDICE_DATO;
+
/** Tipos de Indices conocidos */
typedef enum {
IND_B, /**< Utilizacion de Arboles B */
IND_B_ASC /**< Utilizacion de Arboles B* */
} INDICE_TIPO;
+typedef enum {
+ IND_PRIMARIO,
+ IND_SELECCION,
+ IND_EXAHUSTIVO
+} INDICE_FUNCION;
+
/** Tipos de datos soportados para las claves */
typedef enum {IDX_FLOAT, IDX_INT} INDICE_TIPO_DATO;
typedef struct _indices_h_ {
INDICE_TIPO tipo; /**< Tipo de indice */
INDICE_TIPO_DATO tipo_dato; /**< Tipo de dato a manejar */
+ INDICE_FUNCION funcion; /**< Funcion del indice */
int offset; /**< Offset desde el inicio del dato hasta el lugar donde esta la clave */
unsigned int tam_bloque; /**< Tamaño del bloque (nodo). Deber set multiplo de 512! */
/** Agrega la clave k de posicion location en el
* indice de forma ordenada
*/
- int (*agregar_entrada)(struct _indices_h_ *idx, CLAVE k, int location);
+ int (*agregar_entrada)(struct _indices_h_ *idx, CLAVE k, INDICE_DATO dato);
/** Borra del indice la clave k */
int (*borrar_entrada)(struct _indices_h_ *idx, CLAVE k);
/** Determina si existe la clave k retornando su posicion o -1
* en caso fallido
*/
- int (*existe_entrada)(struct _indices_h_ *idx, CLAVE k);
+ INDICE_DATO (*existe_entrada)(struct _indices_h_ *idx, CLAVE k);
+
+ INDICE_DATO *(*buscar_entradas)(struct _indices_h_ *idx, CLAVE k, int *cant);
char *nombre; /**< Nombre único de busqueda del indice */
char *filename; /**< nombre del archivo de indice */
* \param offset Desplazamiento de la clave dentro del dato
* \param tam_bloque Tamaño del bloque (nodo) del arbol
*/
-INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned tam_bloque);
+INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_FUNCION funcion, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned tam_bloque);
/** Destruye un indice
*
* \param data Array de datos desde donde tomar las claves
* \param ubicacion Dato a guardar asociado a la clave
*/
-void emufs_indice_agregar(INDICE *primero, char *data, int ubicacion);
+void emufs_indice_agregar(INDICE *primero, char *data, INDICE_DATO dato);
+
+INDICE_DATO emufs_indice_buscar(INDICE *primero, char *data);
/** Compara 2 claves de la forma c1 < c2 */
int emufs_indice_es_menor(INDICE *idx, CLAVE c1, CLAVE c2);