mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Allow a way to finely control the order of query results.
This commit is contained in:
parent
6080b734d6
commit
eea640c1ab
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user