/** Heap sort functions **/ static void heapify (void *base, int *h_size, int i, size_t size, int (*compar)(const void *, const void *)) { int left, right, max_or_min; left = 2 * i; right = 2 * i + 1; if ((left < *h_size) && (compar ((char *) base + left * size, (char *) base + i * size) > 0)) { max_or_min = left; } else { max_or_min = i; } if ((right < *h_size) && (compar ((char *) base + max_or_min * size, (char *) base + right * size) < 0)) { max_or_min = right; } if (max_or_min != i) { block_swap ((char *) base + i * size, (char *) base + max_or_min * size, size); heapify (base, h_size, max_or_min, size, compar); } return; }
int32_t hfile_swap(hfile_t *fp) { int32_t fd; meta_t *o; int8_t *ptr; int32_t len; if (!fp) return(-1); len = strlen(fp->name); ptr = fp->name + len; umask(0); do { fp->trailer->timestamp = time(NULL); snprintf(ptr,PATH_MAX - len,"%ld",fp->trailer->timestamp); fd = open(fp->name,O_WRONLY|O_APPEND|O_CREAT|O_EXCL,0644); } while (fd < 0); for (o = index_head(fp->metas); o != NULL; o = meta_next(o)) { o->offset = lseek(fd,0,SEEK_CUR); o->blocksize = block_swap(fd,o->offset,fp->blocks[o->id]); } fp->trailer->indexoffset = lseek(fd,0,SEEK_CUR); fp->trailer->indexsize = index_swap(fd,fp->trailer->indexoffset,fp->metas); fp->trailer->bloomoffset = lseek(fd,0,SEEK_CUR); fp->trailer->bloomsize = bloom_swap(fd,fp->trailer->bloomoffset,fp->bloom); fp->trailer->infooffset = lseek(fd,0,SEEK_CUR); fp->trailer->infosize = hinfo_swap(fd,fp->trailer->infooffset,fp->fileinfo); fp->trailer->version = hfile_version(NULL); htail_swap(fd,lseek(fd,0,SEEK_CUR),fp->trailer); close(fd); return(0); }
void heap_sort (void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { int h_size = nmemb, i; build_heap (base, &h_size, size, compar); for (i=nmemb-1; i>=0; i--) { block_swap (base + 0 * size, base + i * size, size); h_size--; heapify (base, &h_size, 0, size, compar); } return; }
/* Partition array */ static int partition_array (void *base, int lo, int high, size_t size, int (*compar)(const void *, const void *)) { int piv_index, i, j; char *piv_val; piv_val = malloc (sizeof (char) * size); piv_index = pivot_method (base, lo, high); /* TODO: Later we can use median as pivot, or other strategy */ piv_val = memcpy (piv_val, (char *) base + piv_index * size, size); block_swap ((char *) base + lo * size, (char *) base + piv_index * size, size); i = lo; j = high; while (i <= j) { while ((i <= high) && (compar ((char *) base + i * size, piv_val) <= 0)) { i++; } while (compar ((char *) base + j * size, piv_val) > 0) { j--; } if (i < j) { block_swap ((char *) base + i * size, (char *) base + j * size, size); } } block_swap ((char *) base + j * size, (char *) base + lo * size, size); free (piv_val); return j; }