?? dequeue.c
字號:
/*
* Copyright (c) 2000-2008
* Author: Weiming Zhou
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*/
#include <stdio.h>
#include <stdlib.h>
#include "CapiGlobal.h"
#include "DeQueue.h"
#define MIN_DEQUE_MAP_SIZE 16
#define MIN_DEQUE_BLOCK_SIZE 128
/** DeQue中的環形隊列創建函數
@param UINT uBlockSize - 環形隊列大小
@return DEQUEBLOCK * - 環形隊列指針
*/
DEQUEBLOCK *DeQueBlock_Create(UINT uBlockSize)
{
DEQUEBLOCK *pBlock;
pBlock = (DEQUEBLOCK *)malloc(sizeof(DEQUEBLOCK));
if ( pBlock != NULL )
{
pBlock->ppData = malloc(uBlockSize * sizeof(void *));
if ( pBlock->ppData == NULL )
{
free(pBlock);
return NULL;
}
pBlock->uHead = 0;
pBlock->uTail = 0;
}
return pBlock;
}
/** DeQue中的環形隊列釋放函數
@param DEQUE *pQue - DeQue指針
@param DEQUEBLOCK *pBlock - 環形隊列指針
@param DESTROYFUNC DestroyFunc - 數據釋放回調函數指針
@return void - 無
*/
void DeQueBlock_Destroy(DEQUE *pQue, DEQUEBLOCK *pBlock, DESTROYFUNC DestroyFunc)
{
UINT i;
if (pBlock != NULL)
{
if ( DestroyFunc != NULL )
{
if ( pBlock->uHead < pBlock->uTail )
{
for ( i = 0; i < pBlock->uTail; i++ )
{
(*DestroyFunc)( pBlock->ppData[i] );
}
for ( i = pBlock->uHead; i < pQue->uBlockSize; i++ )
{
(*DestroyFunc)( pBlock->ppData[i] );
}
}
else
{
for ( i = pBlock->uHead; i < pBlock->uTail; i++ )
{
(*DestroyFunc)( pBlock->ppData[i] );
}
}
}
free(pBlock->ppData);
free(pBlock);
}
}
/** DeQue的創建函數
@param UINT uMapSize - MAP的大小
@param UINT uBlockSize - 每個環形隊列的大小
@return DEQUE * - 返回創建的DeQue指針,失敗返回NULL
*/
DEQUE * DeQue_Create(UINT uMapSize, UINT uBlockSize)
{
DEQUE *pQue;
if ( uMapSize < MIN_DEQUE_MAP_SIZE )
{
uMapSize = MIN_DEQUE_MAP_SIZE;
}
if ( uBlockSize < MIN_DEQUE_BLOCK_SIZE )
{
uBlockSize = MIN_DEQUE_BLOCK_SIZE;
}
pQue = malloc(sizeof(DEQUE));
if ( pQue != NULL )
{
pQue->ppMap = malloc(uMapSize *sizeof(DEQUEBLOCK *));
if ( pQue->ppMap != NULL )
{
DEQUEBLOCK *pBlock = DeQueBlock_Create(uBlockSize);
if ( pBlock != NULL )
{
pBlock->uMapPos = uMapSize / 2;
pQue->ppMap[pBlock->uMapPos] = pBlock;
pQue->pLast = pBlock;
pQue->pFirst = pBlock;
pQue->uBlockSize = uBlockSize;
pQue->uMapSize = uMapSize;
}
else
{
free(pQue->ppMap);
free(pQue);
pQue = NULL;
}
}
else
{
free(pQue);
pQue = NULL;
}
}
return pQue;
}
/** DeQue的釋放函數
@param DEQUE *pQue - 要釋放的DeQue指針
@param DESTROYFUNC DestroyFunc - 數據釋放回調函數
@return void - 無
*/
void DeQue_Destroy( DEQUE *pQue, DESTROYFUNC DestroyFunc )
{
if ( pQue != NULL )
{
UINT i;
DEQUEBLOCK *pBlock;
for ( i = pQue->pFirst->uMapPos; i <= pQue->pLast->uMapPos; i++)
{
pBlock = pQue->ppMap[i];
DeQueBlock_Destroy(pQue, pBlock, DestroyFunc);
}
free(pQue->ppMap);
free(pQue);
}
}
/** DeQue的插入尾部函數
@param DEQUE *pQue - DeQue指針
@param void *pData - 要插入的數據指針
@return INT (by default) - CAPI_SUCCESS表示成功,CAPI_FAILED表示失敗
*/
INT DeQue_InsertTail( DEQUE *pQue, void *pData )
{
DEQUEBLOCK *pBlock;
UINT uTailNext;
pBlock= pQue->pLast;
/* 計算尾部節點的下一位置 */
if ( pBlock->uTail == pQue->uBlockSize - 1 )
{
uTailNext = 0;
}
else
{
uTailNext = pBlock->uTail + 1;
}
if ( pBlock->uHead != uTailNext ) /* 隊列未滿的情況 */
{
pBlock->ppData[pBlock->uTail] = pData;
pBlock->uTail = uTailNext;
}
else
{
DEQUEBLOCK *pNewBlock = DeQueBlock_Create(pQue->uBlockSize);
if ( pNewBlock == NULL )
{
return CAPI_FAILED;
}
if ( pBlock->uMapPos >= pQue->uMapSize - 1 )
{
/* 重新分配MAP */
DEQUEBLOCK **ppMap = malloc(pQue->uMapSize * 2 * sizeof(DEQUEBLOCK *));
if ( ppMap == NULL )
{
return CAPI_FAILED;
}
memcpy(ppMap, pQue->ppMap,
pQue->uMapSize * sizeof(DEQUEBLOCK *) );
pQue->uMapSize *= 2;
free(pQue->ppMap);
pQue->ppMap = ppMap;
}
pNewBlock->uMapPos = pBlock->uMapPos + 1;
pNewBlock->ppData[0] = pData;
pNewBlock->uTail += 1;
pQue->ppMap[pNewBlock->uMapPos] = pNewBlock;
pQue->pLast = pNewBlock;
}
return CAPI_SUCCESS;
}
/** DeQue的彈出頭部節點數據函數
@param DEQUE *pQue - DeQue指針
@return void * - 彈出的頭部數據指針
*/
void * DeQue_PopHead(DEQUE *pQue)
{
DEQUEBLOCK *pBlock;
UINT uHead;
pBlock = pQue->pFirst;
uHead = pBlock->uHead;
if ( uHead != pBlock->uTail )
{
/* 頭部和尾部沒有重合表示隊列不為空的情況 */
if ( uHead == pQue->uBlockSize - 1 )
{
pBlock->uHead = 0;
}
else
{
pBlock->uHead += 1;
}
if ( pBlock->uHead == pBlock->uTail )
{
/* 隊列中只有一個元素的情況, 如果存在下一塊則需要指向下一個塊 */
if ( pQue->pLast != pQue->pFirst )
{
UINT uMapPos = pBlock->uMapPos;
DeQueBlock_Destroy(pQue, pBlock, NULL);
pBlock = pQue->ppMap[uMapPos + 1];
pQue->pFirst = pBlock;
}
}
return pBlock->ppData[uHead];
}
else
{
return NULL;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -