/* OpenLDAP WiredTiger backend */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * * Copyright 2002-2022 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ /* ACKNOWLEDGEMENTS: * This work was developed by HAMANO Tsukasa * based on back-bdb for inclusion in OpenLDAP Software. * WiredTiger is a product of MongoDB Inc. */ #include "portable.h" #include #include #include "back-wt.h" #include "slap-config.h" #include "idl.h" int wt_idlcache_get(wt_ctx *wc, struct berval *ndn, int scope, ID *ids) { int rc = 0; WT_ITEM item; WT_SESSION *session = wc->idlcache_session; WT_CURSOR *cursor = NULL; Debug( LDAP_DEBUG_TRACE, "=> wt_idlcache_get(\"%s\", %d)\n", ndn->bv_val, scope ); rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL, NULL, &cursor); if(rc){ Debug( LDAP_DEBUG_ANY, "wt_idlcache_get: open_cursor failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); return rc; } cursor->set_key(cursor, ndn->bv_val, (int8_t)scope); rc = cursor->search(cursor); switch( rc ){ case 0: break; case WT_NOTFOUND: Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: miss\n" ); goto done; default: Debug( LDAP_DEBUG_ANY, "<= wt_idlcache_get: search failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); rc = 0; goto done; } rc = cursor->get_value(cursor, &item); if (rc) { Debug( LDAP_DEBUG_ANY, "wt_idlcache_get: get_value failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); goto done; } if (item.size == 0) { Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: updating\n"); rc = WT_NOTFOUND; goto done; } memcpy(ids, item.data, item.size); Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: hit id=%ld first=%ld last=%ld\n", (long)ids[0], (long)WT_IDL_FIRST(ids), (long)WT_IDL_LAST(ids)); done: if(cursor) { cursor->close(cursor); } return rc; } int wt_idlcache_set(wt_ctx *wc, struct berval *ndn, int scope, ID *ids) { int rc = 0; WT_ITEM item; WT_SESSION *session = wc->idlcache_session; WT_CURSOR *cursor = NULL; Debug( LDAP_DEBUG_TRACE, "=> wt_idlcache_set(\"%s\", %d)\n", ndn->bv_val, scope ); item.size = WT_IDL_SIZEOF(ids); item.data = ids; rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL, "overwrite=false", &cursor); if(rc){ Debug( LDAP_DEBUG_ANY, "wt_idlcache_set: open_cursor failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); return rc; } cursor->set_key(cursor, ndn->bv_val, (int8_t)scope); cursor->set_value(cursor, &item); rc = cursor->update(cursor); switch( rc ){ case 0: break; case WT_NOTFOUND: // updating cache by another thread goto done; default: Debug( LDAP_DEBUG_ANY, "wt_idlcache_set: update failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); goto done; } Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_set: set idl size=%ld\n", (long)ids[0]); done: if(cursor) { cursor->close(cursor); } return rc; } int wt_idlcache_begin(wt_ctx *wc, struct berval *ndn, int scope) { int rc = 0; WT_ITEM item; WT_SESSION *session = wc->idlcache_session; WT_CURSOR *cursor = NULL; Debug( LDAP_DEBUG_TRACE, "=> wt_idlcache_begin(\"%s\", %d)\n", ndn->bv_val, scope ); item.size = 0; item.data = ""; rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL, "overwrite=true", &cursor); if(rc){ Debug( LDAP_DEBUG_ANY, "wt_idlcache_begin: open_cursor failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); return rc; } cursor->set_key(cursor, ndn->bv_val, (int8_t)scope); cursor->set_value(cursor, &item); rc = cursor->update(cursor); if(rc){ Debug( LDAP_DEBUG_ANY, "wt_idlcache_begin: update failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); goto done; } Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_begin: set updating\n" ); done: if(cursor) { cursor->close(cursor); } return rc; } int wt_idlcache_clear(Operation *op, wt_ctx *wc, struct berval *ndn) { BackendDB *be = op->o_bd; int rc = 0; struct berval pdn = *ndn; WT_SESSION *session = wc->idlcache_session; WT_CURSOR *cursor = NULL; int level = 0; Debug( LDAP_DEBUG_TRACE, "=> wt_idlcache_clear(\"%s\")\n", ndn->bv_val ); if (be_issuffix( be, ndn )) { return 0; } rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL, NULL, &cursor); if(rc){ Debug( LDAP_DEBUG_ANY, "wt_idlcache_clear: open_cursor failed: %s (%d)\n", wiredtiger_strerror(rc), rc ); return rc; } do { dnParent( &pdn, &pdn ); if (level == 0) { /* clear only parent level cache */ cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_ONE); cursor->remove(cursor); } cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_SUB); cursor->remove(cursor); cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_CHILDREN); cursor->remove(cursor); level++; }while(!be_issuffix( be, &pdn )); if(cursor) { cursor->close(cursor); } return 0; } /* * Local variables: * indent-tabs-mode: t * tab-width: 4 * c-basic-offset: 4 * End: */