static void abreviar_claves(INDICE *idx, B_NodoEntry *array, B_NodoHeader *header);
static void desabreviar_claves(INDICE *idx, B_NodoEntry *array, B_NodoHeader *header);
+int b_borrar_dup_clave(INDICE *idx, INDICE_DATO k, INDICE_DATO dato);
void emufs_indice_b_crear(INDICE *idx)
{
if (idx->tipo_dato == IDX_STRING) {
/* Tengo que sacar el texto repetido del archivo de textos */
- idx->emu_string->borrar_registro(idx->emu_string, clave);
+ idx->emu_string->borrar_registro(idx->emu_string, clave, dummy);
}
return 1;
} else {
return ret;
}
-int emufs_indice_b_borrar(INDICE *idx, CLAVE k)
+int emufs_indice_b_borrar(INDICE *idx, CLAVE k, INDICE_DATO dato)
{
/* Busco el nodo que contiene la clave,si es que esta existe */
char *nodo;
if (encontrado) {
PERR("Clave encontrada, borrando ...");
- fprintf(stderr, "La clave a borrar esta en el nodo %d\n", nodo_id);
- b_borrar_clave(idx, nodo, nodo_id, k);
+ fprintf(stderr, "%s: La clave a borrar esta en el nodo %d\n", idx->nombre, nodo_id);
+ if (idx->funcion != IND_PRIMARIO) {
+ /* Debo borrar primero la clave desde el archivo de
+ * claves repetidas, y si recien ahi me quedo sin claves,
+ * borrar la clave del arbol
+ */
+ PERR("Vamos a borrar duplicados");
+ encontrado = b_borrar_dup_clave(idx, claves[i].dato, dato);
+ fprintf(stderr, "Listo, encontrado = %d\n", encontrado);
+ }
+ if (encontrado) {
+ b_borrar_clave(idx, nodo, nodo_id, k);
+ }
} else {
PERR("Clave no encontrada");
}
{
FILE *fp;
char *out;
- B_NodoHeader header;
- B_NodoEntry *claves;
+ /*B_NodoHeader header;
+ B_NodoEntry *claves;*/
if (id < 0) return NULL;
static void b_grabar_nodo(INDICE *idx, int id, char *data)
{
FILE *fp;
- B_NodoHeader header;
- B_NodoEntry *claves;
+ /*B_NodoHeader header;
+ B_NodoEntry *claves;*/
/* Si las claves son de tipo string debo abreviar antes de guardar */
/* if (idx->tipo_dato == IDX_STRING) {
claves[i-1].hijo_derecho = hijo_izq;
claves[i].hijo_derecho = hijo_der;
}
- /*b_elegir_izquierdo(idx, nodo_header.hijo_izquierdo, hijo1);*/
b_actualizar_header(nodo, &nodo_header);
b_grabar_nodo(idx, nodo_id, nodo);
fprintf(stderr, "La clave esta en la pos = %d\n", pos);
if (header.hijo_izquierdo != -1) {
PERR("Nodo no es hoja, intercambio");
-/* if (pos == 0) {
- actual = b_leer_nodo(idx, nodo_header.hijo_izquierdo);
- else*/
actual = b_leer_nodo(idx, claves[pos].hijo_derecho);
actual_id = claves[pos].hijo_derecho;
p = claves[pos].hijo_derecho;
/* Se cumple la condicion de hijos? */
PERR("Dejo todo consistente");
fprintf(stderr, "Condicion : %d >= %d\n", header_actual.cant, MIN_HIJOS(idx));
- if (header_actual.cant >= MIN_HIJOS(idx)) {
+ if ((header_actual.cant >= MIN_HIJOS(idx)) && (actual_id != 0)) {
PERR("Borrar completo sin fundir");
return;
}
/* Tengo que pasar datos o fundir nodos :-( */
do {
padre_id = header.padre;
+ if (padre_id == -1) continue;
padre = b_leer_nodo(idx, padre_id);
b_leer_header(padre, &header_padre);
claves_padre = b_leer_claves(padre, &header_padre);
B_NodoHeader h_der, h_padre, h_nodo;
B_NodoEntry *c_der, *c_padre, *c_nodo;
+ PERR("Derecha 1");
b_leer_header(nodo, &h_nodo);
c_nodo = b_leer_claves(nodo, &h_nodo);
b_leer_header(der, &h_der);
b_leer_header(padre, &h_padre);
c_padre = b_leer_claves(padre, &h_padre);
+ PERR("Derecha 2");
c_nodo[h_nodo.cant] = c_padre[pos_clave+1];
c_nodo[h_nodo.cant].hijo_derecho = -1; /* XXX */
+ PERR("Derecha 3");
c_padre[pos_clave+1] = c_der[0];
c_padre[pos_clave+1].hijo_derecho = der_id;
/* Muevo las claves de derecho */
+ PERR("Derecha 4");
for(i=0; i<h_der.cant-1; i++) {
c_der[i] = c_der[i+1];
}
b_actualizar_header(der, &h_der);
b_actualizar_header(nodo, &h_nodo);
+ PERR("Derecha 5");
}
void b_pasar_clave_a_derecha(INDICE *idx, char *der, int der_id, char *padre, int padre_id, int padre_pos, B_NodoEntry entry)
if (k.i_clave == -1) PERR("ALGO NO GRABO BIEN!!");
} else {
/* Modifico el que ya existia! */
+ INDICE_DATO dummy;
error = 0;
idx->emu_mult->modificar_registro(idx->emu_mult,
k,
leido,
cant*sizeof(INDICE_DATO)+sizeof(int),
- &error
+ &error,
+ dummy
);
}
/* Clean up! */
* mas de 2 letras iguales, si no no gano nada y complica las cosas
*/
if (iguales > 1) {
+ INDICE_DATO dummy1;
sprintf(salvar, "%d|%s", iguales, resto);
free(actual);
error = 0;
- idx->emu_string->modificar_registro(idx->emu_string, array[i].clave, salvar, strlen(salvar)+1, &error);
+ idx->emu_string->modificar_registro(idx->emu_string, array[i].clave, salvar, strlen(salvar)+1, &error, dummy1);
} else {
free(primera);
primera = actual;
}
iguales = strtol(actual, &resto, 10);
if ((iguales > 0) && (*resto == '|')) {
+ INDICE_DATO dummy2;
strncpy(salvar, primera, iguales);
salvar[iguales] = '\0';
strcat(salvar, resto+1); /* +1 para saltar el separador */
- idx->emu_string->modificar_registro(idx->emu_string, array[i].clave, salvar, strlen(salvar)+1, &error);
+ idx->emu_string->modificar_registro(idx->emu_string, array[i].clave, salvar, strlen(salvar)+1, &error, dummy2);
free(actual);
} else {
free(primera);
return salida;
}
+int b_borrar_dup_clave(INDICE *idx, INDICE_DATO k_dato, INDICE_DATO dato)
+{
+ int cant, pos, i;
+ EMUFS_REG_SIZE tam;
+ int error=0;
+ INDICE_DATO *array;
+ INDICE_DATO dummy1;
+ char *leido;
+ CLAVE k;
+
+ /* Leo el contenido actual */
+ error = 0;
+ k.i_clave = k_dato.id;
+ leido = (char *)idx->emu_mult->leer_registro(idx->emu_mult, k, &tam, &error);
+
+ cant = *((int *)leido);
+
+ /* Obtengo un nuevo lugar para el dato nuevo */
+ array = (INDICE_DATO *)(leido+sizeof(int));
+
+ /* busco pos de dato en array */
+ for(pos=0; pos<cant; pos++) {
+ if (array[pos].id == dato.id) break;
+ }
+
+ for(i=pos; i<cant-1; i++)
+ array[pos] = array[pos+1];
+
+ cant--;
+
+ if (cant == 0) {
+ free(leido);
+ /* No tengo mas cosas en esta clave, la borro */
+ idx->emu_mult->borrar_registro(idx->emu_mult, k, dummy1);
+ return 0;
+ }
+
+ /* Quito el elemento */
+ leido = realloc(leido, sizeof(int)+cant*sizeof(INDICE_DATO));
+
+ /* Actualizo la cantidad */
+ (*((int *)leido)) = cant;
+
+ error = 0;
+ idx->emu_mult->modificar_registro(idx->emu_mult,
+ k,
+ leido,
+ cant*sizeof(INDICE_DATO)+sizeof(int),
+ &error,
+ dummy1
+ );
+
+ free(leido);
+
+ return cant;
+}
+