Commit cc216a01ee512a41320056efc9b588daf9129f7a

Russell Belfer 2013-03-05T16:29:04

Retire spoolandsort iterator Since the case sensitivity is moved into the respective iterators, this removes the spoolandsort iterator code.

diff --git a/src/checkout.c b/src/checkout.c
index 0be87b4..41de0d7 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1248,10 +1248,8 @@ int git_checkout_iterator(
 			&baseline, data.opts.baseline, iterflags, data.pfx, data.pfx)) < 0)
 		goto cleanup;
 
-	/* Handle case insensitivity for baseline if necessary */
-	if (git_iterator_ignore_case(workdir) != git_iterator_ignore_case(baseline))
-		if ((error = git_iterator_spoolandsort_push(baseline, true)) < 0)
-			goto cleanup;
+	/* Should not have case insensitivity mismatch */
+	assert(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline));
 
 	/* Generate baseline-to-target diff which will include an entry for
 	 * every possible update that might need to be made.
diff --git a/src/diff.c b/src/diff.c
index c0f8ee6..7663619 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -620,13 +620,8 @@ int git_diff__from_iterators(
 		goto fail;
 
 	if (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) {
-		/* If either iterator does not have ignore_case set, then we will
-		 * spool its data, sort it icase, and use that for the merge join
-		 * with the other iterator which was icase sorted.  This call is
-		 * a no-op on an iterator that already matches "ignore_case".
-		 */
-		if (git_iterator_spoolandsort_push(old_iter, true) < 0 ||
-			git_iterator_spoolandsort_push(new_iter, true) < 0)
+		if (git_iterator_set_ignore_case(old_iter, true) < 0 ||
+			git_iterator_set_ignore_case(new_iter, true) < 0)
 			goto fail;
 	}
 
diff --git a/src/iterator.c b/src/iterator.c
index 2832e4a..e28f20e 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -960,174 +960,40 @@ fail:
 }
 
 
-typedef struct {
-	/* replacement callbacks */
-	git_iterator_callbacks cb;
-	/* original iterator values */
-	git_iterator_callbacks *orig;
-	git_iterator_type_t orig_type;
-	/* spoolandsort data */
-	git_vector entries;
-	git_pool entry_pool;
-	git_pool string_pool;
-	size_t position;
-} spoolandsort_callbacks;
-
-static int spoolandsort_iterator__current(
-	const git_index_entry **entry, git_iterator *self)
-{
-	spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
-
-	*entry = (const git_index_entry *)
-		git_vector_get(&scb->entries, scb->position);
-
-	return 0;
-}
-
-static int spoolandsort_iterator__at_end(git_iterator *self)
-{
-	spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
-
-	return 0 == scb->entries.length || scb->entries.length - 1 <= scb->position;
-}
-
-static int spoolandsort_iterator__advance(
-	const git_index_entry **entry, git_iterator *self)
-{
-	spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
-
-	*entry = (const git_index_entry *)
-		git_vector_get(&scb->entries, ++scb->position);
-
-	return 0;
-}
-
-static int spoolandsort_iterator__seek(git_iterator *self, const char *prefix)
-{
-	GIT_UNUSED(self);
-	GIT_UNUSED(prefix);
-
-	return -1;
-}
-
-static int spoolandsort_iterator__reset(
-	git_iterator *self, const char *start, const char *end)
-{
-	spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
-
-	GIT_UNUSED(start); GIT_UNUSED(end);
-
-	scb->position = 0;
-
-	return 0;
-}
-
-static void spoolandsort_iterator__free_callbacks(spoolandsort_callbacks *scb)
-{
-	git_pool_clear(&scb->string_pool);
-	git_pool_clear(&scb->entry_pool);
-	git_vector_free(&scb->entries);
-	git__free(scb);
-}
-
-void git_iterator_spoolandsort_pop(git_iterator *self)
+void git_iterator_free(git_iterator *iter)
 {
-	spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
-
-	if (self->type != GIT_ITERATOR_TYPE_SPOOLANDSORT)
+	if (iter == NULL)
 		return;
 
-	self->cb   = scb->orig;
-	self->type = scb->orig_type;
-	self->flags ^= GIT_ITERATOR_IGNORE_CASE;
+	iter->cb->free(iter);
 
-	spoolandsort_iterator__free_callbacks(scb);
-}
+	git__free(iter->start);
+	git__free(iter->end);
 
-static void spoolandsort_iterator__free(git_iterator *self)
-{
-	git_iterator_spoolandsort_pop(self);
-	self->cb->free(self);
+	memset(iter, 0, sizeof(*iter));
+
+	git__free(iter);
 }
 
