int heap_pop() { int i, x, y, z, l, r, res; res = heap[0]; x = heap[--hn]; i = 0; while (1) { l = i + i + 1; r = i + i + 2; z = x; if (l < hn) { y = heap[l]; if (record_cmp(&buf(y), &buf(z)) < 0) z = y; } if (r < hn) { y = heap[r]; if (record_cmp(&buf(y), &buf(z)) < 0) z = y; } if (z == x) break; heap[i] = z; i = (z == heap[l] ? l : r); } heap[i] = x; return res; }
void heap_push(int x) { int i, j, y; for (i = hn++; i; i = j) { j = (i - 1) >> 1; y = heap[j]; if (record_cmp(&buf(x), &buf(y)) >= 0) break; heap[i] = y; } heap[i] = x; }
/* check if the pages sorted */ int check_page(char *out) { int i, ok = 1, num, p, len, oft, *addr, c = 0; struct record *now, *pre; char path[L]; FILE *f; now = &buffer[0][0]; pre = &buffer[0][1]; sprintf(path, "%s.pages", out); chdir(path); pre->x = pre->y = 0; for (p = 0; ok; p++) { sprintf(path, "%s.%07d", out, p); f = fopen(path, "r"); if (!f) break; fread(buffer[1], 1, 1024, f); addr = (int *)((void *)buffer[1] + 1024); num = *--addr; for (i = 0; i < num && ok; i++) { oft = *--addr; len = *--addr; memcpy(path, (char *)buffer[1] + oft, len); path[len] = 0; sscanf(path, "%d%*c%d", &now->x, &now->y); c++; if (record_cmp(pre, now) > 0) { printf("(%d %d %d)\n", p, i, c); ok = 0; break; } *pre = *now; } fclose(f); } chdir(".."); return ok; }
/* check if the file sorted */ int check(FILE * f) { int i; struct line line; struct record *now, *pre; rewind(f); now = &buffer[0][0]; pre = &buffer[0][1]; for (i = 0; !feof(f); i++) { line_read(f, &line); now->x = line.x; now->y = line.y; if (i && record_cmp(pre, now) > 0) { printf("%d ", i); return 0; } *pre = *now; } return 1; }
static struct MNode * mnode_insert(struct MNode *root, struct MNode *node) { int s = 0; if (! root) return node; s = record_cmp(root->row, node->row); if (s < 0) { root->right = mnode_insert(root->right, node); } else if (s == 0) { if (root->level < node->level) root->right = mnode_insert(root->right, node); else root->left = mnode_insert(root->left, node); } else { root->left = mnode_insert(root->left, node); } return root; }
Datum btrecordcmp(PG_FUNCTION_ARGS) { PG_RETURN_INT32(record_cmp(fcinfo)); }
Datum record_ge(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(record_cmp(fcinfo) >= 0); }
Datum record_lt(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(record_cmp(fcinfo) < 0); }
int vos_sort_merge(struct Stmt *sort, struct LL *lsfile, struct Record **_all_rows, unsigned long all_n_row) { int s = 0; unsigned long n_row = 0; struct File *F = 0; struct MNode *root = 0; struct MNode *loser = 0; struct MNode *loser2 = 0; struct Record *rows = 0; struct Record *R = 0; struct Record *all_rows = (*_all_rows); s = stmtsort_init_output(sort); if (s) return s; /* in case of only one file to merge */ if (! lsfile->next) { s = single_merge(lsfile->str, sort->out->filename); return s; } s = file_open(&F, sort->out->filename, FOPEN_WO); if (s) goto err; s = merge_init(&root, lsfile, sort->out->fields); if (s) goto err; R = all_rows; all_rows = R->row_next; R->row_next = 0; R->row_last = 0; while (root) { loser2 = 0; loser = mnode_get_loser(&root, &loser2); if (loser2) { do { record_add_row(&rows, loser->row); n_row++; if (n_row >= all_n_row || ! all_rows) { s = record_write(rows, F, sort->out->fields); if (s) goto err; all_rows = rows; all_rows->row_last = 0; rows = 0; n_row = 0; } loser->row = R; R = all_rows; all_rows = R->row_next; R->row_next = 0; R->row_last = 0; s = record_read2(loser->row, loser->file, sort->out->fields); if (s) break; s = record_cmp(loser2->row, loser->row); } while (s > 0 || (s == 0 && loser2->level > loser->level)); } else { do { record_add_row(&rows, loser->row); n_row++; if (n_row >= all_n_row || ! all_rows) { s = record_write(rows, F, sort->out->fields); if (s) goto err; all_rows = rows; all_rows->row_last = 0; rows = 0; n_row = 0; } loser->row = R; R = all_rows; all_rows = R->row_next; R->row_next = 0; R->row_last = 0; s = record_read2(loser->row, loser->file, sort->out->fields); } while (s == 0); } if (s == E_FILE_END) mnode_destroy(&loser); else root = mnode_insert(root, loser); } R->row_next = all_rows; if (n_row) { s = record_write(rows, F, sort->out->fields); if (s) goto err; rows->row_last->row_next = R; (*_all_rows) = rows; } else { (*_all_rows) = R; } file_write(F); s = 0; err: mnode_destroy(&root); file_close(&F); return s; }