Changeset: 5ba4400fec07 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5ba4400fec07 Modified Files: gdk/gdk_firstn.c gdk/gdk_qsort.c Branch: default Log Message:
Properly do floating point comparisons which may include NIL (NaN). We can't compare NILs with anything, but we must maintain the illusion that they are smaller than anything else. diffs (166 lines): diff --git a/gdk/gdk_firstn.c b/gdk/gdk_firstn.c --- a/gdk/gdk_firstn.c +++ b/gdk/gdk_firstn.c @@ -87,12 +87,26 @@ siftup(OPER, i - 1, SWAP); \ } while (0) -#define LTany(p1, p2) (cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ +#define LTany(p1, p2) (cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ BUNtail(bi, oids[p2] - b->hseqbase)) < 0) -#define GTany(p1, p2) (cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ +#define GTany(p1, p2) (cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ BUNtail(bi, oids[p2] - b->hseqbase)) > 0) -#define LTfix(p1, p2) (vals[oids[p1] - b->hseqbase] < vals[oids[p2] - b->hseqbase]) -#define GTfix(p1, p2) (vals[oids[p1] - b->hseqbase] > vals[oids[p2] - b->hseqbase]) +#define LTflt(a, b) ((bit) (!is_flt_nil(b) && (is_flt_nil(a) || (a) < (b)))) +#define LTdbl(a, b) ((bit) (!is_dbl_nil(b) && (is_dbl_nil(a) || (a) < (b)))) +#define GTflt(a, b) ((bit) (!is_flt_nil(a) && (is_flt_nil(b) || (a) > (b)))) +#define GTdbl(a, b) ((bit) (!is_dbl_nil(a) && (is_dbl_nil(b) || (a) > (b)))) +#define LTfltfix(p1, p2) LTflt(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) +#define GTfltfix(p1, p2) GTflt(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) +#define LTdblfix(p1, p2) LTdbl(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) +#define GTdblfix(p1, p2) GTdbl(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) +#define LTfix(p1, p2) LT(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) +#define GTfix(p1, p2) GT(vals[oids[p1] - b->hseqbase], \ + vals[oids[p2] - b->hseqbase]) #define SWAP1(p1, p2) \ do { \ item = oids[p1]; \ @@ -248,10 +262,10 @@ BATfirstn_unique(BAT *b, BAT *s, BUN n, break; #endif case TYPE_flt: - shuffle_unique(flt, LT); + shuffle_unique(flt, LTflt); break; case TYPE_dbl: - shuffle_unique(dbl, LT); + shuffle_unique(dbl, LTdbl); break; default: heapify(LTany, SWAP1); @@ -285,10 +299,10 @@ BATfirstn_unique(BAT *b, BAT *s, BUN n, break; #endif case TYPE_flt: - shuffle_unique(flt, GT); + shuffle_unique(flt, GTflt); break; case TYPE_dbl: - shuffle_unique(dbl, GT); + shuffle_unique(dbl, GTdbl); break; default: heapify(GTany, SWAP1); @@ -316,14 +330,30 @@ BATfirstn_unique(BAT *b, BAT *s, BUN n, return bn; } -#define LTfixgrp(p1, p2) \ - (goids[p1] < goids[p2] || \ - (goids[p1] == goids[p2] && \ - vals[oids[p1] - b->hseqbase] < vals[oids[p2] - b->hseqbase])) -#define GTfixgrp(p1, p2) \ - (goids[p1] < goids[p2] || \ - (goids[p1] == goids[p2] && \ - vals[oids[p1] - b->hseqbase] > vals[oids[p2] - b->hseqbase])) +#define LTfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + LTfix(p1, p2))) +#define LTfltfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + LTfltfix(p1, p2))) +#define LTdblfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + LTdblfix(p1, p2))) +#define GTfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + GTfix(p1, p2))) +#define GTfltfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + GTfltfix(p1, p2))) +#define GTdblfixgrp(p1, p2) \ + (goids[p1] < goids[p2] || \ + (goids[p1] == goids[p2] && \ + GTdblfix(p1, p2))) #define LTvoidgrp(p1, p2) \ (goids[p1] < goids[p2] || \ (goids[p1] == goids[p2] && oids[p1] < oids[p2])) @@ -333,13 +363,11 @@ BATfirstn_unique(BAT *b, BAT *s, BUN n, #define LTanygrp(p1, p2) \ (goids[p1] < goids[p2] || \ (goids[p1] == goids[p2] && \ - cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ - BUNtail(bi, oids[p2] - b->hseqbase)) < 0)) + LTany(p1, p2))) #define GTanygrp(p1, p2) \ (goids[p1] < goids[p2] || \ (goids[p1] == goids[p2] && \ - cmp(BUNtail(bi, oids[p1] - b->hseqbase), \ - BUNtail(bi, oids[p2] - b->hseqbase)) > 0)) + GTany(p1, p2))) #define SWAP2(p1, p2) \ do { \ item = oids[p1]; \ @@ -475,10 +503,10 @@ BATfirstn_unique_with_groups(BAT *b, BAT break; #endif case TYPE_flt: - shuffle_unique_with_groups(flt, LT); + shuffle_unique_with_groups(flt, LTflt); break; case TYPE_dbl: - shuffle_unique_with_groups(dbl, LT); + shuffle_unique_with_groups(dbl, LTdbl); break; default: heapify(LTanygrp, SWAP2); @@ -530,10 +558,10 @@ BATfirstn_unique_with_groups(BAT *b, BAT break; #endif case TYPE_flt: - shuffle_unique_with_groups(flt, GT); + shuffle_unique_with_groups(flt, GTflt); break; case TYPE_dbl: - shuffle_unique_with_groups(dbl, GT); + shuffle_unique_with_groups(dbl, GTdbl); break; default: heapify(GTanygrp, SWAP2); diff --git a/gdk/gdk_qsort.c b/gdk/gdk_qsort.c --- a/gdk/gdk_qsort.c +++ b/gdk/gdk_qsort.c @@ -204,8 +204,8 @@ struct qsort_t { #undef LT #define GDKqsort_impl GDKqsort_impl_flt_rev -#define LE(i, j) (((flt *) h)[i] >= ((flt *) h)[j]) -#define LT(i, j) (((flt *) h)[i] > ((flt *) h)[j]) +#define LE(i, j) (is_flt_nil(((flt *)h)[j]) || (!is_flt_nil(((flt *)h)[i]) && ((flt *)h)[i] >= ((flt *)h)[j])) +#define LT(i, j) (!is_flt_nil(((flt *)h)[i]) && (is_flt_nil(((flt *)h)[j]) || ((flt *)h)[i] > ((flt *)h)[j])) #include "gdk_qsort_impl.h" #undef GDKqsort_impl #undef LE @@ -231,8 +231,8 @@ struct qsort_t { #undef LT #define GDKqsort_impl GDKqsort_impl_dbl_rev -#define LE(i, j) (((dbl *) h)[i] >= ((dbl *) h)[j]) -#define LT(i, j) (((dbl *) h)[i] > ((dbl *) h)[j]) +#define LE(i, j) (is_dbl_nil(((dbl *)h)[j]) || (!is_dbl_nil(((dbl *)h)[i]) && ((dbl *)h)[i] >= ((dbl *)h)[j])) +#define LT(i, j) (!is_dbl_nil(((dbl *)h)[i]) && (is_dbl_nil(((dbl *)h)[j]) || ((dbl *)h)[i] > ((dbl *)h)[j])) #include "gdk_qsort_impl.h" #undef GDKqsort_impl #undef LE _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list