list.c

来自「傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。」· C语言 代码 · 共 1,356 行 · 第 1/2 页

C
1,356
字号

//#define _CRAPPY_HASH_DEBUG

/*****

List_Ram can still be as high as 30% of the time!

*******/

// #define DO_TIMER

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "mempool.h"
#include "crc32.h"

#ifdef DO_TIMER
#include "timer.h"

TIMER_VARS(List_Ram);
TIMER_VARS(List_RadixWalk);
TIMER_VARS(List_RadixInit);

#else

#define TIMER_P(x)
#define TIMER_Q(X)

#endif // DO_TIMER

#ifndef NDEBUG
#define Debug(func)	func;
#define DebugAlert()	do { __asm { int 03h } } while(0)
#else
#define Debug(func)
#define DebugAlert()
#endif

#define MemAlloc(size)	calloc(1,size)
#define MemFree(mem)	free(mem)

/**********************************/

static MemPool *ListPool_g = NULL, *LinkPool_g = NULL, *HashNodePool_g = NULL;
static int UsageCount = 0;

/**********************************/

int LN_ListLen(LinkNode *pList)
{
LinkNode *pNode;
int Len=0;
	if ( ! pList )
		return 0;
	LN_Walk(pNode,pList) {
		Len++;
	}
return Len;
}

LinkNode *	REGCALL LN_CutHead(LinkNode *pList)
{
LinkNode * LN;
	assert(pList);
	LN = pList->Next;
	if ( LN == pList ) return NULL;
	LN_Cut(LN);
return LN;
}

LinkNode *	REGCALL LN_CutTail(LinkNode *pList)
{
LinkNode * LN;
	assert(pList);
	LN = pList->Prev;
	if ( LN == pList ) return NULL;
	LN_Cut(LN);
return LN;
}

/**********************************/

struct List
{
	List *Next,*Prev;
	void * Data;
};

void	REGCALL List_Destroy(List * pList)
{
List * pNode;
	assert(pList);
	pNode = pList->Next;
	while( pNode != pList )
	{
	List *Next;
		Next = pNode->Next;
		MemPool_FreeHunk(ListPool_g,pNode);
		pNode = Next;
	}
	MemPool_FreeHunk(ListPool_g,pList);
}

List *	REGCALL List_Create(void)
{
List * pNew;

	pNew = MemPool_GetHunk(ListPool_g);
	assert(pNew);
	pNew->Data = NULL;
	pNew->Next = pNew->Prev = pNew;
return pNew;
}

List *	REGCALL List_AddTail(List *pList,void * Data)
{
List * pNew;

	pNew = MemPool_GetHunk(ListPool_g);
	assert(pNew);

	pNew->Next = pList;
	pNew->Prev = pList->Prev;
	pNew->Next->Prev = pNew;
	pNew->Prev->Next = pNew;
	
	pNew->Data= Data;
return pNew;
}

List *	REGCALL List_AddHead(List *pList,void * Data)
{
List * pNew;

	pNew = MemPool_GetHunk(ListPool_g);
	assert(pNew);
	pNew->Data= Data;

	pNew->Prev = pList;
	pNew->Next = pList->Next;
	pNew->Next->Prev = pNew;
	pNew->Prev->Next = pNew;
return pNew;
}

void *	REGCALL List_CutHead(List *pList)
{
List * pNode;
void * pData;
	pNode = pList->Next;
	if ( pNode == pList ) return NULL;
	pData = pNode->Data;

	pList->Next = pNode->Next;
	pList->Next->Prev = pList;

	MemPool_FreeHunk(ListPool_g,pNode);

return pData;
}

void *	REGCALL List_CutTail(List *pList)
{
List * pNode;
void * pData;
	pNode = pList->Prev;
	if ( pNode == pList ) return NULL;
	pData = pNode->Data;

	pList->Prev = pNode->Prev;
	pList->Prev->Next = pList;

	MemPool_FreeHunk(ListPool_g,pNode);

return pData;
}


void *	REGCALL List_PeekHead(List *pList)
{
List * pNode;
	pNode = pList->Next;
	if ( pNode == pList ) return NULL;
return pNode->Data;
}

void *	REGCALL List_PeekTail(List *pList)
{
List * pNode;
	pNode = pList->Prev;
	if ( pNode == pList ) return NULL;
return pNode->Data;
}

void	REGCALL List_CutNode(List *pNode)
{
	pNode->Prev->Next = pNode->Next;
	pNode->Next->Prev = pNode->Prev;

	pNode->Next = pNode->Prev = pNode;
}

