]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/idl.c
document option '-F'
[openldap] / servers / slapd / back-bdb / idl.c
index 2f2c08972f50b2cf87723944e750e61944f057d5..b6d0208fad1bf21105f695641d3bcaeeab2a2231 100644 (file)
@@ -271,7 +271,7 @@ bdb_show_key(
        DBT             *key,
        char            *buf )
 {
-       if ( key->size == sizeof( ID ) ) {
+       if ( key->size == 4 /* LUTIL_HASH_BYTES */ ) {
                unsigned char *c = key->data;
                sprintf( buf, "[%02x%02x%02x%02x]", c[0], c[1], c[2], c[3] );
                return buf;
@@ -292,6 +292,7 @@ bdb_idl_cache_get(
 {
        bdb_idl_cache_entry_t idl_tmp;
        bdb_idl_cache_entry_t *matched_idl_entry;
+       int rc = LDAP_NO_SUCH_OBJECT;
 
        DBT2bv( key, &idl_tmp.kstr );
        idl_tmp.db = db;
@@ -301,19 +302,18 @@ bdb_idl_cache_get(
        if ( matched_idl_entry != NULL ) {
                if ( matched_idl_entry->idl && ids )
                        BDB_IDL_CPY( ids, matched_idl_entry->idl );
-               ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
                ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
                IDL_LRU_DELETE( bdb, matched_idl_entry );
                IDL_LRU_ADD( bdb, matched_idl_entry );
                ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
                if ( matched_idl_entry->idl )
-                       return LDAP_SUCCESS;
+                       rc = LDAP_SUCCESS;
                else
-                       return DB_NOTFOUND;
+                       rc = DB_NOTFOUND;
        }
        ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
 
-       return LDAP_NO_SUCH_OBJECT;
+       return rc;
 }
 
 void
@@ -441,7 +441,14 @@ bdb_idl_fetch_key(
 #if DB_VERSION_FULL < 0x04010000
 #      define BDB_ENOUGH 5
 #else
+       /* We sometimes test with tiny IDLs, and BDB always wants buffers
+        * that are at least one page in size.
+        */
+# if BDB_IDL_DB_SIZE < 4096
+#   define BDB_ENOUGH 2048
+# else
 #      define BDB_ENOUGH 1
+# endif
 #endif
        ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH];
 
@@ -475,8 +482,6 @@ bdb_idl_fetch_key(
        data.ulen = sizeof(buf);
        data.flags = DB_DBT_USERMEM;
 
-       if ( tid ) flags |= DB_RMW;
-
        /* If we're not reusing an existing cursor, get a new one */
        if( opflag != DB_NEXT ) {
                rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
@@ -606,7 +611,7 @@ bdb_idl_insert_key(
        int     rc;
        DBT data;
        DBC *cursor;
-       ID lo, hi, tmp, nlo, nhi, nid;
+       ID lo, hi, nlo, nhi, nid;
        char *err;
 
        {
@@ -639,7 +644,7 @@ bdb_idl_insert_key(
        /* Fetch the first data item for this key, to see if it
         * exists and if it's a range.
         */
-       rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+       rc = cursor->c_get( cursor, key, &data, DB_SET );
        err = "c_get";
        if ( rc == 0 ) {
                if ( nlo != 0 ) {
@@ -683,49 +688,36 @@ bdb_idl_insert_key(
                                /* Update hi/lo if needed, then delete all the items
                                 * between lo and hi
                                 */
-                               if ( id > hi ) {
+                               if ( id < lo ) {
+                                       lo = id;
+                                       nlo = nid;
+                               } else if ( id > hi ) {
+                                       hi = id;
                                        nhi = nid;
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del hi";
-                                               goto fail;
-                                       }
-                                       rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
-                                       if ( rc != 0 ) {
-                                               err = "c_put hi";
-                                               goto fail;
-                                       }
                                }
+                               data.data = &nid;
                                /* Don't fetch anything, just position cursor */
                                data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
                                data.dlen = data.ulen = 0;
-                               rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+                               rc = cursor->c_get( cursor, key, &data, DB_SET );
                                if ( rc != 0 ) {
                                        err = "c_get 2";
                                        goto fail;
                                }
-                               data.data = &nid;
-                               if ( id < lo ) {
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del lo";
-                                               goto fail;
-                                       }
-                                       rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
-                                       if ( rc != 0 ) {
-                                               err = "c_put lo";
-                                               goto fail;
-                                       }
+                               rc = cursor->c_del( cursor, 0 );
+                               if ( rc != 0 ) {
+                                       err = "c_del range1";
+                                       goto fail;
                                }
-                               /* Delete all the records between lo and hi */
-                               for ( i=2; i<count; i++ ) {
-                                       rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP | DB_RMW );
-                                       if ( rc != 0 && rc != DB_NOTFOUND ) {
+                               /* Delete all the records */
+                               for ( i=1; i<count; i++ ) {
+                                       rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP );
+                                       if ( rc != 0 ) {
                                                err = "c_get next_dup";
                                                goto fail;
                                        }
                                        rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 && rc != DB_NOTFOUND ) {
+                                       if ( rc != 0 ) {
                                                err = "c_del range";
                                                goto fail;
                                        }
@@ -739,6 +731,18 @@ bdb_idl_insert_key(
                                        err = "c_put range";
                                        goto fail;
                                }
+                               nid = nlo;
+                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
+                               if ( rc != 0 ) {
+                                       err = "c_put lo";
+                                       goto fail;
+                               }
+                               nid = nhi;
+                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
+                               if ( rc != 0 ) {
+                                       err = "c_put hi";
+                                       goto fail;
+                               }
                        } else {
                        /* There's room, just store it */
                                goto put1;
@@ -848,7 +852,7 @@ bdb_idl_delete_key(
        /* Fetch the first data item for this key, to see if it
         * exists and if it's a range.
         */
-       rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+       rc = cursor->c_get( cursor, key, &data, DB_SET );
        err = "c_get";
        if ( rc == 0 ) {
                if ( tmp != 0 ) {
@@ -856,8 +860,7 @@ bdb_idl_delete_key(
                        if (tmp != nid) {
                                /* position to correct item */
                                tmp = nid;
-                               rc = cursor->c_get( cursor, key, &data, 
-                                       DB_GET_BOTH | DB_RMW  );
+                               rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );
                                if ( rc != 0 ) {
                                        err = "c_get id";
                                        goto fail;