summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-08-04 15:32:22 -0700
committerNoriko Hosoi <nhosoi@redhat.com>2010-08-04 15:32:22 -0700
commit115857a2d111b7b6d72ddadd7c8e231f802fc249 (patch)
tree0dd7afb2905fd01dd9940787376c85b253a44bfc
parent26240315c1ef8fcb71798feae171f394293e953f (diff)
513166 - Simple Paged result doesn't provide the server's estimate
of the total number of entries https://bugzilla.redhat.com/show_bug.cgi?id=513166 Description: By definition, the first integer of the response control is for the estimated search result set size. This fix sets the estimated result set size. * controlType = LDAP_CONTROL_PAGEDRESULTS; * criticality = n/a; * controlValue: * realSearchControlValue ::= SEQUENCE { * size INTEGER (0..maxInt), * -- result set size estimate from server * cookie OCTET STRING
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_search.c17
-rw-r--r--ldap/servers/slapd/dse.c5
-rw-r--r--ldap/servers/slapd/opshared.c13
-rw-r--r--ldap/servers/slapd/pagedresults.c29
-rw-r--r--ldap/servers/slapd/pblock.c14
-rw-r--r--ldap/servers/slapd/proto-slap.h4
-rw-r--r--ldap/servers/slapd/slap.h3
-rw-r--r--ldap/servers/slapd/slapi-plugin.h2
8 files changed, 81 insertions, 6 deletions
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 72ceeb71..72537f4d 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -108,6 +108,8 @@ berval_done(struct berval *val)
*/
int ldbm_back_search_cleanup(Slapi_PBlock *pb, struct ldbminfo *li, sort_spec_thing *sort_control, int ldap_result, char* ldap_result_description, int function_result, Slapi_DN *sdn, struct vlv_request *vlv_request_control)
{
+ int estimate = 0; /* estimated search result count */
+
if(sort_control!=NULL)
{
sort_spec_free(sort_control);
@@ -125,6 +127,7 @@ int ldbm_back_search_cleanup(Slapi_PBlock *pb, struct ldbminfo *li, sort_spec_th
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
delete_search_result_set(&sr);
}
}
@@ -160,6 +163,7 @@ ldbm_back_search( Slapi_PBlock *pb )
LDAPControl **controls = NULL;
Slapi_Operation *operation;
entry_address *addr;
+ int estimate = 0; /* estimated search result set size */
/* SORT control stuff */
int sort = 0;
@@ -202,6 +206,7 @@ ldbm_back_search( Slapi_PBlock *pb )
sr = new_search_result_set( NULL, 0,
compute_lookthrough_limit( pb, li ));
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, sr );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
/* clear this out so we can free it later */
memset(&vlv_request_control, 0, sizeof(vlv_request_control));
@@ -675,6 +680,12 @@ ldbm_back_search( Slapi_PBlock *pb )
sr->sr_candidates = candidates;
sr->sr_virtuallistview = virtual_list_view;
+ /* Set the estimated search result count for simple paged results */
+ if (sr->sr_candidates && !ALLIDS(sr->sr_candidates)) {
+ estimate = IDL_NIDS(sr->sr_candidates);
+ }
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
+
/* check to see if we can skip the filter test */
if ( li->li_filter_bypass && NULL != candidates && !virtual_list_view
&& !lookup_returned_allids ) {
@@ -1117,6 +1128,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
Slapi_DN basesdn;
char *target_uniqueid;
int rc = 0;
+ int estimate = 0; /* estimated search result count */
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -1178,6 +1190,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
if ( use_extension ) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL );
}
@@ -1195,6 +1208,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
if ( use_extension ) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL );
}
@@ -1211,6 +1225,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
if ( use_extension ) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL );
}
@@ -1229,6 +1244,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
if ( use_extension ) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL );
}
@@ -1371,6 +1387,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
/* in case paged results, clean up the conn */
pagedresults_set_search_result(pb->pb_conn, NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
delete_search_result_set( &sr );
slapi_send_ldap_result( pb, LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, nentries, urls );
rc = SLAPI_FAIL_GENERAL;
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index e51ea7d1..c6bffdd4 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -1660,6 +1660,7 @@ dse_search(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi
int isrootdse= 0;
char returntext[SLAPI_DSE_RETURNTEXT_SIZE]= "";
Slapi_DN basesdn;
+ int estimate = 0; /* estimated search result set size */
/*
* Get private information created in the init routine.
@@ -1716,6 +1717,7 @@ dse_search(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi
slapi_pblock_set (pb, SLAPI_SEARCH_RESULT_SET, ss);
dse_search_set_add_entry (ss, baseentry); /* consumes the entry */
baseentry= NULL;
+ estimate = 1; /* scope base */
}
}
slapi_entry_free(baseentry);
@@ -1726,10 +1728,11 @@ dse_search(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi
case LDAP_SCOPE_SUBTREE:
if(!isrootdse)
{
- do_dse_search(pdse, pb, scope, &basesdn, filter, attrs, attrsonly);
+ estimate = do_dse_search(pdse, pb, scope, &basesdn, filter, attrs, attrsonly);
}
break;
}
+ slapi_pblock_set (pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate);
/* Search is done, send LDAP_SUCCESS */
slapi_sdn_done(&basesdn);
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index d06dd2da..4701edf6 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -217,6 +217,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
unsigned int pr_stat = 0;
ber_int_t pagesize = -1;
+ ber_int_t estimate = 0; /* estimated search result set size */
int curr_search_count = 0;
Slapi_Backend *pr_be = NULL;
void *pr_search_result = NULL;
@@ -376,6 +377,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
pr_search_result = pagedresults_get_search_result(pb->pb_conn);
pr_search_result_count =
pagedresults_get_search_result_count(pb->pb_conn);
+ estimate =
+ pagedresults_get_search_result_set_size_estimate(pb->pb_conn);
} else {
/* parse paged-results-control failed */
if (iscritical) { /* return an error since it's critical */
@@ -572,13 +575,16 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
} else {
curr_search_count = pnentries;
}
+ estimate = 0;
} else {
curr_search_count = pnentries;
+ estimate -= estimate?curr_search_count:0;
}
- pagedresults_set_response_control(pb, 0, pagesize, curr_search_count);
+ pagedresults_set_response_control(pb, 0, estimate, curr_search_count);
if (pagedresults_get_with_sort(pb->pb_conn)) {
sort_make_sort_response_control(pb, CONN_GET_SORT_RESULT_CODE, NULL);
}
+ pagedresults_set_search_result_set_size_estimate(pb->pb_conn, estimate);
next_be = NULL; /* to break the loop */
} else {
/* be_suffix null means that we are searching the default backend
@@ -706,16 +712,19 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
} else {
curr_search_count = pnentries;
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate);
if (pagedresults_set_current_be(pb->pb_conn, be) < 0 ||
pagedresults_set_search_result(pb->pb_conn, sr) < 0 ||
pagedresults_set_search_result_count(pb->pb_conn,
curr_search_count) < 0 ||
+ pagedresults_set_search_result_set_size_estimate(pb->pb_conn,
+ estimate) < 0 ||
pagedresults_set_with_sort(pb->pb_conn, with_sort) < 0) {
goto free_and_return;
}
}
pagedresults_set_response_control(pb, 0,
- pagesize, curr_search_count);
+ estimate, curr_search_count);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
next_be = NULL; /* to break the loop */
}
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index e82053bc..fdda938e 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -114,7 +114,7 @@ pagedresults_parse_control_value( struct berval *psbvp,
*/
void
pagedresults_set_response_control( Slapi_PBlock *pb, int iscritical,
- ber_int_t pagesize, int curr_search_count )
+ ber_int_t estimate, int curr_search_count )
{
LDAPControl **resultctrls = NULL;
LDAPControl pr_respctrl;
@@ -135,7 +135,7 @@ pagedresults_set_response_control( Slapi_PBlock *pb, int iscritical,
} else {
cookie_str = slapi_ch_smprintf("%d", curr_search_count);
}
- ber_printf ( ber, "{io}", pagesize, cookie_str, strlen(cookie_str) );
+ ber_printf ( ber, "{io}", estimate, cookie_str, strlen(cookie_str) );
if ( ber_flatten ( ber, &berval ) != LDAP_SUCCESS )
{
goto bailout;
@@ -250,6 +250,31 @@ pagedresults_set_search_result_count(Connection *conn, int count)
}
int
+pagedresults_get_search_result_set_size_estimate(Connection *conn)
+{
+ int count = 0;
+ if (conn) {
+ PR_Lock(conn->c_mutex);
+ count = conn->c_search_result_set_size_estimate;
+ PR_Unlock(conn->c_mutex);
+ }
+ return count;
+}
+
+int
+pagedresults_set_search_result_set_size_estimate(Connection *conn, int count)
+{
+ int rc = -1;
+ if (conn) {
+ PR_Lock(conn->c_mutex);
+ conn->c_search_result_set_size_estimate = count;
+ PR_Unlock(conn->c_mutex);
+ rc = 0;
+ }
+ return rc;
+}
+
+int
pagedresults_get_with_sort(Connection *conn)
{
int flags = 0;
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index dd126976..06a2947e 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -1522,6 +1522,13 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
(*(void **)value) = pblock->pb_op->o_results.r.r_search.search_result_set;
}
break;
+ /* estimated search result set size */
+ case SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE:
+ if(pblock->pb_op!=NULL)
+ {
+ (*(int *)value) = pblock->pb_op->o_results.r.r_search.estimate;
+ }
+ break;
/* Entry returned from iterating over results set */
case SLAPI_SEARCH_RESULT_ENTRY:
if(pblock->pb_op!=NULL)
@@ -2891,6 +2898,13 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
pblock->pb_op->o_results.r.r_search.search_result_set = (void *)value;
}
break;
+ /* estimated search result set size */
+ case SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE:
+ if(pblock->pb_op!=NULL)
+ {
+ pblock->pb_op->o_results.r.r_search.estimate = *(int *)value;
+ }
+ break;
/* Search result - entry returned from iterating over result set */
case SLAPI_SEARCH_RESULT_ENTRY:
if(pblock->pb_op!=NULL)
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index f0d27ca7..1ca99871 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1358,13 +1358,15 @@ int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
* pagedresults.c
*/
int pagedresults_parse_control_value(struct berval *psbvp, ber_int_t *pagesize, int *curr_search_count);
-void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, ber_int_t pagesize, int curr_search_count);
+void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, ber_int_t estimate, int curr_search_count);
Slapi_Backend *pagedresults_get_current_be(Connection *conn);
int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be);
void *pagedresults_get_search_result(Connection *conn);
int pagedresults_set_search_result(Connection *conn, void *sr);
int pagedresults_get_search_result_count(Connection *conn);
int pagedresults_set_search_result_count(Connection *conn, int cnt);
+int pagedresults_get_search_result_get_size_estimate(Connection *conn);
+int pagedresults_set_search_result_set_size_estimate(Connection *conn, int cnt);
int pagedresults_get_with_sort(Connection *conn);
int pagedresults_set_with_sort(Connection *conn, int flags);
int pagedresults_get_sort_result_code(Connection *conn);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 485af174..f5919c7a 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1230,6 +1230,8 @@ typedef struct slapi_operation_results
int nentries;
/* Any referrals encountered during the search */
struct berval **search_referrals;
+ /* estimated search result set size */
+ int estimate;
} r_search;
struct extended_results
@@ -1345,6 +1347,7 @@ typedef struct conn {
Slapi_Backend *c_current_be; /* backend being used */
void *c_search_result_set; /* search result set for paging */
int c_search_result_count; /* search result count */
+ int c_search_result_set_size_estimate; /* estimated search result set size */
int c_sort_result_code; /* sort result put in response */
time_t c_timelimit; /* time limit for this connection */
/* PAGED_RESULTS ENDS */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 83e12f36..df3380b0 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5841,6 +5841,8 @@ typedef struct slapi_plugindesc {
*/
/* Search result set */
#define SLAPI_SEARCH_RESULT_SET 193
+/* Estimated search result set size (for paged results) */
+#define SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE 1930
/* Search result - next entry returned from search result set */
#define SLAPI_SEARCH_RESULT_ENTRY 194
#define SLAPI_SEARCH_RESULT_ENTRY_EXT 1944