void	REGCALL List_DeleteNode(List *pNode)
{
	List_CutNode(pNode);
	List_FreeNode(pNode);
}

void	REGCALL List_FreeNode(List *pNode)
{
	assert(pNode);
	MemPool_FreeHunk(ListPool_g,pNode);
}

void *	REGCALL List_NodeData(List *pNode)
{
	assert(pNode);
	return pNode->Data;
}

List *	REGCALL List_Next(List *pNode)
{
	return pNode->Next;
}
List *	REGCALL List_Prev(List *pNode)
{
	return pNode->Prev;
}

List *	List_Find(List *pList,void *Data)
{
List *pNode;
	assert(pList);
	for(pNode = pList->Next; pNode != pList; pNode = pNode->Next )
	{
		if ( pNode->Data == Data )
			return pNode;
	}
	return NULL;
}

/***********************************************************/
// Stack by linked list

struct Link
{
	Link * Next;
	void * Data;
};

void	REGCALL Link_Destroy(Link * pLink)
{
	while( pLink )
	{
	Link *Next;
		Next = pLink->Next;
		MemPool_FreeHunk(LinkPool_g,pLink);
		pLink = Next;
	}
}

Link *	REGCALL Link_Create(void)
{
Link * pLink;
	pLink = MemPool_GetHunk(LinkPool_g);
	assert(pLink);
	pLink->Next = NULL;
	pLink->Data = NULL;
return pLink;
}

void	REGCALL Link_Push(Link *pLink,void * Data)
{
Link * pNode;
	assert(pLink);
	pNode = MemPool_GetHunk(LinkPool_g);
	assert(pNode);
//	DebugWarn(geRam_IsValidPtr(pLink));
//	DebugWarn(geRam_IsValidPtr(pNode));
	pNode->Data = Data;

	pNode->Next = pLink->Next;
	pLink->Next = pNode;
}

void *	REGCALL Link_Pop(Link *pLink)
{
void *pData;
Link * pNode;
	if ( ! pLink ) return NULL;
//	DebugWarn(geRam_IsValidPtr(pLink));
	pNode = pLink->Next;
	if ( ! pNode ) return NULL;
//	DebugWarn(geRam_IsValidPtr(pNode));
	pData = pNode->Data;
	pLink->Next = pNode->Next;
	MemPool_FreeHunk(LinkPool_g,pNode);
return pData;
}

void *	REGCALL Link_Peek(Link *pLink)
{
void *pData;
Link * pNode;
	if ( ! pLink ) return NULL;
//	DebugWarn(geRam_IsValidPtr(pLink));
	pNode = pLink->Next;
	if ( ! pNode ) return NULL;
//	DebugWarn(geRam_IsValidPtr(pNode));
	pData = pNode->Data;
return pData;
}

/*************************************************************/

#ifdef _DEBUG	// else it's in list.h
struct Stack
{
	void ** Buffer, **End;
	void ** Head;
	int members;
};
#endif

void	REGCALL Stack_Destroy(Stack * pStack)
{
	if ( pStack )
	{
		destroy(pStack->Buffer);
		destroy(pStack);
	}
}

Stack *	REGCALL Stack_Create(void)
{
Stack * pStack;
	pStack = new(Stack);
	assert(pStack);
	pStack->members = 4096;
	pStack->Buffer = MemAlloc(sizeof(void *)*(pStack->members));
	assert(pStack->Buffer);
	pStack->End = pStack->Buffer + (pStack->members);
	pStack->Head = pStack->Buffer;
return pStack;
}

int	REGCALL Stack_Extend(Stack *pStack)
{
void ** NewBuffer;
int newmembers;
	// realloc
	newmembers = pStack->members + 4096;
	NewBuffer = MemAlloc(sizeof(void *)*newmembers);
	assert(NewBuffer);
	memcpy(NewBuffer,pStack->Buffer, sizeof(void *)*(pStack->members));
	pStack->Head = NewBuffer + pStack->members;
	pStack->members = newmembers;
	MemFree(pStack->Buffer);
	pStack->Buffer = NewBuffer;

	pStack->End = pStack->Buffer + (pStack->members);
return newmembers;
}

void	REGCALL Stack_Push_Func(Stack *pStack,void * Data)
{
	assert(pStack);
	*(pStack->Head)++ = Data;
	if ( pStack->Head == pStack->End )
		Stack_Extend(pStack);
}

