/*
 *	Copyright (c) 2004i-2010 Alex Pankratov. All rights reserved.
 *
 *	Hierarchical memory allocator, 1.2.1
 *	http://swapped.cc/halloc
 */

/*
 *	The program is distributed under terms of BSD license. 
 *	You can obtain the copy of the license by visiting:
 *	
 *	http://www.opensource.org/licenses/bsd-license.php
 */

#include <stdlib.h>  /* realloc */
#include <string.h>  /* memset & co */

#include "../halloc.h"
#include "align.h"
#include "hlist.h"

/*
 *	block control header
 */
typedef struct hblock
{
#ifndef NDEBUG
#define HH_MAGIC    0x20040518L
	long          magic;
#endif
	hlist_item_t  siblings; /* 2 pointers */
	hlist_head_t  children; /* 1 pointer  */
	max_align_t   data[1];  /* not allocated, see below */
	
} hblock_t;

#define sizeof_hblock offsetof(hblock_t, data)

/*
 *
 */
realloc_t halloc_allocator = NULL;

#define allocator halloc_allocator

/*
 *	static methods
 */
static void _set_allocator(void);
static void * _realloc(void * ptr, size_t n);

static int  _relate(hblock_t * b, hblock_t * p);
static void _free_children(hblock_t * p);

/*
 *	Core API
 */
void * halloc(void * ptr, size_t len)
{
	hblock_t * p;

	/* set up default allocator */
	if (! allocator)
	{
		_set_allocator();
		assert(allocator);
	}

	/* calloc */
	if (! ptr)
	{
		if (! len)
			return NULL;

		p = allocator(0, len + sizeof_hblock);
		if (! p)
			return NULL;
#ifndef NDEBUG
		p->magic = HH_MAGIC;
#endif
		hlist_init(&p->children);
		hlist_init_item(&p->siblings);

		return p->data;
	}

	p = structof(ptr, hblock_t, data);
	assert(p->magic == HH_MAGIC);

	/* realloc */
	if (len)
	{
		p = allocator(p, len + sizeof_hblock);
		if (! p)
			return NULL;

		hlist_relink(&p->siblings);
		hlist_relink_head(&p->children);
		
		return p->data;
	}

	/* free */
	_free_children(p);
	hlist_del(&p->siblings);
	allocator(p, 0);

	return NULL;
}

void hattach(void * block, void * parent)
{
	hblock_t * b, * p;
	
	if (! block)
	{
		assert(! parent);
		return;
	}

	/* detach */
	b = structof(block, hblock_t, data);
	assert(b->magic == HH_MAGIC);

	hlist_del(&b->siblings);

	if (! parent)
		return;

	/* attach */
	p = structof(parent, hblock_t, data);
	assert(p->magic == HH_MAGIC);
	
	/* sanity checks */
	assert(b != p);          /* trivial */
	assert(! _relate(p, b)); /* heavy ! */

	hlist_add(&p->children, &b->siblings);
}

/*
 *	malloc/free api
 */
void * h_malloc(size_t len)
{
	return halloc(0, len);
}

void * h_calloc(size_t n, size_t len)
{
	void * ptr = halloc(0, len*=n);
	return ptr ? memset(ptr, 0, len) : NULL;
}

void * h_realloc(void * ptr, size_t len)
{
	return halloc(ptr, len);
}

void   h_free(void * ptr)
{
	halloc(ptr, 0);
}

char * h_strdup(const char * str)
{
	size_t len = strlen(str);
	char * ptr = halloc(0, len + 1);
	return ptr ? (ptr[len] = 0, memcpy(ptr, str, len)) : NULL;
}

/*
 *	static stuff
 */
static void _set_allocator(void)
{
	void * p;
	assert(! allocator);
	
	/*
	 *	the purpose of the test below is to check the behaviour
	 *	of realloc(ptr, 0), which is defined in the standard
	 *	as an implementation-specific. if it returns zero,
	 *	then it's equivalent to free(). it can however return
	 *	non-zero, in which case it cannot be used for freeing
	 *	memory blocks and we'll need to supply our own version
	 *
	 *	Thanks to Stan Tobias for pointing this tricky part out.
	 */
	allocator = realloc;
	if (! (p = malloc(1)))
		/* hmm */
		return;
		
	if ((p = realloc(p, 0)))
	{
		/* realloc cannot be used as free() */
		allocator = _realloc;
		free(p);
	}
}

static void * _realloc(void * ptr, size_t n)
{
	/*
	 *	free'ing realloc()
	 */
	if (n)
		return realloc(ptr, n);
	free(ptr);
	return NULL;
}

static int _relate(hblock_t * b, hblock_t * p)
{
	hlist_item_t * i;

	if (!b || !p)
		return 0;

	/* 
	 *  since there is no 'parent' pointer, which would've allowed
	 *  O(log(n)) upward traversal, the check must use O(n) downward 
	 *  iteration of the entire hierarchy; and this can be VERY SLOW
	 */
	hlist_for_each(i, &p->children)
	{
		hblock_t * q = structof(i, hblock_t, siblings);
		if (q == b || _relate(b, q))
			return 1;
	}
	return 0;
}

static void _free_children(hblock_t * p)
{
	hlist_item_t * i, * tmp;
	
#ifndef NDEBUG
	/*
	 *	this catches loops in hierarchy with almost zero 
	 *	overhead (compared to _relate() running time)
	 */
	assert(p && p->magic == HH_MAGIC);
	p->magic = 0; 
#endif
	hlist_for_each_safe(i, tmp, &p->children)
	{
		hblock_t * q = structof(i, hblock_t, siblings);
		_free_children(q);
		allocator(q, 0);
	}
}

