svn commit: samba r20968 - in branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules: .

metze at samba.org metze at samba.org
Tue Jan 23 10:21:14 GMT 2007


Author: metze
Date: 2007-01-23 10:21:14 +0000 (Tue, 23 Jan 2007)
New Revision: 20968

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=20968

Log:
- add functions to sort the meta data and attribute arrays
- we should use them before we store records to disk

metze
Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/repl_meta_data.c


Changeset:
Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/repl_meta_data.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/repl_meta_data.c	2007-01-23 10:08:08 UTC (rev 20967)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/repl_meta_data.c	2007-01-23 10:21:14 UTC (rev 20968)
@@ -53,6 +53,8 @@
 	struct ldb_handle *handle;
 	struct ldb_request *orig_req;
 
+	const struct dsdb_schema *schema;
+
 	struct dsdb_extended_replicated_objects *objs;
 
 	uint32_t index_current;
@@ -73,7 +75,15 @@
 {
 	struct replmd_replicated_request *ar;
 	struct ldb_handle *h;
+	const struct dsdb_schema *schema;
 
+	schema = dsdb_get_schema(module->ldb);
+	if (!schema) {
+		ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
+			      "replmd_replicated_init_handle: no loaded schema found\n");
+		return NULL;
+	}
+
 	h = talloc_zero(req, struct ldb_handle);
 	if (h == NULL) {
 		ldb_set_errstring(module->ldb, "Out of Memory");
@@ -96,6 +106,7 @@
 	ar->module	= module;
 	ar->handle	= h;
 	ar->orig_req	= req;
+	ar->schema	= schema;
 	ar->objs	= objs;
 
 	req->handle = h;
@@ -168,6 +179,75 @@
 	return 0;
 }
 
+static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMetaData1 *m1,
+						   const struct replPropertyMetaData1 *m2,
+						   const uint32_t *rdn_attid)
+{
+	if (m1->attid == m2->attid) {
+		return 0;
+	}
+
+	/*
+	 * the rdn attribute should be at the end!
+	 * so we need to return a value greater than zero
+	 * which means m1 is greater than m2
+	 */
+	if (m1->attid == *rdn_attid) {
+		return 1;
+	}
+
+	/*
+	 * the rdn attribute should be at the end!
+	 * so we need to return a value less than zero
+	 * which means m2 is greater than m1
+	 */
+	if (m2->attid == *rdn_attid) {
+		return -1;
+	}
+
+	return m1->attid - m2->attid;
+}
+
+static void replmd_replPropertyMetaDataCtr1_sort(struct replPropertyMetaDataCtr1 *ctr1,
+						 const uint32_t *rdn_attid)
+{
+	ldb_qsort(ctr1->array, ctr1->count, sizeof(struct replPropertyMetaData1),
+		  discard_const_p(void, rdn_attid), (ldb_qsort_cmp_fn_t)replmd_replPropertyMetaData1_attid_sort);
+}
+
+static int replmd_ldb_message_element_attid_sort(const struct ldb_message_element *e1,
+						 const struct ldb_message_element *e2,
+						 const struct dsdb_schema *schema)
+{
+	const struct dsdb_attribute *a1;
+	const struct dsdb_attribute *a2;
+
+	/* 
+	 * TODO: make this faster by caching the dsdb_attribute pointer
+	 *       on the ldb_messag_element
+	 */
+
+	a1 = dsdb_attribute_by_lDAPDisplayName(schema, e1->name);
+	a2 = dsdb_attribute_by_lDAPDisplayName(schema, e2->name);
+
+	/*
+	 * TODO: remove this check, we should rely on e1 and e2 having valid attribute names
+	 *       in the schema
+	 */
+	if (!a1 || !a2) {
+		return strcasecmp(e1->name, e2->name);
+	}
+
+	return a1->attributeID_id - a2->attributeID_id;
+}
+
+static void replmd_ldb_message_sort(struct ldb_message *msg,
+				    const struct dsdb_schema *schema)
+{
+	ldb_qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element),
+		  discard_const_p(void, schema), (ldb_qsort_cmp_fn_t)replmd_ldb_message_element_attid_sort);
+}
+
 static int replmd_prepare_originating(struct ldb_module *module, struct ldb_request *req,
 				      struct ldb_dn *dn, const char *fn_name,
 				      int (*fn)(struct ldb_module *,
@@ -489,7 +569,9 @@
 		return replmd_replicated_request_error(ar, ret);
 	}
 
-	md = ar->objs->objects[ar->index_current].meta_data;
+	/*
+	 * the meta data array is already sorted by the caller
+	 */
 	for (i=0; i < md->ctr.ctr1.count; i++) {
 		md->ctr.ctr1.array[i].local_usn = seq_num;
 	}
@@ -503,6 +585,8 @@
 		return replmd_replicated_request_error(ar, ret);
 	}
 
+	replmd_ldb_message_sort(msg, ar->schema);
+
 	ret = ldb_build_add_req(&ar->sub.change_req,
 				ar->module->ldb,
 				ar->sub.mem_ctx,
@@ -532,12 +616,6 @@
 #endif
 }
 
-static int replmd_replPropertyMetaData1_attid_compare(struct replPropertyMetaData1 *m1,
-						      struct replPropertyMetaData1 *m2)
-{
-	return m1->attid - m2->attid;
-}
-
 static int replmd_replPropertyMetaData1_conflict_compare(struct replPropertyMetaData1 *m1,
 							 struct replPropertyMetaData1 *m2)
 {
@@ -696,31 +774,16 @@
 	 * 'cn' for most objects is the last entry in the meta data array
 	 * we have stored
 	 *
-	 * as it should stay the last one in the new list, we move it to the end
+	 * sort the new meta data array
 	 */
 	{
-		struct replPropertyMetaData1 *rdn_p, rdn, *last_p;
+		struct replPropertyMetaData1 *rdn_p;
 		uint32_t rdn_idx = omd.ctr.ctr1.count - 1;
-		uint32_t last_idx = ni - 1;
 
 		rdn_p = &nmd.ctr.ctr1.array[rdn_idx];
-		rdn = *rdn_p;
-		last_p = &nmd.ctr.ctr1.array[last_idx];
-
-		if (last_idx > rdn_idx) {
-			memmove(rdn_p, rdn_p+1, (last_idx - rdn_idx)*sizeof(rdn));
-			*last_p = rdn;
-		}
+		replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, &rdn_p->attid);
 	}
 
-	/*
-	 * sort the meta data entries by attid, but skip the last one containing
-	 * the rdn attribute
-	 */
-	qsort(nmd.ctr.ctr1.array, nmd.ctr.ctr1.count - 1,
-	      sizeof(struct replPropertyMetaData1),
-	      (comparison_fn_t)replmd_replPropertyMetaData1_attid_compare);
-
 	/* create the meta data value */
 	nt_status = ndr_push_struct_blob(&nmd_value, msg, &nmd,
 					 (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);
@@ -757,6 +820,8 @@
 		return replmd_replicated_request_error(ar, ret);
 	}
 
+	replmd_ldb_message_sort(msg, ar->schema);
+
 	/* we want to replace the old values */
 	for (i=0; i < msg->num_elements; i++) {
 		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;



More information about the samba-cvs mailing list