void *	REGCALL Stack_Pop_Func(Stack *pStack)
{
	assert(pStack);
	if ( pStack->Head == pStack->Buffer )
		return NULL;
	pStack->Head --;
return *(pStack->Head);
}

/*************************************************************/

struct RadixList
{
	int NumLists;
	int Min,Max;
	List ** Lists;
};

RadixList * RadixList_Create(int RadixListMax)
{
RadixList * pRadixList;
int r;
	pRadixList = new(RadixList);
	assert(pRadixList);
	pRadixList->NumLists = RadixListMax+1;
	pRadixList->Lists = MemAlloc(sizeof(List *)*(pRadixList->NumLists));
	assert(pRadixList->Lists);
	for(r=0;r<(pRadixList->NumLists);r++)
	{
		pRadixList->Lists[r] = List_Create();
		assert(pRadixList->Lists[r]);
	}
	pRadixList->Min = pRadixList->NumLists;
	pRadixList->Max = - 1;
return pRadixList;
}

void RadixList_Destroy(RadixList * pRadixList)
{
int r;
	assert(pRadixList);
	for(r=0;r<(pRadixList->NumLists);r++)
	{
		List_Destroy(pRadixList->Lists[r]);
	}
	MemFree(pRadixList->Lists);
	MemFree(pRadixList);
}

List * RadixList_Add(RadixList *pRadixList,void * Data,int Key)
{
List * l;
	assert(pRadixList);
	assert( Key < pRadixList->NumLists && Key >= 0 );
	l = List_AddTail(pRadixList->Lists[Key],Data);
	if ( Key < pRadixList->Min ) pRadixList->Min = Key;
	if ( Key > pRadixList->Max ) pRadixList->Max = Key;
return l;
}

void * RadixList_CutMax(RadixList *pRadixList,int *pKey)
{
	assert(pRadixList);

	while ( pRadixList->Max >= 0 )
	{
	void * Data;

		if ( Data = List_CutHead(pRadixList->Lists[pRadixList->Max]) )
		{
			if ( pKey ) *pKey = pRadixList->Max;
			return Data;	
		}
		pRadixList->Max --;

	}

return NULL;
}

void * RadixList_CutMin(RadixList *pRadixList,int *pKey)
{
	assert(pRadixList);

	while ( pRadixList->Min < pRadixList->NumLists )
	{
	void * Data;

		if ( Data = List_CutHead(pRadixList->Lists[pRadixList->Min]) )
		{
			if ( pKey ) *pKey = pRadixList->Min;
			return Data;	
		}
		pRadixList->Min ++;

	}

return NULL;
}

void * RadixList_CutKey(RadixList *pRadixList,int Key)
{
	assert(pRadixList);
return List_CutHead(pRadixList->Lists[Key]);
}

/*************************************************/

struct RadixLN
{
	int NumLNs;
	int Min,Max;
	LinkNode * LNs;
};

RadixLN * RadixLN_Create(int RadixLNMax)
{
RadixLN * pRadixLN;
LinkNode * LNs;
int r;
	pRadixLN = new(RadixLN);
	assert(pRadixLN);
	pRadixLN->NumLNs = RadixLNMax+1;
	pRadixLN->LNs = MemAlloc(sizeof(LinkNode)*(pRadixLN->NumLNs));
	assert(pRadixLN->LNs);

TIMER_P(List_RadixInit); // not counting the allocs, tracking in List_Ram

	LNs = pRadixLN->LNs;
	for(r=(pRadixLN->NumLNs);r--;LNs++)
	{
		// LN_InitList( LNs );
		LNs->Next = LNs->Prev = LNs;
	}
	pRadixLN->Min = RadixLNMax;
	pRadixLN->Max = 0;
	
TIMER_Q(List_RadixInit);

return pRadixLN;
}

void RadixLN_Destroy(RadixLN * pRadixLN)
{
	assert(pRadixLN);
	MemFree(pRadixLN->LNs);
	MemFree(pRadixLN);
}

void RadixLN_AddHead(RadixLN *pRadixLN,LinkNode *LN,int Key)
{
	assert(pRadixLN);
	assert( Key < pRadixLN->NumLNs && Key >= 0 );
	LN_AddHead(&(pRadixLN->LNs[Key]),LN);
	if ( Key < pRadixLN->Min ) pRadixLN->Min = Key;
	if ( Key > pRadixLN->Max ) pRadixLN->Max = Key;
}

