1 /* OpenLDAP WiredTiger backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2002-2015 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
18 * based on back-bdb for inclusion in OpenLDAP Software.
19 * WiredTiger is a product of MongoDB Inc.
28 static char presence_keyval[] = {0,0};
29 static struct berval presence_key = BER_BVC(presence_keyval);
31 AttrInfo *wt_index_mask(
33 AttributeDescription *desc,
34 struct berval *atname )
37 AttrInfo *ai = wt_attr_mask( be->be_private, desc );
40 *atname = desc->ad_cname;
44 /* If there is a tagging option, did we ever index the base
45 * type? If so, check for mask, otherwise it's not there.
47 if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
48 /* has tagging option */
49 ai = wt_attr_mask( be->be_private, desc->ad_type->sat_ad );
51 if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) {
52 *atname = desc->ad_type->sat_cname;
57 /* see if supertype defined mask for its subtypes */
58 for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
59 /* If no AD, we've never indexed this type */
60 if ( !at->sat_ad ) continue;
62 ai = wt_attr_mask( be->be_private, at->sat_ad );
64 if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) {
65 *atname = at->sat_cname;
73 /* This function is only called when evaluating search filters.
77 AttributeDescription *desc,
80 struct berval *prefixp )
84 slap_mask_t mask, type = 0;
86 ai = wt_index_mask( be, desc, prefixp );
89 /* TODO: add monitor */
90 return LDAP_INAPPROPRIATE_MATCHING;
92 mask = ai->ai_indexmask;
95 case LDAP_FILTER_PRESENT:
96 type = SLAP_INDEX_PRESENT;
97 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
98 *prefixp = presence_key;
104 case LDAP_FILTER_APPROX:
105 type = SLAP_INDEX_APPROX;
106 if ( desc->ad_type->sat_approx ) {
107 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
114 /* Use EQUALITY rule and index for approximate match */
117 case LDAP_FILTER_EQUALITY:
118 type = SLAP_INDEX_EQUALITY;
119 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
125 case LDAP_FILTER_SUBSTRINGS:
126 type = SLAP_INDEX_SUBSTR;
127 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
137 /* TODO: add monitor index */
138 return LDAP_INAPPROPRIATE_MATCHING;
144 AttributeDescription *ad,
145 struct berval *atname,
153 WT_CURSOR *cursor = NULL;
154 WT_SESSION *session = wc->session;
157 cursor = wt_ctx_index_cursor(wc, atname, 1);
159 Debug( LDAP_DEBUG_ANY,
160 LDAP_XSTRING(indexer)
161 ": open index cursor failed: %s\n",
162 atname->bv_val, 0, 0 );
166 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
167 rc = wt_key_change( op->o_bd, cursor, &presence_key, id, opid );
173 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
174 rc = ad->ad_type->sat_equality->smr_indexer(
175 LDAP_FILTER_EQUALITY,
177 ad->ad_type->sat_syntax,
178 ad->ad_type->sat_equality,
179 atname, vals, &keys, op->o_tmpmemctx );
181 if( rc == LDAP_SUCCESS && keys != NULL ) {
182 for( i=0; keys[i].bv_val != NULL; i++ ) {
183 rc = wt_key_change( op->o_bd, cursor, &keys[i], id, opid );
185 ber_bvarray_free_x( keys, op->o_tmpmemctx );
189 ber_bvarray_free_x( keys, op->o_tmpmemctx );
194 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
195 rc = ad->ad_type->sat_approx->smr_indexer(
198 ad->ad_type->sat_syntax,
199 ad->ad_type->sat_approx,
200 atname, vals, &keys, op->o_tmpmemctx );
202 if( rc == LDAP_SUCCESS && keys != NULL ) {
203 for( i=0; keys[i].bv_val != NULL; i++ ) {
204 rc = wt_key_change( op->o_bd, cursor, &keys[i], id, opid );
206 ber_bvarray_free_x( keys, op->o_tmpmemctx );
210 ber_bvarray_free_x( keys, op->o_tmpmemctx );
216 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
217 rc = ad->ad_type->sat_substr->smr_indexer(
218 LDAP_FILTER_SUBSTRINGS,
220 ad->ad_type->sat_syntax,
221 ad->ad_type->sat_substr,
222 atname, vals, &keys, op->o_tmpmemctx );
224 if( rc == LDAP_SUCCESS && keys != NULL ) {
225 for( i=0; keys[i].bv_val != NULL; i++ ) {
226 rc = wt_key_change( op->o_bd, cursor, &keys[i], id, opid );
228 ber_bvarray_free_x( keys, op->o_tmpmemctx );
232 ber_bvarray_free_x( keys, op->o_tmpmemctx );
240 cursor->close(cursor);
245 static int index_at_values(
248 AttributeDescription *ad,
256 slap_mask_t mask = 0;
260 if ( opid == WT_INDEX_UPDATE_OP )
261 ixop = SLAP_INDEX_ADD_OP;
263 if( type->sat_sup ) {
265 rc = index_at_values( op, wc, NULL,
272 /* If this type has no AD, we've never used it before */
274 ai = wt_attr_mask( op->o_bd->be_private, type->sat_ad );
276 #ifdef LDAP_COMP_MATCH
277 /* component indexing */
279 ComponentReference *cr;
280 for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) {
281 rc = indexer( op, wc, cr->cr_ad, &type->sat_cname,
282 cr->cr_nvals, id, ixop,
288 /* If we're updating the index, just set the new bits that aren't
289 * already in the old mask.
291 if ( opid == WT_INDEX_UPDATE_OP )
292 mask = ai->ai_newmask & ~ai->ai_indexmask;
294 /* For regular updates, if there is a newmask use it. Otherwise
295 * just use the old mask.
297 mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask;
299 rc = indexer( op, wc, ad, &type->sat_cname,
300 vals, id, ixop, mask );
307 AttributeDescription *desc;
309 desc = ad_find_tags( type, tags );
311 ai = wt_attr_mask( op->o_bd->be_private, desc );
314 if ( opid == WT_INDEX_UPDATE_OP )
315 mask = ai->ai_newmask & ~ai->ai_indexmask;
317 mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask;
319 rc = indexer( op, wc, desc, &desc->ad_cname,
320 vals, id, ixop, mask );
336 AttributeDescription *desc,
343 /* Never index ID 0 */
347 rc = index_at_values( op, wc, desc,
348 desc->ad_type, &desc->ad_tags,
355 wt_index_entry( Operation *op, wt_ctx *wc, int opid, Entry *e )
358 Attribute *ap = e->e_attrs;
363 Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
364 opid == SLAP_INDEX_DELETE_OP ? "del" : "add",
365 (long) e->e_id, e->e_dn ? e->e_dn : "" );
367 for ( ; ap != NULL; ap = ap->a_next ) {
368 rc = wt_index_values( op, wc, ap->a_desc,
369 ap->a_nvals, e->e_id, opid );
370 if( rc != LDAP_SUCCESS ) {
371 Debug( LDAP_DEBUG_TRACE,
372 "<= index_entry_%s( %ld, \"%s\" ) failure\n",
373 opid == SLAP_INDEX_ADD_OP ? "add" : "del",
374 (long) e->e_id, e->e_dn );
379 Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
380 opid == SLAP_INDEX_DELETE_OP ? "del" : "add",
381 (long) e->e_id, e->e_dn ? e->e_dn : "" );
387 * indent-tabs-mode: t