Files
cdev-1.7.2n/extensions/cdevGenericServer/include/MultiQueue.h
2022-12-13 12:44:04 +01:00

193 lines
4.2 KiB
C++

#ifndef __MULTIQUEUE_H_
#define __MULTIQUEUE_H_ 1
#include <stdlib.h>
#include <string.h>
class MultiQueueBase
{
private:
int nodeCount;
public:
MultiQueueBase ( void ) { nodeCount = 0; }
virtual void setTail ( void *tail ) = 0;
virtual int getCount ( void ) { return nodeCount; }
virtual int setCount ( int cnt ) { return (nodeCount = (cnt>=0?cnt:0)); }
virtual int incCount ( void ) { return (++nodeCount); }
virtual int decCount ( void ) { return (nodeCount=(nodeCount>0?nodeCount-1:0)); }
};
template <unsigned queueCount> class MultiQueueNode
{
private:
char * binary;
unsigned binaryLen;
public:
class MultiQueueBase *queue[queueCount];
class MultiQueueNode<queueCount> *prev [queueCount];
class MultiQueueNode<queueCount> *next [queueCount];
MultiQueueNode(char * Binary=NULL, size_t BinaryLen=0)
: binary(Binary), binaryLen(BinaryLen)
{
memset(queue, 0, sizeof(class MultiQueueBase *)*queueCount);
memset(prev, 0, sizeof(class MultiQueueNode<queueCount> *)*queueCount);
memset(next, 0, sizeof(class MultiQueueNode<queueCount> *)*queueCount);
}
virtual ~MultiQueueNode(void)
{
binary = NULL;
binaryLen = 0;
clear();
}
virtual void set ( char * Binary, size_t BinaryLen )
{
binary = Binary;
binaryLen = BinaryLen;
}
virtual void get ( char ** Binary, size_t * BinaryLen )
{
*Binary = binary;
*BinaryLen = binaryLen;
}
virtual void clear ( void )
{
for(int i=0; i<queueCount; i++)
{
if(prev[i]) prev [i]->next[i] = next[i];
if(next[i]) next [i]->prev[i] = prev[i];
else if(queue[i]) queue[i]->setTail(prev[i]);
if(queue[i]) queue[i]->decCount();
queue[i]=NULL;
prev[i] =NULL;
next[i] =NULL;
}
}
};
template <unsigned queueIndex, unsigned queueCount> class MultiQueue
: public MultiQueueBase
{
private:
MultiQueueNode<queueCount> head;
MultiQueueNode<queueCount> * tail;
public:
MultiQueue ( void )
{
tail = NULL;
}
virtual ~MultiQueue ( void )
{
MultiQueueNode<queueCount> * node;
while((node=dequeue())!=NULL) delete node;
}
virtual void setTail ( void * Tail )
{
tail = (MultiQueueNode<queueCount> *)Tail;
}
virtual int empty ( void ) { return (head.next[queueIndex]==NULL?1:0); }
virtual void enqueue ( MultiQueueNode<queueCount> * node )
{
if(node!=NULL)
{
if(head.next[queueIndex]==NULL)
{
head.next[queueIndex] = node;
node->prev[queueIndex] = &head;
}
else
{
tail->next[queueIndex] = node;
node->prev[queueIndex] = tail;
}
tail = node;
node->queue[queueIndex] = this;
node->queue[queueIndex]->incCount();
}
}
virtual MultiQueueNode<queueCount> * peek ( void )
{
return head.next[queueIndex];
}
virtual MultiQueueNode<queueCount> * dequeue ( void )
{
MultiQueueNode<queueCount> * node = head.next[queueIndex];
if(node!=NULL) node->clear();
return node;
}
virtual int peek ( char ** binary, size_t * binaryLen )
{
int result = -1;
MultiQueueNode<queueCount> * node;
if((node = peek())!=NULL)
{
node->get(binary, binaryLen);
if(*binary!=NULL && *binaryLen!=0) result = 0;
}
return result;
}
virtual int dequeue ( char ** binary, size_t * binaryLen )
{
int result = -1;
MultiQueueNode<queueCount> * node;
*binary = NULL;
*binaryLen = 0;
if((node = dequeue())!=NULL)
{
node->get(binary, binaryLen);
if(*binary!=NULL && *binaryLen!=0) result = 0;
delete node;
}
return result;
}
virtual MultiQueueNode<queueCount> * localDequeue ( void )
{
MultiQueueNode<queueCount> * node = head.next[queueIndex];
if(node!=NULL)
{
if(node->prev[queueIndex]!=NULL)
node->prev[queueIndex]->next[queueIndex] = node->next[queueIndex];
if(node->next[queueIndex]!=NULL)
node->next[queueIndex]->prev[queueIndex] = node->prev[queueIndex];
else if(node->queue[queueIndex]!=NULL)
{
node->queue[queueIndex]->setTail(node->prev);
node->queue[queueIndex]->decCount();
}
node->queue[queueIndex]=NULL;
node->next [queueIndex]=NULL;
node->prev [queueIndex]=NULL;
}
return node;
}
};
#endif /* __MULTIQUEUE_H_ */