isearch/comm/lqueue.h
2021-03-19 18:38:34 +08:00

161 lines
2.3 KiB
C++

#ifndef __LQUEUE_H__
#define __LQUEUE_H__
#include <malloc.h>
#include "../comm/compiler.h"
template<class T>
class CLinkQueue {
protected:
struct slot_t
{
slot_t *next;
T data;
};
public:
class allocator {
public:
inline allocator(int mc=1024){
freeList = NULL;
freecount = 0;
freemax = mc>60000?60000:mc;
}
inline ~allocator(){
free_cache();
}
private:
friend class CLinkQueue<T>;
unsigned short freecount;
unsigned short freemax;
slot_t *freeList;
__INLINE void free_cache() {
while(freeList) {
slot_t *s = freeList;
freeList = s->next;
freecount--;
free(s);
}
}
__INLINE slot_t *getslot(void)
{
slot_t *s;
if (likely(freeList)) {
s = freeList;
freeList = s->next;
freecount --;
} else {
s = (slot_t *)malloc(sizeof(slot_t));
}
return s;
}
__INLINE void putslot(slot_t *s)
{
if(unlikely(freecount >= freemax)) {
free(s);
} else {
s->next = freeList;
freeList = s;
freecount++;
}
}
};
public:
inline CLinkQueue (allocator *a=0)
{
count = 0;
head = NULL;
tail = &head;
alloc = a;
}
inline ~CLinkQueue () {
while(head) {
slot_t *s = head;
head = s->next;
free(s);
}
head = NULL;
tail = NULL;
}
__INLINE void SetAllocator(allocator *a) { alloc = a; }
__INLINE int QueueEmpty () const {
return count==0;
}
__INLINE int Count() const {
return count;
}
__INLINE T Front(void) const {
return head==NULL ? NULL : head->data;
}
__INLINE int Push (T p)
{
slot_t *s = getslot();
if(unlikely(s==NULL))
return -1;
count++;
s->data = p;
s->next = NULL;
*tail = s;
tail = &s->next;
return 0;
}
__INLINE int Unshift (T p)
{
slot_t *s = getslot();
if(s==NULL)
return -1;
count++;
s->data = p;
s->next = head;
if(head == NULL)
tail = &s->next;
head = s;
return 0;
}
__INLINE T Pop ()
{
if (head==NULL)
return (T)0;
slot_t *s = head;
head = s->next;
if(head == NULL)
tail = &head;
T ret = s->data;
putslot(s);
count--;
return ret;
}
protected:
allocator *alloc;
slot_t *head;
slot_t **tail;
int count;
private:
__INLINE slot_t *getslot(void) {
if(alloc) return alloc->getslot();
return (slot_t *)malloc(sizeof(slot_t));
}
__INLINE void putslot(slot_t *p) {
if(alloc){
alloc->putslot(p);
return;
};
free(p);
}
};
#endif