From a499b030d1840a0714721695cd6fcf54bc7dbb68 Mon Sep 17 00:00:00 2001 From: Ricardo Markiewicz Date: Sun, 9 May 2004 18:44:46 +0000 Subject: [PATCH 1/1] * Integro Indice B con EMUFS e Indice * Ajusto detalles para futura implementacion (macros, func auxiliares) --- emufs/Makefile | 4 +- emufs/b_test.c | 7 ++- emufs/emufs.c | 4 +- emufs/emufs.h | 2 +- emufs/indice_b.c | 150 +++++++++++++++++++++++------------------------ emufs/indice_b.h | 8 +-- emufs/indices.c | 48 +++++++++++++-- emufs/indices.h | 11 +++- 8 files changed, 137 insertions(+), 97 deletions(-) diff --git a/emufs/Makefile b/emufs/Makefile index e43a3a3..f98675d 100644 --- a/emufs/Makefile +++ b/emufs/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -g -ansi -pedantic -DDEBUG LDFLAGS=-lm -EMUFS_COMMON=emufs.o tipo1.o tipo2.o tipo3.o idx.o did.o fsc.o common.o indices.o +EMUFS_COMMON=emufs.o tipo1.o tipo2.o tipo3.o idx.o did.o fsc.o common.o indices.o indice_b.o all: libemufs.a tipo1_main tipo2_main tipo3_main b_test @@ -11,7 +11,7 @@ tipo2_main: tipo2_main.o $(EMUFS_COMMON) tipo3_main: tipo3_main.o $(EMUFS_COMMON) -b_test: b_test.o indice_b.o +#b_test: b_test.o indice_b.o libemufs.a: $(EMUFS_COMMON) $(AR) cru libemufs.a $(EMUFS_COMMON) diff --git a/emufs/b_test.c b/emufs/b_test.c index b945672..4fd9c9d 100644 --- a/emufs/b_test.c +++ b/emufs/b_test.c @@ -7,7 +7,8 @@ int main(int argc, char *argv[]) { int pos; int c; - b_crear(); + + /*emufs_indice_b_crear(); srand(time(NULL)); @@ -17,14 +18,14 @@ int main(int argc, char *argv[]) do { printf("Numero a buscar (-1 para salir):\n"); scanf("%d", &c); - fgetc(stdin); /*saco el \n del buffer */ + fgetc(stdin); pos = b_buscar(c); if (pos == -1) printf("No encontrado\n"); else printf("Esta en la pos %d\n", pos); } while (c!=-1); - +*/ return 0; } diff --git a/emufs/emufs.c b/emufs/emufs.c index 760fc49..14fcafb 100644 --- a/emufs/emufs.c +++ b/emufs/emufs.c @@ -342,10 +342,10 @@ int debug_ver_estadisticas(EMUFS* efs) return 0; } -int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset) +int emufs_agregar_indice(EMUFS *emu, char *nombre, 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); + tmp = emufs_indice_crear(emu, nombre, tipo, tipo_dato, offset, tam_bloque); if (tmp == NULL) return 0; diff --git a/emufs/emufs.h b/emufs/emufs.h index d610a8a..fcbd9b7 100644 --- a/emufs/emufs.h +++ b/emufs/emufs.h @@ -173,6 +173,6 @@ int ver_archivo_FS(EMUFS *emu); /** 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); +int emufs_agregar_indice(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned int tam_bloque); #endif /* _EMUFS_H_ */ diff --git a/emufs/indice_b.c b/emufs/indice_b.c index 396e9af..f3fd08f 100644 --- a/emufs/indice_b.c +++ b/emufs/indice_b.c @@ -1,26 +1,23 @@ #include "indice_b.h" -#define FILENAME "b.idx" -#define BLOCK_SIZE 512 - /* Cantidad de claves por nodo */ -#define CANT_HIJOS ((BLOCK_SIZE-sizeof(B_NodoHeader))/sizeof(B_NodoEntry)) -#define CANT_NODOS (CANT_HIJOS+1) -#define MIN_HIJOS (CANT_HIJOS/2) +#define CANT_HIJOS(x) ((x->tam_bloque-sizeof(B_NodoHeader))/sizeof(B_NodoEntry)) +#define CANT_NODOS(x) (CANT_HIJOS(x)+1) +#define MIN_HIJOS(x) (CANT_HIJOS(x)/2) /* Auxiliares */ -static void b_grabar_nodo(int id, char *data); -static int b_ultimo_id(); -static char *b_leer_nodo(int id); -static char *b_crear_nodo(); +static void b_grabar_nodo(INDICE *idx, int id, char *data); +static int b_ultimo_id(INDICE *idx); +static char *b_leer_nodo(INDICE *idx, int id); +static char *b_crear_nodo(INDICE *idx, int *i); 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(int clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2); -const int b_elegir_izquierdo(int a, int b); +static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2); +const int b_elegir_izquierdo(INDICE *idx, int a, int b); -void b_crear() +void emufs_indice_b_crear(INDICE *idx) { FILE *fp; char *bloque; @@ -31,19 +28,19 @@ void b_crear() header.padre = -1; header.hijo_izquierdo = -1; - fp = fopen(FILENAME, "w"); + fp = fopen(idx->filename, "w"); /* Creo el archivo con el Nodo raiz */ - bloque = (char *)malloc(BLOCK_SIZE); - memset(bloque, -1, BLOCK_SIZE); + bloque = (char *)malloc(idx->tam_bloque); + memset(bloque, -1, idx->tam_bloque); memcpy(bloque, &header, sizeof(B_NodoHeader)); - fwrite(bloque, BLOCK_SIZE, 1, fp); + fwrite(bloque, idx->tam_bloque, 1, fp); fclose(fp); } -int b_insertar(int clave, int ubicacion) +int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, int ubicacion) { int i, nodo_id, padre_id; B_NodoHeader header; @@ -51,7 +48,7 @@ int b_insertar(int clave, int ubicacion) char *nodo, *padre; /* Leo la raiz */ - nodo = b_leer_nodo(0); + nodo = b_leer_nodo(idx, 0); padre_id = nodo_id = 0; padre = NULL; while (nodo) { @@ -61,14 +58,14 @@ int b_insertar(int clave, int ubicacion) b_leer_header(nodo, &header); claves = b_leer_claves(nodo, &header); i=0; - while ((ifilename, "r"); fseek(fp, 0, SEEK_END); - i = ftell(fp)/BLOCK_SIZE; + i = ftell(fp)/idx->tam_bloque; fclose(fp); return i; } -static char *b_crear_nodo(int *id) +static char *b_crear_nodo(INDICE *idx, int *id) { char *bloque; B_NodoHeader header; - (*id) = b_ultimo_id(); + (*id) = b_ultimo_id(idx); - printf("Nuevo nodo creado : id = %d\n", *id); header.cant = 0; header.nivel = 0; header.hijo_izquierdo = -1; header.padre = -1; - bloque = (char *)malloc(BLOCK_SIZE); - memset(bloque, -1, BLOCK_SIZE); + bloque = (char *)malloc(idx->tam_bloque); + memset(bloque, -1, idx->tam_bloque); memcpy(bloque, &header, sizeof(B_NodoHeader)); - b_grabar_nodo(*id, bloque); + b_grabar_nodo(idx, *id, bloque); return bloque; } -static char *b_leer_nodo(int id) +static char *b_leer_nodo(INDICE *idx, int id) { FILE *fp; char *out; if (id < 0) return NULL; - fp = fopen(FILENAME, "r"); + fp = fopen(idx->filename, "r"); if (fp == NULL) return NULL; - fseek(fp, id*BLOCK_SIZE, SEEK_SET); + fseek(fp, id*idx->tam_bloque, SEEK_SET); - out = (char *)malloc(BLOCK_SIZE); + out = (char *)malloc(idx->tam_bloque); if (out == NULL) { fclose(fp); return NULL; } - if (fread(out, 1, BLOCK_SIZE, fp) != BLOCK_SIZE) { + if (fread(out, 1, idx->tam_bloque, fp) != idx->tam_bloque) { free(out); /* No se puso leer el nodo */ fclose(fp); @@ -191,7 +185,7 @@ static char *b_leer_nodo(int id) return out; } -static void b_grabar_nodo(int id, char *data) +static void b_grabar_nodo(INDICE *idx, int id, char *data) { FILE *fp; @@ -212,9 +206,9 @@ static void b_grabar_nodo(int id, char *data) printf("SOLO GUARDO DATA\n"); }*/ - fp = fopen(FILENAME, "r+"); - fseek(fp, id*BLOCK_SIZE, SEEK_SET); - fwrite(data, 1, BLOCK_SIZE, fp); + fp = fopen(idx->filename, "r+"); + fseek(fp, id*idx->tam_bloque, SEEK_SET); + fwrite(data, 1, idx->tam_bloque, fp); fclose(fp); } @@ -236,7 +230,7 @@ static B_NodoEntry *b_leer_claves(char *src, B_NodoHeader *header) return (B_NodoEntry *)(src+sizeof(B_NodoHeader)); } -static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2) +static void b_insertar_en_nodo(INDICE *idx, CLAVE clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2) { char *padre, *nuevo; int nuevo_id; @@ -249,21 +243,21 @@ static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo do { if (!nodo) { /* CREAR NODO? */ - nodo = b_crear_nodo(&nodo_id); + nodo = b_crear_nodo(idx, &nodo_id); } b_leer_header(nodo, &nodo_header); claves = b_leer_claves(nodo, &nodo_header); - padre = b_leer_nodo(nodo_header.padre); + padre = b_leer_nodo(idx, nodo_header.padre); - if (nodo_header.cant == CANT_HIJOS) { + if (nodo_header.cant == CANT_HIJOS(idx)) { int total; - nuevo = b_crear_nodo(&nuevo_id); + nuevo = b_crear_nodo(idx, &nuevo_id); i=0; /* Creo una lista ordenada de los nodos a partir */ tmp_claves = (B_NodoEntry *)malloc(sizeof(B_NodoEntry)*(nodo_header.cant+1)); total = nodo_header.cant; - while ((itam_bloque-sizeof(B_NodoHeader)); for(j=0; jtam_bloque-sizeof(B_NodoHeader)); for(j=0; jtam_bloque); free(nodo); nodo = tmp_nuevo; clave = tmp_claves[total/2].clave; ubicacion = nuevo_id; - b_grabar_nodo(nuevo_id+1, nodo); - b_grabar_nodo(nuevo_id, nuevo); + b_grabar_nodo(idx, nuevo_id+1, nodo); + b_grabar_nodo(idx, nuevo_id, nuevo); free(nodo); free(nuevo); @@ -331,15 +325,15 @@ static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo hijo2 = nuevo_id; /* Limpio al padre */ - nuevo = b_leer_nodo(0); + nuevo = b_leer_nodo(idx, 0); b_leer_header(nuevo, &nuevo_header); nuevo_header.cant = 0; nuevo_header.padre = -1; nuevo_header.nivel = nodo_header.nivel+1; - memset(nuevo, -1, BLOCK_SIZE); + memset(nuevo, -1, idx->tam_bloque); b_actualizar_header(nuevo, &nuevo_header); - b_grabar_nodo(0, nuevo); + b_grabar_nodo(idx, 0, nuevo); nodo_id = 0; nodo = nuevo; @@ -349,36 +343,36 @@ static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo /* La clave entra en este nodo!! */ i = 0; if (nodo_header.cant > 0) { - while ((claves[i].clave < clave) && (i < nodo_header.cant)) i++; + while ((emufs_indice_es_menor(idx, claves[i].clave, clave)) && (i < nodo_header.cant)) i++; for(j=nodo_header.cant; j > i; j--) claves[j] = claves[j-1]; } nodo_header.cant++; claves[i].clave = clave; claves[i].ubicacion = ubicacion; - nodo_header.hijo_izquierdo = b_elegir_izquierdo(nodo_header.hijo_izquierdo, hijo1); + nodo_header.hijo_izquierdo = b_elegir_izquierdo(idx, nodo_header.hijo_izquierdo, hijo1); b_actualizar_header(nodo, &nodo_header); - b_grabar_nodo(nodo_id, nodo); + b_grabar_nodo(idx, nodo_id, nodo); /* Debo actualizar los punteros al padre de los hijos */ if (hijo1 != -1) { - nuevo = b_leer_nodo(hijo1); + nuevo = b_leer_nodo(idx, hijo1); if (nuevo != NULL) { b_leer_header(nuevo, &nuevo_header); nuevo_header.padre = nodo_id; b_actualizar_header(nuevo, &nuevo_header); - b_grabar_nodo(hijo1, nuevo); + b_grabar_nodo(idx, hijo1, nuevo); free(nuevo); } else printf("FUCK! hijo1=%d no existe!\n", hijo1); } if (hijo2 != -1) { - nuevo = b_leer_nodo(hijo2); + nuevo = b_leer_nodo(idx, hijo2); if (nuevo != NULL) { b_leer_header(nuevo, &nuevo_header); nuevo_header.padre = nodo_id; b_actualizar_header(nuevo, &nuevo_header); - b_grabar_nodo(hijo2, nuevo); + b_grabar_nodo(idx, hijo2, nuevo); free(nuevo); } else printf("FUCK! hijo2=%d no existe!\n", hijo2); } @@ -387,7 +381,7 @@ static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo } while (!salir); } -const int b_elegir_izquierdo(int a, int b) +const int b_elegir_izquierdo(INDICE *idx, int a, int b) { int cual; char *nodo1, *nodo2; @@ -397,8 +391,8 @@ const int b_elegir_izquierdo(int a, int b) if (a==-1) return b; if (b==-1) return a; - nodo1 = b_leer_nodo(a); - nodo2 = b_leer_nodo(b); + nodo1 = b_leer_nodo(idx, a); + nodo2 = b_leer_nodo(idx, b); b_leer_header(nodo1, &header1); b_leer_header(nodo2, &header2); @@ -406,7 +400,7 @@ const int b_elegir_izquierdo(int a, int b) claves1 = b_leer_claves(nodo1, &header1); claves2 = b_leer_claves(nodo2, &header2); - if (claves1[0].clave < claves2[0].clave) + if (emufs_indice_es_menor(idx, claves1[0].clave, claves2[0].clave)) cual = a; else cual = b; diff --git a/emufs/indice_b.h b/emufs/indice_b.h index c0a1bf3..f1f6714 100644 --- a/emufs/indice_b.h +++ b/emufs/indice_b.h @@ -21,7 +21,7 @@ typedef struct _b_nodo_header_ { typedef struct _b_nodo_entry_ { /* FIXME usar tipo CLAVE */ - int clave; + CLAVE clave; /* Si el nivel del nodo == 0, quiere decir que es el * bloque del archivo de datos donde esta el registro. * Si el nivel != 0, es el siguiente bloque dentro @@ -31,13 +31,13 @@ typedef struct _b_nodo_entry_ { } B_NodoEntry; /* Crea un arbol */ -void b_crear(); +void emufs_indice_b_crear(INDICE *idx); /* Inserta un par clave-ubicacion */ -int b_insertar(int clave, int ubicacion); +int emufs_indice_b_insertar(INDICE *idx, CLAVE clave, int ubicacion); /* Busca una clave, retorna ubicacion o -1 si no existe */ -int b_buscar(int clave); +int emufs_indice_b_buscar(INDICE *idx, CLAVE clave); #endif diff --git a/emufs/indices.c b/emufs/indices.c index 8766054..a099e13 100644 --- a/emufs/indices.c +++ b/emufs/indices.c @@ -1,8 +1,11 @@ #include "indices.h" #include "emufs.h" +#include "indice_b.h" -INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset) +static CLAVE obtenet_clave(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) { int len; INDICE *tmp; @@ -23,13 +26,17 @@ INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TI tmp->tipo = tipo; tmp->tipo_dato = tipo_dato; - + tmp->tam_bloque = tam_bloque; tmp->offset = offset; tmp->sig = NULL; switch (tipo) { - case IND_B_MAS: - /* llenar metodos */ + case IND_B: + emufs_indice_b_crear(tmp); + tmp->agregar_entrada = emufs_indice_b_insertar; + tmp->borrar_entrada = NULL; + tmp->existe_entrada = emufs_indice_b_buscar; + break; case IND_B_ASC: /* llenar metodos */ break; @@ -47,8 +54,17 @@ void emufs_indice_destruir(EMUFS *emu, INDICE *i) free(i); } +void emufs_indice_agregar(INDICE *primero, char *data, int ubicacion) +{ + INDICE *iter = primero; + + while (iter) { + iter->agregar_entrada(iter, obtenet_clave(iter, data), ubicacion); + iter = iter->sig; + } +} -CLAVE emufs_indice_obtenet_clave(INDICE *idx, char *data) +static CLAVE obtenet_clave(INDICE *idx, char *data) { CLAVE k; switch (idx->tipo_dato) { @@ -62,3 +78,25 @@ CLAVE emufs_indice_obtenet_clave(INDICE *idx, char *data) return k; } +int emufs_indice_es_menor(INDICE *idx, CLAVE c1, CLAVE c2) +{ + switch (idx->tipo_dato) { + case IDX_FLOAT: + return c1.f_clave < c2.f_clave; + case IDX_INT: + return c1.i_clave < c2.i_clave; + } + return 0; +} + +int emufs_indice_es_igual(INDICE *idx, CLAVE c1, CLAVE c2) +{ + switch (idx->tipo_dato) { + case IDX_FLOAT: + return c1.f_clave == c2.f_clave; + case IDX_INT: + return c1.i_clave == c2.i_clave; + } + return 0; +} + diff --git a/emufs/indices.h b/emufs/indices.h index 935bc6e..7e3d70a 100644 --- a/emufs/indices.h +++ b/emufs/indices.h @@ -5,9 +5,11 @@ #include #include +#define STRUCT_OFFSET(x, y) ((int)(&(x->y))-(int)(x)) + typedef struct _emu_fs_t EMUFS; -typedef enum {IND_B_MAS, IND_B_ASC} INDICE_TIPO; +typedef enum {IND_B, IND_B_ASC} INDICE_TIPO; typedef enum {IDX_FLOAT, IDX_INT} INDICE_TIPO_DATO; @@ -20,6 +22,7 @@ typedef struct _indices_h_ { INDICE_TIPO tipo; INDICE_TIPO_DATO tipo_dato; int offset; + unsigned int tam_bloque; /* debe ser multiplo de 512! */ /** Agrega la clave k de posicion location en el * indice de forma ordenada @@ -38,9 +41,13 @@ typedef struct _indices_h_ { struct _indices_h_ *sig; } INDICE; -INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset); +INDICE *emufs_indice_crear(EMUFS *emu, char *nombre, INDICE_TIPO tipo, INDICE_TIPO_DATO tipo_dato, unsigned int offset, unsigned tam_bloque); void emufs_indice_destruir(EMUFS *emu, INDICE *i); +void emufs_indice_agregar(INDICE *primero, char *data, int ubicacion); CLAVE emufs_indice_obtenet_clave(INDICE *idx, char *data); + +int emufs_indice_es_menor(INDICE *idx, CLAVE c1, CLAVE c2); +int emufs_indice_es_igual(INDICE *idx, CLAVE c1, CLAVE c2); #endif -- 2.43.0