Allow a way to finely control the order of query results.

This commit is contained in:
terry%mozilla.org 1999-07-12 22:09:23 +00:00
parent 6080b734d6
commit eea640c1ab
4 changed files with 136 additions and 38 deletions

View File

@ -171,7 +171,7 @@ TDBCursor* tdbQueryNolock(TDB* db, TDBNodeRange range[3],
TDBSortSpecification* sortspec)
{
PRInt32 rangescore[3];
PRInt32 tree = -1;
PRInt32 tree;
PRInt32 curscore;
PRInt32 bestscore = -1;
PRInt32 i;
@ -191,31 +191,46 @@ TDBCursor* tdbQueryNolock(TDB* db, TDBNodeRange range[3],
result->range[i].max = tdbNodeDup(range[i].max);
if (result->range[i].max == NULL) goto FAIL;
}
}
rangescore[i] = 0;
if (range[i].min != NULL || range[i].max != NULL) {
/* Hey, some limitations were specified, we like this key some. */
rangescore[i]++;
if (range[i].min != NULL && range[i].max != NULL) {
/* Ooh, we were given both minimum and maximum, that's better
than only getting one.*/
for (tree = 0 ; tree < NUMTREES ; tree++) {
if (key[tree][0] == sortspec->keyorder[0] &&
key[tree][1] == sortspec->keyorder[1] &&
key[tree][2] == sortspec->keyorder[2]) {
break;
}
}
if (tree >= NUMTREES) {
/* The passed in keyorder was not valid (which, in fact, is the usual
case). Go find the best tree to use. */
for (i=0 ; i<3 ; i++) {
rangescore[i] = 0;
if (range[i].min != NULL || range[i].max != NULL) {
/* Hey, some limitations were specified, we like this key
some. */
rangescore[i]++;
if (tdbCompareNodes(range[i].min, range[i].max) == 0) {
/* Say! This key was exactly specified. We like it
best. */
if (range[i].min != NULL && range[i].max != NULL) {
/* Ooh, we were given both minimum and maximum, that's
better than only getting one.*/
rangescore[i]++;
if (tdbCompareNodes(range[i].min, range[i].max) == 0) {
/* Say! This key was exactly specified. We like it
best. */
rangescore[i]++;
}
}
}
}
}
for (i=0 ; i<NUMTREES ; i++) {
curscore = rangescore[key[i][0]] * 100 +
rangescore[key[i][1]] * 10 +
rangescore[key[i][2]];
if (bestscore < curscore) {
bestscore = curscore;
tree = i;
for (i=0 ; i<NUMTREES ; i++) {
curscore = rangescore[key[i][0]] * 100 +
rangescore[key[i][1]] * 10 +
rangescore[key[i][2]];
if (bestscore < curscore) {
bestscore = curscore;
tree = i;
}
}
}

View File

@ -89,6 +89,40 @@ typedef struct {
PRBool reverse; /* If true, then return biggest results
first. Otherwise, the smallest
stuff comes first. */
PRInt16 keyorder[3]; /* Specify which keys to sort in. If you use
this, then each of the three entries must
be a unique number between 0 and 2. For
example, if:
keyorder[0] == 1
keyorder[1] == 2
keyorder[2] == 0
then results will be returned sorted
primarily by the middle value of each
triple, with a secondary sort by the
third value and a tertiary sort by
the first value.
You are not guaranteed to get things in
this order; it is only a request. In
particular, in the current implementation,
if keyorder[2] == 1, your request will
be ignored.
If the values of keyorder[] are not
legitimately specified, then a default
order will be selected (the system will
pick the order it can do most
efficiently.)
Practically speaking, the only reason to
ever set the keyorder is if your request
only gives values for one of the ranges,
and you want to specify which order the
other fields should be sorted in. And
keyorder[0] had better specify which
entry is the non-NULL one, or things will
be very slow.
*/
} TDBSortSpecification;

View File

@ -171,7 +171,7 @@ TDBCursor* tdbQueryNolock(TDB* db, TDBNodeRange range[3],
TDBSortSpecification* sortspec)
{
PRInt32 rangescore[3];
PRInt32 tree = -1;
PRInt32 tree;
PRInt32 curscore;
PRInt32 bestscore = -1;
PRInt32 i;
@ -191,31 +191,46 @@ TDBCursor* tdbQueryNolock(TDB* db, TDBNodeRange range[3],
result->range[i].max = tdbNodeDup(range[i].max);
if (result->range[i].max == NULL) goto FAIL;
}
}
rangescore[i] = 0;
if (range[i].min != NULL || range[i].max != NULL) {
/* Hey, some limitations were specified, we like this key some. */
rangescore[i]++;
if (range[i].min != NULL && range[i].max != NULL) {
/* Ooh, we were given both minimum and maximum, that's better
than only getting one.*/
for (tree = 0 ; tree < NUMTREES ; tree++) {
if (key[tree][0] == sortspec->keyorder[0] &&
key[tree][1] == sortspec->keyorder[1] &&
key[tree][2] == sortspec->keyorder[2]) {
break;
}
}
if (tree >= NUMTREES) {
/* The passed in keyorder was not valid (which, in fact, is the usual
case). Go find the best tree to use. */
for (i=0 ; i<3 ; i++) {
rangescore[i] = 0;
if (range[i].min != NULL || range[i].max != NULL) {
/* Hey, some limitations were specified, we like this key
some. */
rangescore[i]++;
if (tdbCompareNodes(range[i].min, range[i].max) == 0) {
/* Say! This key was exactly specified. We like it
best. */
if (range[i].min != NULL && range[i].max != NULL) {
/* Ooh, we were given both minimum and maximum, that's
better than only getting one.*/
rangescore[i]++;
if (tdbCompareNodes(range[i].min, range[i].max) == 0) {
/* Say! This key was exactly specified. We like it
best. */
rangescore[i]++;
}
}
}
}
}
for (i=0 ; i<NUMTREES ; i++) {
curscore = rangescore[key[i][0]] * 100 +
rangescore[key[i][1]] * 10 +
rangescore[key[i][2]];
if (bestscore < curscore) {
bestscore = curscore;
tree = i;
for (i=0 ; i<NUMTREES ; i++) {
curscore = rangescore[key[i][0]] * 100 +
rangescore[key[i][1]] * 10 +
rangescore[key[i][2]];
if (bestscore < curscore) {
bestscore = curscore;
tree = i;
}
}
}

View File

@ -89,6 +89,40 @@ typedef struct {
PRBool reverse; /* If true, then return biggest results
first. Otherwise, the smallest
stuff comes first. */
PRInt16 keyorder[3]; /* Specify which keys to sort in. If you use
this, then each of the three entries must
be a unique number between 0 and 2. For
example, if:
keyorder[0] == 1
keyorder[1] == 2
keyorder[2] == 0
then results will be returned sorted
primarily by the middle value of each
triple, with a secondary sort by the
third value and a tertiary sort by
the first value.
You are not guaranteed to get things in
this order; it is only a request. In
particular, in the current implementation,
if keyorder[2] == 1, your request will
be ignored.
If the values of keyorder[] are not
legitimately specified, then a default
order will be selected (the system will
pick the order it can do most
efficiently.)
Practically speaking, the only reason to
ever set the keyorder is if your request
only gives values for one of the ranges,
and you want to specify which order the
other fields should be sorted in. And
keyorder[0] had better specify which
entry is the non-NULL one, or things will
be very slow.
*/
} TDBSortSpecification;