int insersion(int argc, char* argv[]) { FILE* fd; char path[512]; TEntidad* entidad; TArchivo* arch; if(argc < 4) { printf("Argumentos invalidos\n"); return 1; } strcpy(path, argv[2]); strcat(path, ".dat"); fd = fopen(argv[3], "rb"); arch = Archivo_crear(path, SIZE_BLOQUE); while((entidad = leer_entidad(fd))) { if(Archivo_agregar_buf(arch, (uint8_t*) entidad, sizeof(int)+strlen(entidad->entidad)+1)) { printf("Error escribiendo\n"); printf(" >> Size: %u\n", sizeof(int)+strlen(entidad->entidad)+1); printf(" >> Entidad: {\n"); printf(" \t id: '%d'\n", entidad->id); printf(" \t entidad: '%s'\n", entidad->entidad); printf(" }\n"); free(entidad); fclose(fd); Archivo_destruir(arch); return 1; } free(entidad); } fclose(fd); Archivo_flush(arch); Archivo_destruir(arch); return 0; }
int main(int argc, char* argv[]){ MODE mode = WRITE; TArchivo* arch; if(argc >= 2){ if(!strcmp(argv[1], "-r")) mode = READ; } arch = Archivo_crear(TEST_PATH, BLOQUE_SIZE); switch(mode){ case READ:{ Archivo_bloque_leer(arch); uint8_t *buf; size_t size; while((buf = Archivo_get_buf(arch, &size))){ printf("%u '%s'\n", size, (char*) buf); free(buf); } break; } default:{ printf("Escribiendo\n"); int i = 0; for(i=0;i<TEST_STRING_LENGTH; i++){ if(! Archivo_agregar_buf(arch, (uint8_t*) strings[i], strlen(strings[i])+1)) printf("%d Pude agregar\n", i); } Archivo_flush(arch); break; } } Archivo_destruir(arch); return 0; }
int listado(int argc, char* argv[]) { uint8_t *buf; size_t size; TArchivo* arch; char path[512]; TEntidad* entidad; strcpy(path, argv[2]); strcat(path, ".dat"); arch = Archivo_crear(path, SIZE_BLOQUE); Archivo_bloque_leer(arch); while((buf = Archivo_get_buf(arch, &size))) { entidad = (TEntidad*) buf; printf("%u '%d,%s'\n", size, entidad->id, entidad->entidad); free(buf); } Archivo_destruir(arch); return 0; }
int busqueda(int argc, char* argv[]) { uint8_t *buf; size_t size; TArchivo* arch; char path[512]; TEntidad* entidad; int id; if(argc < 4) { printf("Argumentos invalidos\n"); return 1; } id = (int) atoi(argv[2]); strcpy(path, argv[3]); strcat(path, ".dat"); arch = Archivo_crear(path, SIZE_BLOQUE); Archivo_bloque_leer(arch); while((buf = Archivo_get_buf(arch, &size))) { entidad = (TEntidad*) buf; if(entidad->id == id) { printf("%u '%d,%s'\n", size, entidad->id, entidad->entidad); free(buf); break; } free(buf); } Archivo_destruir(arch); return 0; }
int replacememt_selection(char* in_file, char* tmp_name, size_t block_size, size_t array_size, TSortExternFunction cmp){ TArchivo *in, *arch_tmp; void** tmp_array; unsigned int pasada = 0; uint8_t *buf; size_t buf_size=0, largo_actual = 0, offset = 0;; char path[255] = {0}; //TArchivoReg* arch_tmp; TSortHelper *last = NULL; if(!in_file || !tmp_name || !block_size || !array_size) return 1; tmp_array = (void**) calloc(array_size, sizeof(void*)); sprintf(path, tmp_name, pasada); //arch_tmp = ArchivoReg_crear(path); arch_tmp = Archivo_crear(path, block_size); in = Archivo_crear(in_file, block_size); Archivo_bloque_leer(in); while( (buf = Archivo_get_buf(in, &buf_size)) ){ TSortHelper* tmp_sort = (TSortHelper*) calloc(1, sizeof(TSortHelper)); tmp_sort->size = buf_size; tmp_sort->buf = buf; tmp_sort->cmp = cmp; if(largo_actual >= array_size - offset){ if(last){ free(last->buf); free(last); } // El orden que se genera es de mayor a menor heapsort(tmp_array, largo_actual, &sort_helper_cmp); last = tmp_array[largo_actual-1]; //ArchivoReg_escribir(arch_tmp, last->buf, last->size); Archivo_agregar_buf(arch_tmp, last->buf, last->size); tmp_array[largo_actual-1] = NULL; largo_actual--; } if(last != NULL && cmp(last->buf, last->size, tmp_sort->buf, tmp_sort->size) < 0 ){ //El ultimo que se escribio en archivo es mayor al que se quiere escribir offset++; tmp_array[array_size-offset] = tmp_sort; if(offset == array_size){ //Ya esta todo dormido. Creo archivo nuevo //ArchivoReg_destruir(arch_tmp); Archivo_flush(arch_tmp); Archivo_destruir(arch_tmp); sprintf(path, tmp_name, ++pasada); //arch_tmp = ArchivoReg_crear(path); arch_tmp = Archivo_crear(path, block_size); offset = 0; largo_actual = array_size; } }else tmp_array[largo_actual++] = tmp_sort; } Archivo_destruir(in); free(last->buf); free(last); // Escribir las cosas que qedaron en el buffer a disco if(largo_actual){ size_t largo = largo_actual; heapsort(tmp_array, largo, &sort_helper_cmp); while(largo){ last = tmp_array[--largo]; //ArchivoReg_escribir(arch_tmp, last->buf, last->size); Archivo_agregar_buf(arch_tmp, last->buf, last->size); free(last->buf); free(last); } } //ArchivoReg_destruir(arch_tmp); Archivo_flush(arch_tmp); Archivo_destruir(arch_tmp); // Escribo los que quedaron dormidos en un nuevo archivo if(offset){ //void **offset_array = tmp_array + sizeof(void*) * largo_actual; void **offset_array = tmp_array + largo_actual; sprintf(path, tmp_name, ++pasada); //arch_tmp = ArchivoReg_crear(path); arch_tmp = Archivo_crear(path, block_size); heapsort(offset_array, offset, &sort_helper_cmp); while(offset){ last = offset_array[--offset]; //ArchivoReg_escribir(arch_tmp, last->buf, last->size); Archivo_agregar_buf(arch_tmp, last->buf, last->size); free(last->buf); free(last); } //ArchivoReg_destruir(arch_tmp); Archivo_flush(arch_tmp); Archivo_destruir(arch_tmp); } free(tmp_array); return pasada; }
int merge_externo(char* out_path, char* tmp_name, size_t block_size, size_t array_size, size_t desde, size_t hasta, TSortExternFunction cmp){ TMergeHelper** tmp_array; size_t i=0, es_ultimo = 0, real_array_size = array_size; char path[255] = {0}; TArchivo* out_file = NULL; if(!out_path || !tmp_name || !block_size || !array_size || hasta <= desde) return 1; if(hasta - desde +1 <= array_size){ real_array_size = array_size = hasta-desde+1; es_ultimo = 1; } printf("Mergeo desde %d hasta %d con array: %d\n", desde, hasta, array_size); tmp_array = (TMergeHelper**) calloc(array_size, sizeof(void*)); for(i=0; i < array_size; i++){ tmp_array[i] = (TMergeHelper*) calloc(1, sizeof(TMergeHelper)); tmp_array[i]->cmp = cmp; sprintf(path, tmp_name, desde+i); tmp_array[i]->arch = Archivo_crear(path, block_size); if(Archivo_bloque_leer(tmp_array[i]->arch)){ Archivo_destruir(tmp_array[i]->arch); array_size--; i--; continue; } Archivo_close(tmp_array[i]->arch); if(!(tmp_array[i]->buf = Archivo_get_bloque_buf(tmp_array[i]->arch, &(tmp_array[i]->size)))){ Archivo_destruir(tmp_array[i]->arch); array_size--; i--; continue; } } desde += array_size; sprintf(path, tmp_name, ++hasta); out_file = Archivo_crear((es_ultimo)? out_path : path, block_size); while(1){ //Cabeza mode: on heapsort((void**) tmp_array, array_size, &merge_helper_cmp); Archivo_agregar_buf(out_file, tmp_array[array_size-1]->buf, tmp_array[array_size-1]->size); free(tmp_array[array_size-1]->buf); if(! (tmp_array[array_size-1]->buf = Archivo_get_bloque_buf( tmp_array[array_size-1]->arch, &(tmp_array[array_size-1]->size) )) ){ // NULL leo siguiente bloque Archivo_open(tmp_array[array_size-1]->arch); if(Archivo_bloque_leer(tmp_array[array_size-1]->arch)){ //Se termino el archivo. Archivo_destruir(tmp_array[array_size-1]->arch); if(! (--array_size)) // No hay mas archivos break; }else{ Archivo_close(tmp_array[array_size-1]->arch); if(! (tmp_array[array_size-1]->buf = Archivo_get_bloque_buf( tmp_array[array_size-1]->arch, &(tmp_array[array_size-1]->size) ))) printf("Error muy loco, si pasa esto algo esta andando MUY mal\n"); } } } Archivo_flush(out_file); Archivo_destruir(out_file); for(i=0; i < real_array_size; i++) free(tmp_array[i]); free(tmp_array); if(es_ultimo) return 0; return merge_externo(out_path, tmp_name, block_size, real_array_size, desde, hasta, cmp); }