add _last, _prev, and _seek for dbiterators

This commit is contained in:
Bob Halley
1999-09-02 16:43:45 +00:00
parent d92543b360
commit 065273f52a
4 changed files with 257 additions and 5 deletions

View File

@@ -64,6 +64,7 @@ typedef struct dbinfo {
dns_dbiterator_t * dbiterator;
dns_dbversion_t * iversion;
int pause_every;
isc_boolean_t ascending;
ISC_LINK(struct dbinfo) link;
} dbinfo;
@@ -73,6 +74,7 @@ static dns_dbtable_t * dbtable;
static ISC_LIST(dbinfo) dbs;
static dbinfo * cache_dbi = NULL;
static int pause_every = 0;
static isc_boolean_t ascending = ISC_TRUE;
static void
print_result(char *message, isc_result_t result) {
@@ -158,13 +160,17 @@ select_db(char *origintext) {
}
static void
list(dbinfo *dbi) {
list(dbinfo *dbi, char *seektext) {
dns_fixedname_t fname;
dns_name_t *name;
dns_dbnode_t *node;
dns_rdatasetiter_t *rdsiter;
isc_result_t result;
int i;
size_t len;
dns_fixedname_t fseekname;
dns_name_t *seekname;
isc_buffer_t source;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -181,8 +187,27 @@ list(dbinfo *dbi) {
result = dns_db_createiterator(dbi->db, ISC_FALSE,
&dbi->dbiterator);
if (result == DNS_R_SUCCESS)
result = dns_dbiterator_first(dbi->dbiterator);
if (result == DNS_R_SUCCESS) {
if (seektext != NULL) {
len = strlen(seektext);
isc_buffer_init(&source, seektext, len,
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&source, len);
dns_fixedname_init(&fseekname);
seekname = dns_fixedname_name(&fseekname);
result = dns_name_fromtext(seekname, &source,
dns_rootname,
ISC_FALSE,
NULL);
if (result == ISC_R_SUCCESS)
result = dns_dbiterator_seek(
dbi->dbiterator,
seekname);
} else if (dbi->ascending)
result = dns_dbiterator_first(dbi->dbiterator);
else
result = dns_dbiterator_last(dbi->dbiterator);
}
} else
result = DNS_R_SUCCESS;
@@ -202,7 +227,10 @@ list(dbinfo *dbi) {
print_rdatasets(name, rdsiter);
dns_rdatasetiter_destroy(&rdsiter);
dns_db_detachnode(dbi->db, &node);
result = dns_dbiterator_next(dbi->dbiterator);
if (dbi->ascending)
result = dns_dbiterator_next(dbi->dbiterator);
else
result = dns_dbiterator_prev(dbi->dbiterator);
i++;
if (result == DNS_R_SUCCESS && i == dbi->pause_every) {
printf("[more...]\n");
@@ -244,6 +272,7 @@ load(char *filename, char *origintext, isc_boolean_t cache) {
dbi->dbiterator = NULL;
dbi->iversion = NULL;
dbi->pause_every = pause_every;
dbi->ascending = ascending;
len = strlen(origintext);
isc_buffer_init(&source, origintext, len, ISC_BUFFERTYPE_TEXT);
@@ -618,9 +647,13 @@ main(int argc, char *argv[]) {
((options & DNS_DBFIND_NOWILD) == 0) ?
"TRUE" : "FALSE");
continue;
} else if (strstr(s, "!LS ") == s) {
DBI_CHECK(dbi);
list(dbi, &s[4]);
continue;
} else if (strcmp(s, "!LS") == 0) {
DBI_CHECK(dbi);
list(dbi);
list(dbi, NULL);
continue;
} else if (strstr(s, "!DU ") == s) {
DBI_CHECK(dbi);
@@ -643,6 +676,14 @@ main(int argc, char *argv[]) {
v = atoi(&s[2]);
dbi->pause_every = v;
continue;
} else if (strcmp(s, "!+") == 0) {
DBI_CHECK(dbi);
dbi->ascending = ISC_TRUE;
continue;
} else if (strcmp(s, "!-") == 0) {
DBI_CHECK(dbi);
dbi->ascending = ISC_FALSE;
continue;
} else if (strcmp(s, "!DB") == 0) {
dbi = NULL;
origin = dns_rootname;

View File

@@ -49,6 +49,39 @@ dns_dbiterator_first(dns_dbiterator_t *iterator) {
return (iterator->methods->first(iterator));
}
dns_result_t
dns_dbiterator_last(dns_dbiterator_t *iterator) {
/*
* Move the node cursor to the first node in the database (if any).
*/
REQUIRE(DNS_DBITERATOR_VALID(iterator));
return (iterator->methods->last(iterator));
}
dns_result_t
dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
/*
* Move the node cursor to the node with name 'name'.
*/
REQUIRE(DNS_DBITERATOR_VALID(iterator));
return (iterator->methods->seek(iterator, name));
}
dns_result_t
dns_dbiterator_prev(dns_dbiterator_t *iterator) {
/*
* Move the node cursor to the previous node in the database (if any).
*/
REQUIRE(DNS_DBITERATOR_VALID(iterator));
return (iterator->methods->prev(iterator));
}
dns_result_t
dns_dbiterator_next(dns_dbiterator_t *iterator) {
/*

View File

@@ -76,6 +76,9 @@ ISC_LANG_BEGINDECLS
typedef struct dns_dbiteratormethods {
void (*destroy)(dns_dbiterator_t **iteratorp);
dns_result_t (*first)(dns_dbiterator_t *iterator);
dns_result_t (*last)(dns_dbiterator_t *iterator);
dns_result_t (*seek)(dns_dbiterator_t *iterator, dns_name_t *name);
dns_result_t (*prev)(dns_dbiterator_t *iterator);
dns_result_t (*next)(dns_dbiterator_t *iterator);
dns_result_t (*current)(dns_dbiterator_t *iterator,
dns_dbnode_t **nodep, dns_name_t *name);
@@ -136,6 +139,54 @@ dns_dbiterator_first(dns_dbiterator_t *iterator);
* Other results are possible, depending on the DB implementation.
*/
dns_result_t
dns_dbiterator_last(dns_dbiterator_t *iterator);
/*
* Move the node cursor to the last node in the database (if any).
*
* Requires:
* 'iterator' is a valid iterator.
*
* Returns:
* DNS_R_SUCCESS
* DNS_R_NOMORE There are no nodes in the database.
*
* Other results are possible, depending on the DB implementation.
*/
dns_result_t
dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name);
/*
* Move the node cursor to the node with name 'name'.
*
* Requires:
* 'iterator' is a valid iterator.
*
* 'name' is a valid name.
*
* Returns:
* DNS_R_SUCCESS
* DNS_R_NOTFOUND
*
* Other results are possible, depending on the DB implementation.
*/
dns_result_t
dns_dbiterator_prev(dns_dbiterator_t *iterator);
/*
* Move the node cursor to the previous node in the database (if any).
*
* Requires:
* 'iterator' is a valid iterator.
*
* Returns:
* DNS_R_SUCCESS
* DNS_R_NOMORE There are no more nodes in the
* database.
*
* Other results are possible, depending on the DB implementation.
*/
dns_result_t
dns_dbiterator_next(dns_dbiterator_t *iterator);
/*

View File

@@ -222,6 +222,10 @@ typedef struct rbtdb_rdatasetiter {
static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
static dns_result_t dbiterator_first(dns_dbiterator_t *iterator);
static dns_result_t dbiterator_last(dns_dbiterator_t *iterator);
static dns_result_t dbiterator_seek(dns_dbiterator_t *iterator,
dns_name_t *name);
static dns_result_t dbiterator_prev(dns_dbiterator_t *iterator);
static dns_result_t dbiterator_next(dns_dbiterator_t *iterator);
static dns_result_t dbiterator_current(dns_dbiterator_t *iterator,
dns_dbnode_t **nodep,
@@ -233,6 +237,9 @@ static dns_result_t dbiterator_origin(dns_dbiterator_t *iterator,
static dns_dbiteratormethods_t dbiterator_methods = {
dbiterator_destroy,
dbiterator_first,
dbiterator_last,
dbiterator_seek,
dbiterator_prev,
dbiterator_next,
dbiterator_current,
dbiterator_pause,
@@ -3900,6 +3907,126 @@ dbiterator_first(dns_dbiterator_t *iterator) {
return (result);
}
static dns_result_t
dbiterator_last(dns_dbiterator_t *iterator) {
dns_result_t result;
rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
dns_name_t *name, *origin;
if (rbtdbiter->result != DNS_R_SUCCESS &&
rbtdbiter->result != DNS_R_NOMORE)
return (rbtdbiter->result);
unpause(rbtdbiter);
if (!rbtdbiter->tree_locked) {
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
rbtdbiter->tree_locked = ISC_TRUE;
}
name = dns_fixedname_name(&rbtdbiter->name);
origin = dns_fixedname_name(&rbtdbiter->origin);
dns_rbtnodechain_reset(&rbtdbiter->chain);
result = dns_rbtnodechain_last(&rbtdbiter->chain, rbtdb->tree, name,
origin);
if (result != DNS_R_NEWORIGIN) {
INSIST(result != DNS_R_SUCCESS);
if (result == DNS_R_NOTFOUND) {
/*
* The tree is empty.
*/
result = DNS_R_NOMORE;
}
rbtdbiter->node = NULL;
} else {
result = dns_rbtnodechain_current(&rbtdbiter->chain, NULL,
NULL, &rbtdbiter->node);
if (result == DNS_R_SUCCESS)
rbtdbiter->new_origin = ISC_TRUE;
else
rbtdbiter->node = NULL;
}
rbtdbiter->result = result;
return (result);
}
static dns_result_t
dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
dns_result_t result;
rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
dns_name_t *iname, *origin;
if (rbtdbiter->result != DNS_R_SUCCESS &&
rbtdbiter->result != DNS_R_NOMORE)
return (rbtdbiter->result);
unpause(rbtdbiter);
if (!rbtdbiter->tree_locked) {
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
rbtdbiter->tree_locked = ISC_TRUE;
}
iname = dns_fixedname_name(&rbtdbiter->name);
origin = dns_fixedname_name(&rbtdbiter->origin);
dns_rbtnodechain_reset(&rbtdbiter->chain);
rbtdbiter->node = NULL;
result = dns_rbt_findnode(rbtdb->tree, name, NULL, &rbtdbiter->node,
&rbtdbiter->chain, ISC_TRUE, NULL, NULL);
if (result != DNS_R_SUCCESS) {
if (result == DNS_R_PARTIALMATCH)
result = DNS_R_NOTFOUND;
rbtdbiter->node = NULL;
} else {
result = dns_rbtnodechain_current(&rbtdbiter->chain, iname,
origin, NULL);
if (result == DNS_R_SUCCESS)
rbtdbiter->new_origin = ISC_TRUE;
else
rbtdbiter->node = NULL;
}
rbtdbiter->result = result;
return (result);
}
static dns_result_t
dbiterator_prev(dns_dbiterator_t *iterator) {
dns_result_t result;
rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
dns_name_t *name, *origin;
REQUIRE(rbtdbiter->node != NULL);
if (rbtdbiter->result != DNS_R_SUCCESS)
return (rbtdbiter->result);
if (rbtdbiter->paused)
resume_iteration(rbtdbiter);
name = dns_fixedname_name(&rbtdbiter->name);
origin = dns_fixedname_name(&rbtdbiter->origin);
result = dns_rbtnodechain_prev(&rbtdbiter->chain, name, origin);
if (result == DNS_R_NEWORIGIN || result == DNS_R_SUCCESS) {
if (result == DNS_R_NEWORIGIN)
rbtdbiter->new_origin = ISC_TRUE;
else
rbtdbiter->new_origin = ISC_FALSE;
result = dns_rbtnodechain_current(&rbtdbiter->chain, NULL,
NULL, &rbtdbiter->node);
if (result != DNS_R_SUCCESS) {
rbtdbiter->result = result;
rbtdbiter->node = NULL;
}
} else
rbtdbiter->result = result;
return (result);
}
static dns_result_t
dbiterator_next(dns_dbiterator_t *iterator) {
dns_result_t result;