Beispiel #1
0
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;
}
Beispiel #2
0
int dbSelection::exactKeyCmp(void const* a, void const* b) 
{
    dbGetTie ta, tb;
    dbSortContext* ctx = sortThreadContext.get();
    return compare(ctx->db->getRow(ta, ((dbSortRecord*)a)->oid),
		   ctx->db->getRow(tb, ((dbSortRecord*)b)->oid),
		   ctx->order);				
}
Beispiel #3
0
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++;
        }
    }
}
Beispiel #4
0
 static int compare(ObjectRef* a, ObjectRef* b) { 
     dbSortContext* ctx = sortThreadContext.get();
     return dbSelection::compare(a->oid, b->oid, ctx->order);
 }
Beispiel #5
0
static int compareRecords(void const* a, void const* b)
{
    dbSortContext* ctx = sortThreadContext.get();
    return dbSelection::compare(*(oid_t*)a, *(oid_t*)b, ctx->order);
}
Beispiel #6
0
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;
}