/*
 * sort_list: a stable sort for lists.
 *
 * Time complexity: O(n*log n)
 *   [assuming limited zero-element fragments]
 *
 * Space complexity: O(1).
 *
 * Stable: yes.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lib.h"
#include "allocate.h"

#undef PARANOIA
#undef COVERAGE

#ifdef PARANOIA
#include <assert.h>
#else
#define assert(x)
#endif

#ifdef COVERAGE
static unsigned char been_there[256];
#define BEEN_THERE(_c)					\
  do {							\
	if (!been_there[_c]) {				\
		been_there[_c] = 1;			\
		printf ("Been there: %c\n", _c);	\
	}						\
  } while (0)
#else
#define BEEN_THERE(_c) do { } while (0)
#endif

// Sort one fragment.  LIST_NODE_NR (==29) is a bit too high for my
// taste for something this simple.  But, hey, it's O(1).
//
// I would use libc qsort for this, but its comparison function
// gets a pointer indirection extra.
static void array_sort(void **ptr, int nr, int (*cmp)(const void *, const void *))
{
	int i;
	for (i = 1; i < nr; i++) {
		void *p = ptr[i];
		if (cmp(ptr[i-1],p) > 0) {
			int j = i;
			do {
				ptr[j] = ptr[j-1];
				if (!--j)
					break;
			} while (cmp(ptr[j-1], p) > 0);
			ptr[j] = p;
		}
	}
}

#ifdef PARANOIA
static void verify_seq_sorted (struct ptr_list *l, int n,
			       int (*cmp)(const void *, const void *))
{
	int i = 0;
	const void *a;
	struct ptr_list *head = l;

	while (l->nr == 0) {
		l = l->next;
		if (--n == 0)
			return;
		assert (l != head);
	}

	a = l->list[0];
	while (n > 0) {
		const void *b;
		if (++i >= l->nr) {
			i = 0;
			l = l->next;
			n--;
			assert (l != head || n == 0);
			continue;
		}
		b = l->list[i];
		assert (cmp (a, b) <= 0);
		a = b;
	}
}
#endif


#define FLUSH_TO(b)						\
  do {								\
	int nr = (b)->nr;					\
	assert (nbuf >= nr);					\
	memcpy ((b)->list, buffer, nr * sizeof (void *));	\
	nbuf -= nr;						\
	memmove (buffer, buffer + nr, nbuf * sizeof (void *));	\
  } while (0)

#define DUMP_TO(b)						\
  do {								\
        assert (nbuf <= (b)->nr);				\
	memcpy ((b)->list, buffer, nbuf * sizeof (void *));	\
  } while (0)


// Merge two already-sorted sequences of blocks:
//   (b1_1, ..., b1_n)  and  (b2_1, ..., b2_m)
// Since we may be moving blocks around, we return the new head
// of the merged list.
static struct ptr_list *
merge_block_seqs (struct ptr_list *b1, int n,
		  struct ptr_list *b2, int m,
		  int (*cmp)(const void *, const void *))
{
	int i1 = 0, i2 = 0;
	const void *buffer[2 * LIST_NODE_NR];
	int nbuf = 0;
	struct ptr_list *newhead = b1;

	// printf ("Merging %d blocks at %p with %d blocks at %p\n", n, b1, m, b2);

	// Skip empty blocks in b2.
	while (b2->nr == 0) {
		BEEN_THERE('F');
		b2 = b2->next;
		if (--m == 0) {
			BEEN_THERE('G');
			return newhead;
		}
	}

	// Do a quick skip in case entire blocks from b1 are
	// already less than smallest element in b2.
	while (b1->nr == 0 ||
	       cmp (PTR_ENTRY(b1, b1->nr - 1), PTR_ENTRY(b2,0)) < 0) {
		// printf ("Skipping whole block.\n");
		BEEN_THERE('H');
		b1 = b1->next;
		if (--n == 0) {
			BEEN_THERE('I');
			return newhead;	
		}
	}

	while (1) {
		const void *d1 = PTR_ENTRY(b1,i1);
		const void *d2 = PTR_ENTRY(b2,i2);

		assert (i1 >= 0 && i1 < b1->nr);
		assert (i2 >= 0 && i2 < b2->nr);
		assert (b1 != b2);
		assert (n > 0);
		assert (m > 0);

		if (cmp (d1, d2) <= 0) {
			BEEN_THERE('J');
			buffer[nbuf++] = d1;
			// Element from b1 is smaller
			if (++i1 >= b1->nr) {
				BEEN_THERE('L');
				FLUSH_TO(b1);
				do {
					b1 = b1->next;
					if (--n == 0) {
						BEEN_THERE('O');
						while (b1 != b2) {
							BEEN_THERE('P');
							FLUSH_TO(b1);
							b1 = b1->next;
						}
						assert (nbuf == i2);
						DUMP_TO(b2);
						return newhead;
					}
				} while (b1->nr == 0);
				i1 = 0;
			}
		} else {
			BEEN_THERE('K');
			// Element from b2 is smaller
			buffer[nbuf++] = d2;
			if (++i2 >= b2->nr) {
				struct ptr_list *l = b2;
				BEEN_THERE('M');
				// OK, we finished with b2.  Pull it out
				// and plug it in before b1.

				b2 = b2->next;
				b2->prev = l->prev;
				b2->prev->next = b2;
				l->next = b1;
				l->prev = b1->prev;
				l->next->prev = l;
				l->prev->next = l;

				if (b1 == newhead) {
					BEEN_THERE('N');
					newhead = l;
				}

				FLUSH_TO(l);
				b2 = b2->prev;
				do {
					b2 = b2->next;
					if (--m == 0) {
						BEEN_THERE('Q');
						assert (nbuf == i1);
						DUMP_TO(b1);
						return newhead;
					}
				} while (b2->nr == 0);
				i2 = 0;
			}
		}
	}
}


void sort_list(struct ptr_list **plist, int (*cmp)(const void *, const void *))
{
	struct ptr_list *head = *plist, *list = head;
	int blocks = 1;

	if (!head)
		return;

	// Sort all the sub-lists
	do {
		array_sort(list->list, list->nr, cmp);
#ifdef PARANOIA
		verify_seq_sorted (list, 1, cmp);
#endif
		list = list->next;
	} while (list != head);

	// Merge the damn things together
	while (1) {
		struct ptr_list *block1 = head;

		do {
			struct ptr_list *block2 = block1;
			struct ptr_list *next, *newhead;
			int i;

			for (i = 0; i < blocks; i++) {
				block2 = block2->next;
				if (block2 == head) {
					if (block1 == head) {
						BEEN_THERE('A');
						*plist = head;
						return;
					}
					BEEN_THERE('B');
					goto next_pass;
				}						
			}

			next = block2;
			for (i = 0; i < blocks; ) {
				next = next->next;
				i++;
				if (next == head) {
					BEEN_THERE('C');
					break;
				}
				BEEN_THERE('D');
			}

			newhead = merge_block_seqs (block1, blocks,
						    block2, i,
						    cmp);
#ifdef PARANOIA
			verify_seq_sorted (newhead, blocks + i, cmp);
#endif
			if (block1 == head) {
				BEEN_THERE('E');
				head = newhead;
			}
			block1 = next;
		} while (block1 != head);
	next_pass:
		blocks <<= 1;
	}
}
