#ifndef	ACL_SLICE_INCLUDE_H
#define	ACL_SLICE_INCLUDE_H

#ifdef	__cplusplus
extern "C" {
#endif

#include "acl_define.h"

#define	ACL_SLICE_FLAG_OFF		(0)
#define	ACL_SLICE_FLAG_GC1		(1 << 0)  /**< ռʡ,  gc ܲ */
#define	ACL_SLICE_FLAG_GC2		(1 << 1)  /**< ռе, gc ȽϺ */
#define	ACL_SLICE_FLAG_GC3		(1 << 2)  /**< ռ, gc ֻ˳ʱ */
#define	ACL_SLICE_FLAG_RTGC_OFF		(1 << 10) /**< رʵʱڴͷ */
#define	ACL_SLICE_FLAG_LP64_ALIGN	(1 << 11) /**< Ƿ64λƽ̨Ҫ8ֽڶ */

/**
 * ڴƬص״̬ṹ
 */
typedef struct ACL_SLICE_STAT {
	int   nslots;           /**< total slice count free in slots */
	int   islots;           /**< current position of free slots slice */
	int   page_nslots;      /**< count slice of each page */
	int   page_size;        /**< length of each malloc */
	int   slice_length;	/**< length of each slice from user's set */
	int   slice_size;       /**< length of each slice really allocated */
	int   nbuf;             /**< count of MEM_BUF allocated */
	acl_uint64 length;      /**< total size of all MEM_BUF's buf */
	acl_uint64 used_length; /**< total size of used */
	unsigned int flag;	/**< same as the ACL_SLICE's flag been set when created */
} ACL_SLICE_STAT;

typedef struct ACL_SLICE ACL_SLICE;

/**
 * ڴƬض
 * @param name {const char*} ʶƣԱڵ
 * @param page_size {int} ڴʱķڴҳС
 * @param slice_size {int} ÿ̶ڴƬĴС
 * @param flag {unsigned int} ־λμACL_SLICE_FLAG_xxx
 * @return {ACL_SLICE*} ڴƬض
 */
ACL_API ACL_SLICE *acl_slice_create(const char *name, int page_size,
	int slice_size, unsigned int flag);

/**
 * һڴƬض
 * @param slice {ACL_SLICE*} ڴƬض
 */
ACL_API void acl_slice_destroy(ACL_SLICE *slice);

/**
 * ڴƬжٸڴƬڱʹ
 * @param slice {ACL_SLICE*} ڴƬض
 * @return {int} >= 0, ڱʹõڴƬ
 */
ACL_API int acl_slice_used(ACL_SLICE *slice);

/**
 * һڴƬ
 * @param slice {ACL_SLICE*} ڴƬض
 * @return {void*} ڴƬַ
 */
ACL_API void *acl_slice_alloc(ACL_SLICE *slice);

/**
 * һڴƬҽڴƬݳʼΪ0
 * @param slice {ACL_SLICE*} ڴƬض
 * @return {void*} ڴƬַ
 */
ACL_API void *acl_slice_calloc(ACL_SLICE *slice);

/**
 * ͷһڴƬ
 * @param slice {ACL_SLICE*} ڴƬض
 * @param ptr {void*} ڴƬַ,  acl_slice_alloc/acl_slice_calloc 
 */
ACL_API void acl_slice_free2(ACL_SLICE *slice, void *ptr);

/**
 * ͷһڴƬ
 * @param ptr {void*} ڴƬַ,  acl_slice_alloc/acl_slice_calloc 
 */
ACL_API void acl_slice_free(void *ptr);

/**
 * 鿴ڴƬصĵǰ״̬
 * @param slice {ACL_SLICE*} ڴƬض
 * @param sbuf {ACL_SLICE_STAT*} 洢, Ϊ
 */
ACL_API void acl_slice_stat(ACL_SLICE *slice, ACL_SLICE_STAT *sbuf);

/**
 * ֹڴƬزõڴͷ
 * @param slice {ACL_SLICE*} ڴƬض
 */
ACL_API int acl_slice_gc(ACL_SLICE *slice);

/*----------------------------------------------------------------------------*/

typedef struct ACL_SLICE_POOL {
	ACL_SLICE **slices;		/* the slice array */
	int   base;			/* the base byte size */
	int   nslice;			/* the max number of base size */
	unsigned int slice_flag;	/* flag: ACL_SLICE_FLAG_GC2[3] | ACL_SLICE_FLAG_RTGC_OFF */
} ACL_SLICE_POOL;

ACL_API void acl_slice_pool_init(ACL_SLICE_POOL *asp);
ACL_API ACL_SLICE_POOL *acl_slice_pool_create(int base, int nslice,
	unsigned int slice_flag);
ACL_API void acl_slice_pool_destroy(ACL_SLICE_POOL *asp);
ACL_API int acl_slice_pool_used(ACL_SLICE_POOL *asp);
ACL_API void acl_slice_pool_clean(ACL_SLICE_POOL *asp);
ACL_API void acl_slice_pool_reset(ACL_SLICE_POOL *asp);
ACL_API void acl_slice_pool_free(const char *filename, int line, void *buf);
ACL_API void acl_slice_pool_gc(ACL_SLICE_POOL *asp);
ACL_API void *acl_slice_pool_alloc(const char *filename, int line,
	ACL_SLICE_POOL *asp, size_t size);
ACL_API void *acl_slice_pool_calloc(const char *filename, int line,
	ACL_SLICE_POOL *asp, size_t nmemb, size_t size);
ACL_API void *acl_slice_pool_realloc(const char *filename, int line,
	ACL_SLICE_POOL *asp, void *ptr, size_t size);
ACL_API void *acl_slice_pool_memdup(const char *filename, int line,
	ACL_SLICE_POOL *asp, const void *ptr, size_t len);
ACL_API char *acl_slice_pool_strdup(const char *filename, int line,
	ACL_SLICE_POOL *asp, const char *str);
ACL_API char *acl_slice_pool_strndup(const char *filename, int line,
	ACL_SLICE_POOL *asp, const char *str, size_t len);

ACL_API void acl_slice_mem_hook(void *(*malloc_hook)(const char*, int, size_t),
		void *(*calloc_hook)(const char*, int, size_t, size_t),
		void *(*realloc_hook)(const char*, int, void*, size_t),
		void  (*free_hook)(const char*, int, void*));
ACL_API void acl_slice_mem_unhook(void);

#ifdef	__cplusplus
}
#endif

#endif
