]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#10526 back-mdb: optimize mdb_idl_intersection
authorHoward Chu <hyc@openldap.org>
Thu, 25 Jun 2026 14:22:53 +0000 (15:22 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 30 Jun 2026 14:14:33 +0000 (14:14 +0000)
Improve case of intersecting a list and a range.

servers/slapd/back-mdb/idl.c

index f8ba9f59dbddf7f36d948b6ebe8e0d0e3b20be88..bc1a45d1a7c88de7fe4100ed7d0e93652e69bf8d 100644 (file)
@@ -260,6 +260,8 @@ static int mdb_idl_delete( ID *ids, ID id )
        return 0;
 }
 
+#ifndef MDB_JUST_TESTING_IDLS
+
 static char *
 mdb_show_key(
        char            *buf,
@@ -703,6 +705,8 @@ fail:
        return rc;
 }
 
+#endif /* MDB_JUST_TESTING_IDLS */
+
 
 /*
  * idl_intersection - return a = a intersection b
@@ -753,10 +757,22 @@ mdb_idl_intersection(
        /* If a range completely covers the list, the result is
         * just the list.
         */
-       if ( MDB_IDL_IS_RANGE( b )
-               && MDB_IDL_RANGE_FIRST( b ) <= MDB_IDL_FIRST( a )
-               && MDB_IDL_RANGE_LAST( b ) >= MDB_IDL_LLAST( a ) ) {
-               goto done;
+       if ( MDB_IDL_IS_RANGE( b )) {
+               idmin = MDB_IDL_RANGE_FIRST( b );
+               idmax = MDB_IDL_RANGE_LAST( b );
+               if ( idmin <= MDB_IDL_FIRST( a ) && idmax >= MDB_IDL_LAST( a ) )
+                       goto done;
+               /* The range overlaps the list. The result is just the
+                * elements of the list within the range.
+                */
+               cursorc = 0;
+               cursora = idmin;
+               ida = mdb_idl_first( a, &cursora );
+               while( ida <= idmax ) {
+                       a[++cursorc] = ida;
+                       ida = mdb_idl_next( a, &cursora );
+               }
+               goto new_a;
        }
 
        /* Fine, do the intersection one element at a time.
@@ -767,7 +783,7 @@ mdb_idl_intersection(
        idb = mdb_idl_first( b, &cursorb );
        cursorc = 0;
 
-       while( ida <= idmax || idb <= idmax ) {
+       while( cursora <= a[0] && cursorb <= b[0] ) {
                if( ida == idb ) {
                        a[++cursorc] = ida;
                        ida = mdb_idl_next( a, &cursora );
@@ -778,6 +794,7 @@ mdb_idl_intersection(
                        idb = mdb_idl_next( b, &cursorb );
                }
        }
+new_a:
        a[0] = cursorc;
 done:
        if (swap)