void RadixLN_AddTail(RadixLN *pRadixLN,LinkNode *LN,int Key)
{
	assert(pRadixLN);
	assert( Key < pRadixLN->NumLNs && Key >= 0 );
	LN_AddTail(&(pRadixLN->LNs[Key]),LN);
	if ( Key < pRadixLN->Min ) pRadixLN->Min = Key;
	if ( Key > pRadixLN->Max ) pRadixLN->Max = Key;
}

LinkNode * RadixLN_CutMax(RadixLN *pRadixLN,int *pKey)
{
	assert(pRadixLN);

TIMER_P(List_RadixWalk);
	while ( pRadixLN->Max >= 0 )
	{
	LinkNode * LN;

		if ( LN = LN_CutHead(&(pRadixLN->LNs[pRadixLN->Max])) )
		{
			if ( pKey ) *pKey = pRadixLN->Max;
TIMER_Q(List_RadixWalk);
			return LN;
		}
		pRadixLN->Max --;
	}
TIMER_Q(List_RadixWalk);

return NULL;
}

LinkNode * RadixLN_CutMin(RadixLN *pRadixLN,int *pKey)
{
	assert(pRadixLN);

TIMER_P(List_RadixWalk);
	while ( pRadixLN->Min < pRadixLN->NumLNs )
	{
	LinkNode * LN;

		if ( LN = LN_CutHead(&(pRadixLN->LNs[pRadixLN->Min])) )
		{
			if ( pKey ) *pKey = pRadixLN->Max;
TIMER_Q(List_RadixWalk);
			return LN;
		}
		pRadixLN->Min ++;
	}
TIMER_Q(List_RadixWalk);

return NULL;
}

LinkNode * RadixLN_CutKey(RadixLN *pRadixLN,int Key)
{
	assert(pRadixLN);
return LN_CutHead(&(pRadixLN->LNs[Key]));
}


LinkNode * RadixLN_PeekMax(RadixLN *pRadixLN,int *pKey)
{
LinkNode * LNs;
	assert(pRadixLN);

TIMER_P(List_RadixWalk);
	LNs = & pRadixLN->LNs[pRadixLN->Max];
	while ( pRadixLN->Max >= 0 )
	{
	LinkNode * LN;

		LN = LNs->Next;
		if ( LN != LNs )
		{
			if ( pKey ) *pKey = pRadixLN->Max;
TIMER_Q(List_RadixWalk);
			return LN;
		}
		pRadixLN->Max --;
		LNs --;
	}
TIMER_Q(List_RadixWalk);

return NULL;
}

LinkNode * RadixLN_PeekMin(RadixLN *pRadixLN,int *pKey)
{
LinkNode * LNlist;
	assert(pRadixLN);

TIMER_P(List_RadixWalk);
	LNlist = & pRadixLN->LNs[pRadixLN->Min];
	while ( pRadixLN->Min < pRadixLN->NumLNs )
	{
	LinkNode * LN;

		LN = LNlist->Next;
		if ( LN != LNlist )
		{
			if ( pKey ) *pKey = pRadixLN->Min;
TIMER_Q(List_RadixWalk);
			return LN;
		}
		pRadixLN->Min ++;
		LNlist ++;
	}
TIMER_Q(List_RadixWalk);

return NULL;
}

/*************************************************/

struct RadixLink
{
	int NumLinks;
	int Min,Max;
	Link * Links;
};

RadixLink * RadixLink_Create(int RadixLinkMax)
{
RadixLink * pRadixLink;
	pRadixLink = new(RadixLink);
	assert(pRadixLink);
	pRadixLink->NumLinks = RadixLinkMax+1;
	pRadixLink->Links = MemAlloc(sizeof(Link)*(pRadixLink->NumLinks));
	assert(pRadixLink->Links);
	//memset(pRadixLink->Links,0,(sizeof(Link)*(pRadixLink->NumLinks)));
	pRadixLink->Min = pRadixLink->NumLinks;
	pRadixLink->Max = - 1;
return pRadixLink;
}

void RadixLink_Grow(RadixLink *pRadixLink,int NewMax)
{
Link * OldLinks;
int OldNumLinks;

	OldNumLinks = pRadixLink->NumLinks;
	OldLinks = pRadixLink->Links;

	pRadixLink->NumLinks = NewMax + 1;
	pRadixLink->Links = MemAlloc(sizeof(Link)*(pRadixLink->NumLinks));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?