4 #define FILENAME "b.idx"
7 /* Cantidad de claves por nodo */
8 #define CANT_HIJOS ((BLOCK_SIZE-sizeof(B_NodoHeader))/sizeof(B_NodoEntry))
9 #define CANT_NODOS (CANT_HIJOS+1)
10 #define MIN_HIJOS (CANT_HIJOS/2)
13 static void b_grabar_nodo(int id, char *data);
14 static int b_ultimo_id();
15 static char *b_leer_nodo(int id);
16 static char *b_crear_nodo();
17 static void b_leer_header(char *src, B_NodoHeader *header);
18 static void b_actualizar_header(char *src, B_NodoHeader *header);
19 static B_NodoEntry *b_leer_claves(char *src, B_NodoHeader *header);
20 static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2);
21 const int b_elegir_izquierdo(int a, int b);
32 header.hijo_izquierdo = -1;
34 fp = fopen(FILENAME, "w");
36 /* Creo el archivo con el Nodo raiz */
37 bloque = (char *)malloc(BLOCK_SIZE);
38 memset(bloque, -1, BLOCK_SIZE);
40 memcpy(bloque, &header, sizeof(B_NodoHeader));
42 fwrite(bloque, BLOCK_SIZE, 1, fp);
46 int b_insertar(int clave, int ubicacion)
48 int i, nodo_id, padre_id;
54 nodo = b_leer_nodo(0);
55 padre_id = nodo_id = 0;
58 if (padre) free(padre);
61 b_leer_header(nodo, &header);
62 claves = b_leer_claves(nodo, &header);
64 while ((i<header.cant) && (claves[i].clave < clave)) i++;
65 if ((i<header.cant) && (claves[i].clave == clave)) {
66 /* CLAVE DUPLICADA! */
70 if (header.nivel != 0) {
71 nodo = b_leer_nodo(header.hijo_izquierdo);
72 nodo_id = header.hijo_izquierdo;
78 if (header.nivel != 0) {
79 nodo = b_leer_nodo(claves[i-1].ubicacion);
80 nodo_id = claves[i-1].ubicacion;
92 b_insertar_en_nodo(clave, ubicacion, nodo_id, nodo, -1, -1);
93 return 1; /* Agregar OK! */
96 int b_buscar(int clave)
104 nodo = b_leer_nodo(0);
106 b_leer_header(nodo, &header);
107 claves = b_leer_claves(nodo, &header);
109 while ((i<header.cant) && (claves[i].clave < clave)) i++;
110 if (claves[i].clave == clave) {
111 ret = claves[i].ubicacion;
117 nodo = b_leer_nodo(header.hijo_izquierdo);
118 printf("Me voy a izquierda = %d\n", header.hijo_izquierdo);
120 nodo = b_leer_nodo(claves[i-1].ubicacion);
121 printf("Me voy a hijo=%li\n", claves[i-1].ubicacion);
127 /* Nodo no encontrado */
131 static int b_ultimo_id()
135 fp = fopen(FILENAME, "r");
136 fseek(fp, 0, SEEK_END);
137 i = ftell(fp)/BLOCK_SIZE;
143 static char *b_crear_nodo(int *id)
148 (*id) = b_ultimo_id();
150 printf("Nuevo nodo creado : id = %d\n", *id);
153 header.hijo_izquierdo = -1;
156 bloque = (char *)malloc(BLOCK_SIZE);
157 memset(bloque, -1, BLOCK_SIZE);
158 memcpy(bloque, &header, sizeof(B_NodoHeader));
160 b_grabar_nodo(*id, bloque);
165 static char *b_leer_nodo(int id)
170 if (id < 0) return NULL;
172 fp = fopen(FILENAME, "r");
173 if (fp == NULL) return NULL;
175 fseek(fp, id*BLOCK_SIZE, SEEK_SET);
177 out = (char *)malloc(BLOCK_SIZE);
183 if (fread(out, 1, BLOCK_SIZE, fp) != BLOCK_SIZE) {
185 /* No se puso leer el nodo */
194 static void b_grabar_nodo(int id, char *data)
198 /* if (id > b_ultimo_id()) {
199 printf("AGREGANDO AL FINAL\n");
200 fp = fopen(FILENAME, "a");
202 _("No se pudo abrir archivo\n");
206 fp = fopen(FILENAME, "w");
208 _("No se pudo abrir archivo\n");
211 fseek(fp, id*BLOCK_SIZE, SEEK_SET);
212 printf("SOLO GUARDO DATA\n");
215 fp = fopen(FILENAME, "r+");
216 fseek(fp, id*BLOCK_SIZE, SEEK_SET);
217 fwrite(data, 1, BLOCK_SIZE, fp);
221 static void b_leer_header(char *src, B_NodoHeader *header)
225 memcpy(header, src, sizeof(B_NodoHeader));
228 static void b_actualizar_header(char *src, B_NodoHeader *header)
231 memcpy(src, header, sizeof(B_NodoHeader));
234 static B_NodoEntry *b_leer_claves(char *src, B_NodoHeader *header)
236 return (B_NodoEntry *)(src+sizeof(B_NodoHeader));
239 static void b_insertar_en_nodo(int clave, int ubicacion, int nodo_id, char *nodo, int hijo1, int hijo2)
246 B_NodoHeader nodo_header, nuevo_header;
247 B_NodoEntry *claves, *tmp_claves, *claves_nuevo;
252 nodo = b_crear_nodo(&nodo_id);
254 b_leer_header(nodo, &nodo_header);
255 claves = b_leer_claves(nodo, &nodo_header);
257 padre = b_leer_nodo(nodo_header.padre);
259 if (nodo_header.cant == CANT_HIJOS) {
261 nuevo = b_crear_nodo(&nuevo_id);
263 /* Creo una lista ordenada de los nodos a partir */
264 tmp_claves = (B_NodoEntry *)malloc(sizeof(B_NodoEntry)*(nodo_header.cant+1));
265 total = nodo_header.cant;
266 while ((i<nodo_header.cant) && (claves[i].clave < clave)) {
267 tmp_claves[i] = claves[i];
270 tmp_claves[i].clave = clave;
271 tmp_claves[i].ubicacion = ubicacion;
272 while (i < nodo_header.cant) {
273 tmp_claves[i+1] = claves[i];
277 /* Asigno a cada nodo lo que corresponde */
278 b_leer_header(nuevo, &nuevo_header);
280 nuevo_header.nivel = nodo_header.nivel;
281 nodo_header.cant = total/2;
282 nuevo_header.cant = total - nodo_header.cant;
284 memset(claves, '*', BLOCK_SIZE-sizeof(B_NodoHeader));
285 for(j=0; j<nodo_header.cant; j++)
286 claves[j] = tmp_claves[j];
288 claves_nuevo = b_leer_claves(nuevo, &nuevo_header);
289 memset(claves_nuevo, '*', BLOCK_SIZE-sizeof(B_NodoHeader));
290 for(j=0; j<nuevo_header.cant; j++)
291 claves_nuevo[j] = tmp_claves[j+total/2+1];
293 b_actualizar_header(nodo, &nodo_header);
294 b_actualizar_header(nuevo, &nuevo_header);
297 clave = tmp_claves[total/2].clave;
298 ubicacion = nuevo_id;
300 b_grabar_nodo(nodo_id, nodo);
301 b_grabar_nodo(nuevo_id, nuevo);
310 nodo_id = nodo_header.padre;
312 /* Oops, parti el raiz, y este debe quedar en 0, lo paso a otro bloque
313 * y dejo el padre vacio
315 char *tmp_nuevo = b_crear_nodo(&nodo_id);
316 memcpy(tmp_nuevo, nodo, BLOCK_SIZE);
320 clave = tmp_claves[total/2].clave;
321 ubicacion = nuevo_id;
323 b_grabar_nodo(nuevo_id+1, nodo);
324 b_grabar_nodo(nuevo_id, nuevo);
333 /* Limpio al padre */
334 nuevo = b_leer_nodo(0);
336 b_leer_header(nuevo, &nuevo_header);
337 nuevo_header.cant = 0;
338 nuevo_header.padre = -1;
339 nuevo_header.nivel = nodo_header.nivel+1;
340 memset(nuevo, -1, BLOCK_SIZE);
341 b_actualizar_header(nuevo, &nuevo_header);
342 b_grabar_nodo(0, nuevo);
349 /* La clave entra en este nodo!! */
351 if (nodo_header.cant > 0) {
352 while ((claves[i].clave < clave) && (i < nodo_header.cant)) i++;
353 for(j=nodo_header.cant; j > i; j--)
354 claves[j] = claves[j-1];
357 claves[i].clave = clave;
358 claves[i].ubicacion = ubicacion;
359 nodo_header.hijo_izquierdo = b_elegir_izquierdo(nodo_header.hijo_izquierdo, hijo1);
361 b_actualizar_header(nodo, &nodo_header);
362 b_grabar_nodo(nodo_id, nodo);
364 /* Debo actualizar los punteros al padre de los hijos */
366 nuevo = b_leer_nodo(hijo1);
368 b_leer_header(nuevo, &nuevo_header);
369 nuevo_header.padre = nodo_id;
370 b_actualizar_header(nuevo, &nuevo_header);
371 b_grabar_nodo(hijo1, nuevo);
373 } else printf("FUCK! hijo1=%d no existe!\n", hijo1);
376 nuevo = b_leer_nodo(hijo2);
378 b_leer_header(nuevo, &nuevo_header);
379 nuevo_header.padre = nodo_id;
380 b_actualizar_header(nuevo, &nuevo_header);
381 b_grabar_nodo(hijo2, nuevo);
383 } else printf("FUCK! hijo2=%d no existe!\n", hijo2);
390 const int b_elegir_izquierdo(int a, int b)
394 B_NodoHeader header1, header2;
395 B_NodoEntry *claves1, *claves2;
400 nodo1 = b_leer_nodo(a);
401 nodo2 = b_leer_nodo(b);
403 b_leer_header(nodo1, &header1);
404 b_leer_header(nodo2, &header2);
406 claves1 = b_leer_claves(nodo1, &header1);
407 claves2 = b_leer_claves(nodo2, &header2);
409 if (claves1[0].clave < claves2[0].clave)