diff options
-rw-r--r-- | ldap/servers/slapd/back-ldbm/dblayer.c | 158 |
1 files changed, 84 insertions, 74 deletions
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index 5c1f6e6c..a052d00b 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -2774,6 +2774,79 @@ dblayer_remove_env(struct ldbminfo *li) #define DB_DUPSORT 0 #endif +static int +_dblayer_set_db_callbacks(dblayer_private *priv, DB *dbp, struct attrinfo *ai) +{ + int rc = 0; + + /* With the new idl design, the large 8Kbyte pages we use are not + optimal. The page pool churns very quickly as we add new IDs under a + sustained add load. Smaller pages stop this happening so much and + consequently make us spend less time flushing dirty pages on checkpoints. + But 8K is still a good page size for id2entry. So we now allow different + page sizes for the primary and secondary indices. + Filed as bug: 604654 + */ + if (idl_get_idl_new()) { + rc = dbp->set_pagesize( + dbp, + (priv->dblayer_index_page_size == 0) ? + DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size); + } else { + rc = dbp->set_pagesize( + dbp, + (priv->dblayer_page_size == 0) ? + DBLAYER_PAGESIZE : priv->dblayer_page_size); + } + if (rc) + return rc; + +#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR < 3300 + rc = dbp->set_malloc(dbp, (void *)slapi_ch_malloc); + if (rc) + return rc; +#endif + + if (idl_get_idl_new() && !(ai->ai_indexmask & INDEX_VLV)) { + rc = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT); + if (rc) + return rc; + + rc = dbp->set_dup_compare( dbp, idl_new_compare_dups); + if (rc) + return rc; + } + + if (ai->ai_indexmask & INDEX_VLV) { + /* + * Need index with record numbers for + * Virtual List View index + */ + rc = dbp->set_flags(dbp, DB_RECNUM); + if (rc) + return rc; + } else if (ai->ai_key_cmp_fn) { /* set in attr_index_config() */ + /* + This is so that we can have ordered keys in the index, so that + greater than/less than searches work on indexed attrs. We had + to introduce this when we changed the integer key format from + a 32/64 bit value to a normalized string value. The default + bdb key cmp is based on length and lexicographic order, which + does not work with integer strings. + + NOTE: If we ever need to use app_private for something else, we + will have to create some sort of data structure with different + fields for different uses. We will also need to have a new() + function that creates and allocates that structure, and a + destroy() function that destroys the structure, and make sure + to call it when the DB* is closed and/or freed. + */ + dbp->app_private = (void *)ai->ai_key_cmp_fn; + dbp->set_bt_compare(dbp, dblayer_bt_compare); + } + return rc; +} + /* Routines for opening and closing random files in the DB_ENV. Used by ldif2db merging code currently. @@ -2781,7 +2854,9 @@ dblayer_remove_env(struct ldbminfo *li) Success: 0 Failure: -1 */ -int dblayer_open_file(backend *be, char* indexname, int open_flag, struct attrinfo *ai, DB **ppDB) +int +dblayer_open_file(backend *be, char* indexname, int open_flag, + struct attrinfo *ai, DB **ppDB) { struct ldbminfo *li = (struct ldbminfo *) be->be_database->plg_private; ldbm_instance *inst = (ldbm_instance *) be->be_instance_info; @@ -2840,79 +2915,9 @@ int dblayer_open_file(backend *be, char* indexname, int open_flag, struct attrin goto out; dbp = *ppDB; -/* With the new idl design, the large 8Kbyte pages we use are not - optimal. The page pool churns very quickly as we add new IDs under a - sustained add load. Smaller pages stop this happening so much and - consequently make us spend less time flushing dirty pages on checkpoints. - But 8K is still a good page size for id2entry. So we now allow different - page sizes for the primary and secondary indices. - Filed as bug: 604654 - */ - if (idl_get_idl_new()) { - return_value = dbp->set_pagesize( - dbp, - (priv->dblayer_index_page_size == 0) ? - DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size - ); - } else { - return_value = dbp->set_pagesize( - dbp, - (priv->dblayer_page_size == 0) ? - DBLAYER_PAGESIZE : priv->dblayer_page_size - ); - } - if (0 != return_value) - goto out; - -#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR < 3300 - return_value = dbp->set_malloc(dbp, (void *)slapi_ch_malloc); - if (0 != return_value) { + return_value = _dblayer_set_db_callbacks(priv, dbp, ai); + if (return_value) goto out; - } -#endif - - if (idl_get_idl_new() && !(ai->ai_indexmask & INDEX_VLV)) { - return_value = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT); - if (0 != return_value) - goto out; - - if (ai->ai_dup_cmp_fn) { - /* If set, use the special dup compare callback */ - return_value = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn); - } else { - return_value = dbp->set_dup_compare(dbp, idl_new_compare_dups); - } - if (0 != return_value) - goto out; - } - - if (ai->ai_indexmask & INDEX_VLV) { - /* - * Need index with record numbers for - * Virtual List View index - */ - return_value = dbp->set_flags(dbp, DB_RECNUM); - if (0 != return_value) - goto out; - } else if (ai->ai_key_cmp_fn) { /* set in attr_index_config() */ - /* - This is so that we can have ordered keys in the index, so that - greater than/less than searches work on indexed attrs. We had - to introduce this when we changed the integer key format from - a 32/64 bit value to a normalized string value. The default - bdb key cmp is based on length and lexicographic order, which - does not work with integer strings. - - NOTE: If we ever need to use app_private for something else, we - will have to create some sort of data structure with different - fields for different uses. We will also need to have a new() - function that creates and allocates that structure, and a - destroy() function that destroys the structure, and make sure - to call it when the DB* is closed and/or freed. - */ - dbp->app_private = (void *)ai->ai_key_cmp_fn; - dbp->set_bt_compare(dbp, dblayer_bt_compare); - } /* The subname argument allows applications to have * subdatabases, i.e., multiple databases inside of a single @@ -2920,8 +2925,10 @@ int dblayer_open_file(backend *be, char* indexname, int open_flag, struct attrin * are both numerous and reasonably small, in order to * avoid creating a large number of underlying files. */ + /* If inst_parent_dir_name is not the primary DB dir && + * the index file does not exist */ if ((charray_get_index(priv->dblayer_data_directories, - inst->inst_parent_dir_name) != 0) && + inst->inst_parent_dir_name) > 0) && !dblayer_inst_exists(inst, file_name)) { char inst_dir[MAXPATHLEN]; @@ -2947,6 +2954,9 @@ int dblayer_open_file(backend *be, char* indexname, int open_flag, struct attrin goto out; } dbp = *ppDB; + return_value = _dblayer_set_db_callbacks(priv, dbp, ai); + if (return_value) + goto out; slapi_ch_free_string(&abs_file_name); if (inst_dirp != inst_dir) |