summaryrefslogtreecommitdiffstats
path: root/servers/slapd/back-wt/cache.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--servers/slapd/back-wt/cache.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/servers/slapd/back-wt/cache.c b/servers/slapd/back-wt/cache.c
new file mode 100644
index 0000000..ee393a0
--- /dev/null
+++ b/servers/slapd/back-wt/cache.c
@@ -0,0 +1,231 @@
+/* OpenLDAP WiredTiger backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
+ * based on back-bdb for inclusion in OpenLDAP Software.
+ * WiredTiger is a product of MongoDB Inc.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+#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:
+ */