-int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case)
+int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case)
 {
-	const git_index_entry *item;
-	spoolandsort_callbacks *scb;
-	int (*entrycomp)(const void *a, const void *b);
+	bool desire_ignore_case  = (ignore_case != 0);
 
-	if (((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0) == (ignore_case != 0))
+	if (iterator__ignore_case(iter) == desire_ignore_case)
 		return 0;
 
 	if (iter->type == GIT_ITERATOR_TYPE_EMPTY) {
-		iter->flags = (iter->flags ^ GIT_ITERATOR_IGNORE_CASE);
-		return 0;
-	}
-
-	scb = git__calloc(1, sizeof(spoolandsort_callbacks));
-	GITERR_CHECK_ALLOC(scb);
-
-	ITERATOR_SET_CB(scb,spoolandsort);
-
-	scb->orig      = iter->cb;
-	scb->orig_type = iter->type;
-	scb->position  = 0;
-
-	entrycomp = ignore_case ? git_index_entry__cmp_icase : git_index_entry__cmp;
-
-	if (git_vector_init(&scb->entries, 16, entrycomp) < 0 ||
-		git_pool_init(&scb->entry_pool, sizeof(git_index_entry), 0) < 0 ||
-		git_pool_init(&scb->string_pool, 1, 0) < 0 ||
-		git_iterator_current(&item, iter) < 0)
-		goto fail;
-
-	while (item) {
-		git_index_entry *clone = git_pool_malloc(&scb->entry_pool, 1);
-		if (!clone)
-			goto fail;
-
-		memcpy(clone, item, sizeof(git_index_entry));
-
-		if (item->path) {
-			clone->path = git_pool_strdup(&scb->string_pool, item->path);
-			if (!clone->path)
-				goto fail;
-		}
-
-		if (git_vector_insert(&scb->entries, clone) < 0)
-			goto fail;
-
-		if (git_iterator_advance(&item, iter) < 0)
-			goto fail;
+		if (desire_ignore_case)
+			iter->flags |= GIT_ITERATOR_IGNORE_CASE;
+		else
+			iter->flags &= ~GIT_ITERATOR_IGNORE_CASE;
+	} else {
+		giterr_set(GITERR_INVALID,
+			"Cannot currently set ignore case on non-empty iterators");
+		return -1;
 	}
 
-	git_vector_sort(&scb->entries);
-
-	iter->cb   = (git_iterator_callbacks *)scb;
-	iter->type = GIT_ITERATOR_TYPE_SPOOLANDSORT;
-	iter->flags ^= GIT_ITERATOR_IGNORE_CASE;
-
 	return 0;
-
-fail:
-	spoolandsort_iterator__free_callbacks(scb);
-	return -1;
-}
-
-
-void git_iterator_free(git_iterator *iter)
-{
-	if (iter == NULL)
-		return;
-
-	iter->cb->free(iter);
-
-	git__free(iter->start);
-	git__free(iter->end);
-
-	memset(iter, 0, sizeof(*iter));
-
-	git__free(iter);
 }
 
 git_index *git_iterator_get_index(git_iterator *iter)
@@ -1135,21 +1001,9 @@ git_index *git_iterator_get_index(git_iterator *iter)
 	if (iter->type == GIT_ITERATOR_TYPE_INDEX)
 		return ((index_iterator *)iter)->index;
 
-	if (iter->type == GIT_ITERATOR_TYPE_SPOOLANDSORT &&
-		((spoolandsort_callbacks *)iter->cb)->orig_type == GIT_ITERATOR_TYPE_INDEX)
-		return ((index_iterator *)iter)->index;
-
 	return NULL;
 }
 
-git_iterator_type_t git_iterator_inner_type(git_iterator *iter)
-{
-	if (iter->type == GIT_ITERATOR_TYPE_SPOOLANDSORT)
-		return ((spoolandsort_callbacks *)iter->cb)->orig_type;
-
-	return iter->type;
-}
-
 int git_iterator_current_tree_entry(
 	const git_tree_entry **tree_entry, git_iterator *iter)
 {
@@ -1263,4 +1117,3 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
 
 	return 0;
 }
-
diff --git a/src/iterator.h b/src/iterator.h
index feb0c22..24c7b77 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -19,7 +19,6 @@ typedef enum {
 	GIT_ITERATOR_TYPE_TREE = 1,
 	GIT_ITERATOR_TYPE_INDEX = 2,
 	GIT_ITERATOR_TYPE_WORKDIR = 3,
-	GIT_ITERATOR_TYPE_SPOOLANDSORT = 4
 } git_iterator_type_t;
 
 typedef enum {
@@ -86,14 +85,6 @@ extern int git_iterator_for_workdir(
 
 extern void git_iterator_free(git_iterator *iter);
 
-/* Spool all iterator values, resort with alternative ignore_case value
- * and replace callbacks with spoolandsort alternates.
- */
-extern int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case);
-
-/* Restore original callbacks - not required in most circumstances */
-extern void git_iterator_spoolandsort_pop(git_iterator *iter);
-
 /* Return a git_index_entry structure for the current value the iterator
  * is looking at or NULL if the iterator is at the end.
  *
@@ -154,6 +145,8 @@ GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter)
 	return ((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0);
 }
 
+extern int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case);
+
 extern int git_iterator_current_tree_entry(
 	const git_tree_entry **tree_entry, git_iterator *iter);
 
@@ -196,6 +189,4 @@ extern int git_iterator_current_workdir_path(
 /* Return index pointer if index iterator, else NULL */
 extern git_index *git_iterator_get_index(git_iterator *iter);
 
-extern git_iterator_type_t git_iterator_inner_type(git_iterator *iter);
-
 #endif