From 986e4e48ee9d650393c59575b4d498944db1222a Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mareynol@redhat.com>
Date: Tue, 7 Feb 2012 15:13:38 -0500
Subject: [PATCH] Ticket #17 - new replication optimizations

Found some more optimizations in the backend.

Remove any unneccessary checks on replicated operations.

While the syntax and schema check functions do check for replicated
ops, there is still a lot of code that can by skipped over.

https://fedorahosted.org/389/ticket/17
---
 ldap/servers/slapd/back-ldbm/ldbm_add.c    |   51 ++++++++++++---------
 ldap/servers/slapd/back-ldbm/ldbm_modify.c |   69 ++++++++++++++++------------
 2 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index acab07d..748ef26 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -208,14 +208,19 @@ ldbm_back_add( Slapi_PBlock *pb )
 				               "ldbm_back_add: Null target dn\n");
 				goto error_return;
 			}
-			dn = slapi_sdn_get_dn(sdn);
-			ldap_result_code = slapi_dn_syntax_check(pb, dn, 1);
-			if (ldap_result_code)
-			{
-				ldap_result_code = LDAP_INVALID_DN_SYNTAX;
-				slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-				goto error_return;
+
+			/* not need to check the dn syntax as this is a replicated op */
+			if(!is_replicated_operation){
+				dn = slapi_sdn_get_dn(sdn);
+				ldap_result_code = slapi_dn_syntax_check(pb, dn, 1);
+				if (ldap_result_code)
+				{
+					ldap_result_code = LDAP_INVALID_DN_SYNTAX;
+					slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+					goto error_return;
+				}
 			}
+
 			slapi_sdn_get_backend_parent(sdn, &parentsdn, pb->pb_backend);
 			/* Check if an entry with the intended DN already exists. */
 			done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_DN_ENTRY); /* Could be through this multiple times */
@@ -332,22 +337,24 @@ ldbm_back_add( Slapi_PBlock *pb )
 		}
 	}
 
+	/* no need to check the schema as this is a replication add */
+	if(!is_replicated_operation){
+		if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) && slapi_entry_schema_check(pb, e) != 0)
+		{
+			LDAPDebug(LDAP_DEBUG_TRACE, "entry failed schema check\n", 0, 0, 0);
+			ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+			goto error_return;
+		}
 
-	if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) && slapi_entry_schema_check(pb, e) != 0) 
-	{
-		LDAPDebug(LDAP_DEBUG_TRACE, "entry failed schema check\n", 0, 0, 0);
-		ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
-		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-		goto error_return;
-	} 
-
-	/* Check attribute syntax */
-	if (slapi_entry_syntax_check(pb, e, 0) != 0)
-	{
-		LDAPDebug(LDAP_DEBUG_TRACE, "entry failed syntax check\n", 0, 0, 0);
-		ldap_result_code = LDAP_INVALID_SYNTAX;
-		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-		goto error_return;
+		/* Check attribute syntax */
+		if (slapi_entry_syntax_check(pb, e, 0) != 0)
+		{
+			LDAPDebug(LDAP_DEBUG_TRACE, "entry failed syntax check\n", 0, 0, 0);
+			ldap_result_code = LDAP_INVALID_SYNTAX;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+			goto error_return;
+		}
 	}
 
 	opcsn = operation_get_csn (operation);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 943a095..f4f1263 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -217,6 +217,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
 	int is_fixup_operation= 0;
 	int is_ruv = 0;                 /* True if the current entry is RUV */
 	CSN *opcsn = NULL;
+	int repl_op;
 	int i = 0;
 
 	slapi_pblock_get( pb, SLAPI_BACKEND, &be);
@@ -224,6 +225,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
 	slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr );
 	slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
 	slapi_pblock_get( pb, SLAPI_TXN, (void**)&parent_txn );
+	slapi_pblock_get (pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op);
 
 	slapi_pblock_get( pb, SLAPI_OPERATION, &operation );
 	if (NULL == operation)
@@ -244,12 +246,16 @@ ldbm_back_modify( Slapi_PBlock *pb )
 	{
 		goto error_return;
 	}
-	ldap_result_code = slapi_dn_syntax_check(pb, slapi_sdn_get_dn(addr->sdn), 1);
-	if (ldap_result_code)
-	{
-		ldap_result_code = LDAP_INVALID_DN_SYNTAX;
-		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-		goto error_return;
+
+	/* no need to check the dn syntax as this is a replicated op */
+	if(!repl_op){
+		ldap_result_code = slapi_dn_syntax_check(pb, slapi_sdn_get_dn(addr->sdn), 1);
+		if (ldap_result_code)
+		{
+			ldap_result_code = LDAP_INVALID_DN_SYNTAX;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+			goto error_return;
+		}
 	}
 
 	/* The dblock serializes writes to the database,
@@ -302,7 +308,9 @@ ldbm_back_modify( Slapi_PBlock *pb )
 		goto error_return;
 	}
 
-	remove_illegal_mods(mods);
+	if(!repl_op){
+	    remove_illegal_mods(mods);
+	}
 
 	/* ec is the entry that our bepreop should get to mess with */
 	slapi_pblock_set( pb, SLAPI_MODIFY_EXISTING_ENTRY, ec->ep_entry );
@@ -344,7 +352,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
 	 * If the objectClass attribute type was modified in any way, expand
 	 * the objectClass values to reflect the inheritance hierarchy.
 	 */
-	for ( i = 0; mods[i] != NULL; ++i ) {
+	for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
 		if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
 			slapi_schema_expand_objectclasses( ec->ep_entry );
 			break;
@@ -362,29 +370,32 @@ ldbm_back_modify( Slapi_PBlock *pb )
 		goto error_return;
 	}
 
-	/* check that the entry still obeys the schema */
-	if ( (operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) && 
-		  slapi_entry_schema_check( pb, ec->ep_entry ) != 0 ) {
-		ldap_result_code= LDAP_OBJECT_CLASS_VIOLATION;
-		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-		goto error_return;
-	}
+	/* if this is a replicated op, we don't need to perform these checks */
+	if(!repl_op){
+		/* check that the entry still obeys the schema */
+		if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) &&
+			slapi_entry_schema_check( pb, ec->ep_entry ) != 0 ) {
+			ldap_result_code= LDAP_OBJECT_CLASS_VIOLATION;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+			goto error_return;
+		}
 
-	/* check attribute syntax for the new values */
-	if (slapi_mods_syntax_check(pb, mods, 0) != 0)
-	{
-		ldap_result_code = LDAP_INVALID_SYNTAX;
-		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
-		goto error_return;
-	}
+		/* check attribute syntax for the new values */
+		if (slapi_mods_syntax_check(pb, mods, 0) != 0)
+		{
+			ldap_result_code = LDAP_INVALID_SYNTAX;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+			goto error_return;
+		}
 
-	/*
-	 * make sure the entry contains all values in the RDN.
-	 * if not, the modification must have removed them.
-	 */
-	if ( ! slapi_entry_rdn_values_present( ec->ep_entry ) ) {
-		ldap_result_code= LDAP_NOT_ALLOWED_ON_RDN;
-		goto error_return;
+		/*
+		 * make sure the entry contains all values in the RDN.
+		 * if not, the modification must have removed them.
+		 */
+		if ( ! slapi_entry_rdn_values_present( ec->ep_entry ) ) {
+			ldap_result_code= LDAP_NOT_ALLOWED_ON_RDN;
+			goto error_return;
+		}
 	}
 
 	if (!is_ruv && !is_fixup_operation) {
-- 
1.7.1

