void dbSelection::sort(dbDatabase* db, dbOrderByNode* order) { size_t n = nRows; if (n <= 1) { return; } TRACE_MSG(("Sort %d records\n", n)); ObjectRef* refs = new ObjectRef[n]; segment *seg; int k = 0; for (seg = first; seg != NULL; seg = seg->next) { for (int i = 0, nr = seg->nRows; i < nr; i++) { refs[k++].oid = seg->rows[i]; } } dbSortContext ctx; ctx.order = order; sortThreadContext.set(&ctx); iqsort(refs, n); k = 0; for (seg = first; seg != NULL; seg = seg->next) { for (int i = 0, nr = seg->nRows; i < nr; i++) { seg->rows[i] = refs[k++].oid; } } delete[] refs; }
void dbSelection::sort(dbDatabase* db, dbOrderByNode* order) { size_t n = nRows; if (n <= 1) { return; } TRACE_MSG(("Sort %d records\n", n)); oid_t* oids = new oid_t[n]; toArray(oids); dbSortContext ctx; ctx.order = order; sortThreadContext.set(&ctx); qsort(oids, n, sizeof(oid_t), &compareRecords); oid_t* p = oids; for (segment *seg = first; seg != NULL; seg = seg->next) { for (int i = 0, n = seg->nRows; i < n; i++) { seg->rows[i] = *p++; } } }
void dbSelection::sort(dbDatabase* db, dbOrderByNode* order) { int i, j, k, n = nRows; dbSortRecord* keys = new dbSortRecord[n]; segment* seg = first; dbGetTie tie; byte* p; int offs = order->field->dbsOffs; TRACE_MSG(("Sort %d records\n", n)); switch (order->field->type) { case dbField::tpBool: case dbField::tpInt1: for (i = 0; seg != NULL; seg = seg->next) { for (j = 0, k = seg->nRows; j < k; j++, i++) { p = (byte*)db->getRow(tie, seg->rows[j]); int4 val = *(int1*)(p + offs); keys[i].high = order->ascent ? val : -val; keys[i].low = 0; keys[i].oid = seg->rows[j]; } } qsort(keys, n, sizeof(dbSortRecord), cmpIntKey); break; case dbField::tpInt2: for (i = 0; seg != NULL; seg = seg->next) { for (j = 0, k = seg->nRows; j < k; j++, i++) { p = (byte*)db->getRow(tie, seg->rows[j]); int4 val = *(int2*)(p + offs); keys[i].high = order->ascent ? val : -val; keys[i].low = 0; keys[i].oid = seg->rows[j]; } } qsort(keys, n, sizeof(dbSortRecord), cmpIntKey); break; case dbField::tpInt4: case dbField::tpReal4: case dbField::tpArray: for (i = 0; seg != NULL; seg = seg->next) { for (j = 0, k = seg->nRows; j < k; j++, i++) { p = (byte*)db->getRow(tie, seg->rows[j]); int4 val = *(int4*)(p + offs); keys[i].high = order->ascent ? val : -val; keys[i].low = 0; keys[i].oid = seg->rows[j]; } } qsort(keys, n, sizeof(dbSortRecord), cmpIntKey); break; case dbField::tpInt8: case dbField::tpReal8: for (i = 0; seg != NULL; seg = seg->next) { for (j = 0, k = seg->nRows; j < k; j++, i++) { p = (byte*)db->getRow(tie, seg->rows[j]); int8 val = *(int8*)(p + offs); if (!order->ascent) { val = -val; } keys[i].high = int8_high_part(val); keys[i].low = int8_low_part(val); keys[i].oid = seg->rows[j]; } } qsort(keys, n, sizeof(dbSortRecord), cmpLongKey); break; case dbField::tpString: for (i = 0; seg != NULL; seg = seg->next) { for (j = 0, k = seg->nRows; j < k; j++, i++) { byte* p = (byte*)db->getRow(tie, seg->rows[j]); int8 val = packStrKey(p + ((dbVarying*)(p + offs))->offs); if (!order->ascent) { val = -val; } keys[i].high = int8_high_part(val); keys[i].low = int8_low_part(val); keys[i].oid = seg->rows[j]; } } qsort(keys, n, sizeof(dbSortRecord), cmpLongKey); break; default: assert(false); } if (order->next != NULL || order->field->type == dbField::tpString) { dbSortContext ctx; ctx.db = db; ctx.order = order; sortThreadContext.set(&ctx); for (i = 0, k = 0; i < n; i = j) { for (j = i+1; j < n && keys[j].high == keys[i].high && keys[j].low == keys[i].low; j++); if (j > i + 1) { qsort(keys + i, j - i, sizeof(dbSortRecord), exactKeyCmp); } } } if (n != 0) { for (i = 0, j = 0, seg = first, k = seg->nRows; i < n; i++, j++) { if (j == k) { seg = seg->next; k = seg->nRows; j = 0; } seg->rows[j] = keys[i].oid; } } delete[] keys; }