added linkedList and test for linkedList
This commit is contained in:
@@ -4,6 +4,7 @@ DIRS += misc
|
||||
DIRS += pv
|
||||
DIRS += factory
|
||||
DIRS += test
|
||||
DIRS += miscTest
|
||||
DIRS += pvTest
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
|
||||
@@ -3292,7 +3292,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
|
||||
for(int i=0; i < pvdata->getLength(); i++) {
|
||||
if(i!=0) *buffer += ",";
|
||||
int num = pvdata->get(i,1,&data);
|
||||
StringPtrArray value = data.data;
|
||||
StringArray value = data.data;
|
||||
if(num==1) {
|
||||
if(value[data.offset].length()>0) {
|
||||
*buffer += value[data.offset].c_str();
|
||||
|
||||
@@ -4,6 +4,8 @@ include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += pvType.h
|
||||
INC += noDefaultMethods.h
|
||||
INC += linkedListVoid.h
|
||||
INC += linkedList.h
|
||||
INC += lock.h
|
||||
INC += requester.h
|
||||
INC += serialize.h
|
||||
@@ -15,6 +17,7 @@ INC += serializeHelper.h
|
||||
LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += bitSet.cpp
|
||||
LIBSRCS += serializeHelper.cpp
|
||||
LIBSRCS += linkedListVoid.cpp
|
||||
|
||||
LIBRARY=pvMisc
|
||||
|
||||
|
||||
81
pvDataApp/misc/linkedList.h
Normal file
81
pvDataApp/misc/linkedList.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* linkedList.h */
|
||||
#ifndef LINKEDLIST_H
|
||||
#define LINKEDLIST_H
|
||||
#include "pvIntrospect.h"
|
||||
#include "linkedListVoid.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template <typename T>
|
||||
class LinkedList;
|
||||
|
||||
template <typename T>
|
||||
class LinkedListNode : private LinkedListVoidNode {
|
||||
public:
|
||||
LinkedListNode(T *object) : LinkedListVoidNode(object){}
|
||||
~LinkedListNode() {}
|
||||
T *getObject() { return (T *)LinkedListVoidNode::getObject();}
|
||||
bool isOnList() {return LinkedListVoidNode::isOnList();}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LinkedList : private LinkedListVoid {
|
||||
public:
|
||||
LinkedList() : LinkedListVoid() {}
|
||||
~LinkedList() {}
|
||||
int getLength() {return LinkedListVoid::getLength();}
|
||||
void addTail(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addTail((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void addHead(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addHead((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void insertAfter(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertAfter(
|
||||
(LinkedListVoidNode *)listNode,(LinkedListVoidNode *)addNode);
|
||||
}
|
||||
void insertBefore(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertBefore((LinkedListVoidNode *)listNode,
|
||||
(LinkedListVoidNode *)addNode);
|
||||
}
|
||||
LinkedListNode<T> *removeTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeTail();
|
||||
}
|
||||
LinkedListNode<T> *removeHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeHead();
|
||||
}
|
||||
void remove(LinkedListNode<T> *listNode){
|
||||
LinkedListVoid::remove((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void remove(T *object){
|
||||
LinkedListVoid::remove(object);
|
||||
}
|
||||
LinkedListNode<T> *getHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getHead();
|
||||
}
|
||||
LinkedListNode<T> *getTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getTail();
|
||||
}
|
||||
LinkedListNode<T> *getNext(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getNext(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
}
|
||||
LinkedListNode<T> *getPrev(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getPrev(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
}
|
||||
bool isEmpty() { return LinkedListVoid::isEmpty();}
|
||||
bool contains(T *object) { return LinkedListVoid::contains(object);}
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLIST_H */
|
||||
|
||||
|
||||
|
||||
249
pvDataApp/misc/linkedListVoid.cpp
Normal file
249
pvDataApp/misc/linkedListVoid.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* linkedListVoid.cpp */
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include "lock.h"
|
||||
#include "pvType.h"
|
||||
#include "pvIntrospect.h"
|
||||
#include "linkedListVoid.h"
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static volatile int64 totalNodeConstruct = 0;
|
||||
static volatile int64 totalNodeDestruct = 0;
|
||||
static volatile int64 totalListConstruct = 0;
|
||||
static volatile int64 totalListDestruct = 0;
|
||||
static Mutex *globalMutex = 0;
|
||||
static String alreadyOnList("already on list");
|
||||
|
||||
int64 LinkedListVoidNode::getTotalConstruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalNodeConstruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoidNode::getTotalDestruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalNodeDestruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoid::getTotalConstruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalListConstruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoid::getTotalDestruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalListDestruct;
|
||||
}
|
||||
|
||||
|
||||
void LinkedListVoid::init() {
|
||||
static Mutex mutex = Mutex();
|
||||
Lock xx(&mutex);
|
||||
if(globalMutex==0) globalMutex = new Mutex();
|
||||
}
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(void *object)
|
||||
: object(object),before(0),after(0)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalNodeConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(bool isHead)
|
||||
: object(this),before(this),after(this)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalNodeConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoidNode::~LinkedListVoidNode()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
totalNodeDestruct++;
|
||||
}
|
||||
|
||||
void *LinkedListVoidNode::getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
bool LinkedListVoidNode::isOnList()
|
||||
{
|
||||
if(before==0 && after==0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkedListVoid::LinkedListVoid()
|
||||
: head(new LinkedListVoidNode(true)),length(0)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalListConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoid::~LinkedListVoid()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
delete head;
|
||||
totalListDestruct++;
|
||||
}
|
||||
|
||||
int LinkedListVoid::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addTail(LinkedListVoidNode *node)
|
||||
{
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->before = head->before;
|
||||
node->after = head;
|
||||
head->before->after = node;
|
||||
head->before = node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addHead(LinkedListVoidNode *node)
|
||||
{
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->after = head->after;
|
||||
node->before = head;
|
||||
head->after->before = node;
|
||||
head->after = node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertAfter(LinkedListVoidNode *node,
|
||||
LinkedListVoidNode *addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = node;
|
||||
LinkedListVoidNode *newNode = addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
newNode->after = existingNode->after;
|
||||
newNode->before = existingNode;
|
||||
existingNode->after->before = newNode;
|
||||
existingNode->after = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertBefore(LinkedListVoidNode *node,
|
||||
LinkedListVoidNode *addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = node;
|
||||
LinkedListVoidNode *newNode = addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
newNode->after = existingNode;
|
||||
newNode->before = existingNode->before;
|
||||
existingNode->before->after = newNode;
|
||||
existingNode->before = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->before;
|
||||
remove(head->before);
|
||||
return node;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->after;
|
||||
remove(head->after);
|
||||
return node;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(LinkedListVoidNode *listNode)
|
||||
{
|
||||
LinkedListVoidNode *node = listNode;
|
||||
if(node->before==0 || node->after==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
LinkedListVoidNode *prev = node->before;
|
||||
LinkedListVoidNode *next = node->after;
|
||||
node->after = node->before = 0;
|
||||
prev->after = next;
|
||||
next->before = prev;
|
||||
length--;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(void * object)
|
||||
{
|
||||
LinkedListVoidNode *node = getHead();
|
||||
while(node!=0) {
|
||||
if(node->getObject()==object) {
|
||||
remove(node);
|
||||
return;
|
||||
}
|
||||
node = getNext(node);
|
||||
}
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->before;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->after==head) return 0;
|
||||
return listNode->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->before==head) return 0;
|
||||
return listNode->before;
|
||||
}
|
||||
|
||||
bool LinkedListVoid::isEmpty()
|
||||
{
|
||||
if(head->after==head) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LinkedListVoid::contains(void * object)
|
||||
{
|
||||
LinkedListVoidNode *node = getHead();
|
||||
while(node!=0) {
|
||||
if(node->getObject()==object) {
|
||||
return true;
|
||||
}
|
||||
node = getNext(node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
69
pvDataApp/misc/linkedListVoid.h
Normal file
69
pvDataApp/misc/linkedListVoid.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* linkedListVoid.h */
|
||||
#ifndef LINKEDLISTVOID_H
|
||||
#define LINKEDLISTVOID_H
|
||||
#include "pvIntrospect.h"
|
||||
#include "noDefaultMethods.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class LinkedListVoid;
|
||||
class LinkedListVoidNode;
|
||||
|
||||
class LinkedListVoidNode {
|
||||
public:
|
||||
~LinkedListVoidNode();
|
||||
static int64 getTotalConstruct();
|
||||
static int64 getTotalDestruct();
|
||||
void *getObject();
|
||||
bool isOnList();
|
||||
protected:
|
||||
LinkedListVoidNode(void *object);
|
||||
private:
|
||||
LinkedListVoidNode(bool isHead);
|
||||
friend class LinkedListVoid;
|
||||
void *object;
|
||||
LinkedListVoidNode *before;
|
||||
LinkedListVoidNode *after;
|
||||
// do not implement the following
|
||||
LinkedListVoidNode(const LinkedListVoidNode&);
|
||||
LinkedListVoidNode & operator=(const LinkedListVoidNode&);
|
||||
};
|
||||
|
||||
class LinkedListVoid {
|
||||
public:
|
||||
~LinkedListVoid();
|
||||
static int64 getTotalConstruct();
|
||||
static int64 getTotalDestruct();
|
||||
int getLength();
|
||||
void addTail(LinkedListVoidNode *listNode);
|
||||
void addHead(LinkedListVoidNode *listNode);
|
||||
void insertAfter(LinkedListVoidNode *listNode,
|
||||
LinkedListVoidNode *addNode);
|
||||
void insertBefore(LinkedListVoidNode *listNode,
|
||||
LinkedListVoidNode *addNode);
|
||||
LinkedListVoidNode *removeTail();
|
||||
LinkedListVoidNode *removeHead();
|
||||
void remove(LinkedListVoidNode *listNode);
|
||||
void remove(void * object);
|
||||
LinkedListVoidNode *getHead();
|
||||
LinkedListVoidNode *getTail();
|
||||
LinkedListVoidNode *getNext(LinkedListVoidNode *listNode);
|
||||
LinkedListVoidNode *getPrev(LinkedListVoidNode *listNode);
|
||||
bool isEmpty();
|
||||
bool contains(void * object);
|
||||
protected:
|
||||
LinkedListVoid();
|
||||
private:
|
||||
static void init();
|
||||
friend class LinkedListVoidNode;
|
||||
LinkedListVoidNode *head;
|
||||
int length;
|
||||
// do not implement the following
|
||||
LinkedListVoid(const LinkedListVoid&);
|
||||
LinkedListVoid & operator=(const LinkedListVoid&);
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLISTVOID_H */
|
||||
|
||||
|
||||
|
||||
12
pvDataApp/miscTest/Makefile
Normal file
12
pvDataApp/miscTest/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += testLinkedList
|
||||
testLinkedList_SRCS += testLinkedList.cpp
|
||||
testLinkedList_LIBS += pvMisc Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
451
pvDataApp/miscTest/testLinkedList.cpp
Normal file
451
pvDataApp/miscTest/testLinkedList.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* * testLinkedList.cpp
|
||||
* *
|
||||
* * Created on: 2010.11
|
||||
* * Author: Marty Kraimer
|
||||
* */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <list>
|
||||
|
||||
#include <epicsTime.h>
|
||||
#include <epicsAssert.h>
|
||||
|
||||
#include "lock.h"
|
||||
#include "linkedList.h"
|
||||
#include "pvIntrospect.h"
|
||||
#include "pvData.h"
|
||||
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
static int numNodes = 5;
|
||||
class Basic;
|
||||
typedef LinkedListNode<Basic> BasicListNode;
|
||||
typedef LinkedList<Basic> BasicList;
|
||||
|
||||
class Basic {
|
||||
public:
|
||||
Basic(int i): index(i),node(new BasicListNode(this)) {}
|
||||
~Basic() { delete node;}
|
||||
int index;
|
||||
BasicListNode*node;
|
||||
};
|
||||
|
||||
static void testBasic(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
basicList->addTail(basics[i]->node);
|
||||
assert(basicList->getLength()==i+1);
|
||||
}
|
||||
BasicListNode *basicNode = basicList->getHead();
|
||||
fprintf(fd,"basic addTail");
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->getNext(basicNode);
|
||||
}
|
||||
assert(basicList->isEmpty()==false);
|
||||
basicNode = basicList->getTail();
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
assert(basicList->contains(basicNode->getObject()));
|
||||
basicNode = basicList->getPrev(basicNode);
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
Basic *basic = basicList->getHead()->getObject();
|
||||
assert(basic->index==i);
|
||||
assert(basics[i]->node->isOnList()==true);
|
||||
basicList->remove(basics[i]);
|
||||
assert(basics[i]->node->isOnList()==false);
|
||||
int length = basicList->getLength();
|
||||
assert(length==(numNodes-i-1));
|
||||
}
|
||||
assert(basicList->isEmpty());
|
||||
for(int i=numNodes-1; i>=0; i--) {
|
||||
basicList->addHead(basics[i]->node);
|
||||
assert(basicList->getLength()==numNodes-i);
|
||||
}
|
||||
basicNode = basicList->getHead();
|
||||
fprintf(fd,"basic addHead");
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->getNext(basicNode);
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
Basic *basic = basicList->getHead()->getObject();
|
||||
assert(basic->index==i);
|
||||
basicList->removeHead();
|
||||
assert(basic->node->isOnList()==false);
|
||||
int length = basicList->getLength();
|
||||
assert(length==(numNodes-i-1));
|
||||
}
|
||||
assert(basicList->isEmpty());
|
||||
basicList->addTail(basics[0]->node);
|
||||
basicNode = basicList->getTail();
|
||||
assert(basicNode->getObject()->index==0);
|
||||
for(int i=1;i<numNodes;i++) {
|
||||
basicList->insertAfter(basicNode,basics[i]->node);
|
||||
basicNode = basicList->getTail();
|
||||
assert(basicList->getLength()==i+1);
|
||||
}
|
||||
fprintf(fd,"basic addTail insertAfter");
|
||||
basicNode = basicList->getHead();
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->getNext(basicNode);
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
for(int i=numNodes-1; i>=0; i--) {
|
||||
Basic *basic = basicList->getTail()->getObject();
|
||||
assert(basic->index==i);
|
||||
basicList->removeTail();
|
||||
assert(basic->node->isOnList()==false);
|
||||
int length = basicList->getLength();
|
||||
assert(length==i);
|
||||
}
|
||||
assert(basicList->isEmpty());
|
||||
basicList->addHead(basics[numNodes-1]->node);
|
||||
basicNode = basicList->getHead();
|
||||
assert(basicNode->getObject()->index==4);
|
||||
for(int i=numNodes-2; i>=0; i--) {
|
||||
basicList->insertBefore(basicNode,basics[i]->node);
|
||||
basicNode = basicList->getHead();
|
||||
assert(basicList->getLength()==numNodes-i);
|
||||
}
|
||||
fprintf(fd,"basic addTail insertBefore");
|
||||
basicNode = basicList->getHead();
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->getNext(basicNode);
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
for(int i=numNodes-1; i>=0; i--) {
|
||||
Basic *basic = basicList->getTail()->getObject();
|
||||
assert(basic->index==i);
|
||||
basicList->remove(basic);
|
||||
assert(basic->node->isOnList()==false);
|
||||
int length = basicList->getLength();
|
||||
assert(length==i);
|
||||
}
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testQueue(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
fprintf(fd,"\nQueue test\n");
|
||||
for(int i=0;i<numNodes;i++) {
|
||||
basicList->addTail(basics[i]->node);
|
||||
assert(basicList->getLength()==i+1);
|
||||
}
|
||||
BasicListNode *basicNode = basicList->removeHead();
|
||||
while(basicNode!=0) basicNode = basicList->removeHead();
|
||||
for(int i=0;i<numNodes;i++) basicList->addTail(basics[i]->node);
|
||||
basicNode = basicList->removeHead();
|
||||
fprintf(fd,"queue");
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testStack(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
fprintf(fd,"\nStack test\n");
|
||||
for(int i=0;i<numNodes;i++) {
|
||||
basicList->addHead(basics[i]->node);
|
||||
assert(basicList->getLength()==i+1);
|
||||
}
|
||||
BasicListNode *basicNode = basicList->removeHead();
|
||||
while(basicNode!=0) basicNode = basicList->removeHead();
|
||||
for(int i=0;i<numNodes;i++) basicList->addHead(basics[i]->node);
|
||||
basicNode = basicList->removeHead();
|
||||
fprintf(fd,"stack");
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testList(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
fprintf(fd,"\ntestList\n");
|
||||
for(int i=0;i<numNodes;i++) basicList->addTail(basics[i]->node);
|
||||
fprintf(fd,"list");
|
||||
BasicListNode *basicNode = basicList->removeHead();
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testRandomInsertRemove(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
fprintf(fd,"\nRandom insert/remove test\n");
|
||||
basicList->addHead(basics[4]->node);
|
||||
basicList->insertAfter(basics[4]->node,basics[3]->node);
|
||||
basicList->insertAfter(basics[3]->node,basics[2]->node);
|
||||
basicList->addTail(basics[1]->node);
|
||||
basicList->addTail(basics[0]->node);
|
||||
BasicListNode *basicNode = basicList->removeHead();
|
||||
fprintf(fd,"stack");
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testOrderedQueue(FILE * fd ) {
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
BasicListNode *basicNode = 0;
|
||||
fprintf(fd,"\nOrdered Queue test\n");
|
||||
basicList->addHead(basics[2]->node);
|
||||
for(int i=0;i<numNodes;i++) {
|
||||
if(basicList->contains(basics[i]->node->getObject())) continue;
|
||||
basicNode = basicList->getHead();
|
||||
while(basicNode!=0) {
|
||||
if(basicNode->getObject()->index>=basics[i]->index) {
|
||||
basicList->insertBefore(basicNode,basics[i]->node);
|
||||
break;
|
||||
}
|
||||
basicNode = basicList->getNext(basicNode);
|
||||
}
|
||||
if(basicList->contains(basics[i]->node->getObject())) continue;
|
||||
basicList->addTail(basics[i]->node);
|
||||
}
|
||||
fprintf(fd,"list");
|
||||
basicNode = basicList->removeHead();
|
||||
while(basicNode!=0) {
|
||||
fprintf(fd," %d",basicNode->getObject()->index);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testTime() {
|
||||
epicsTimeStamp startTime;
|
||||
epicsTimeStamp endTime;
|
||||
int numNodes = 1000;
|
||||
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
printf("\nTime test\n");
|
||||
int ntimes = 1000;
|
||||
epicsTimeGetCurrent(&startTime);
|
||||
for(int i=0; i<ntimes; i++) {
|
||||
for(int j=0;j<numNodes;j++) basicList->addTail(basics[j]->node);
|
||||
BasicListNode *basicNode = basicList->removeHead();
|
||||
while(basicNode!=0) basicNode = basicList->removeHead();
|
||||
}
|
||||
epicsTimeGetCurrent(&endTime);
|
||||
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
|
||||
diff *= 1000.0;
|
||||
printf("diff %f milliSeconds\n",diff);
|
||||
diff = diff/1000.0; // convert from milliseconds to seconds
|
||||
diff = diff/ntimes; // seconds per outer loop
|
||||
diff = diff*1e6; // converty to microseconds
|
||||
printf("time per iteration %f microseconds\n",diff);
|
||||
diff = diff/(numNodes*2); // convert to per addTail/removeHead
|
||||
printf("time per addTail/removeHead %f microseconds\n",diff);
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testTimeLocked() {
|
||||
epicsTimeStamp startTime;
|
||||
epicsTimeStamp endTime;
|
||||
Mutex *mutex = new Mutex();
|
||||
int numNodes = 1000;
|
||||
|
||||
LinkedList<Basic> *basicList = new BasicList();
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
printf("\nTime test locked\n");
|
||||
int ntimes = 1000;
|
||||
epicsTimeGetCurrent(&startTime);
|
||||
for(int i=0; i<ntimes; i++) {
|
||||
for(int j=0;j<numNodes;j++) {
|
||||
Lock xx(mutex);
|
||||
basicList->addTail(basics[j]->node);
|
||||
}
|
||||
BasicListNode *basicNode = 0;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
while(basicNode!=0) {
|
||||
Lock xx(mutex);
|
||||
basicNode = basicList->removeHead();
|
||||
}
|
||||
}
|
||||
epicsTimeGetCurrent(&endTime);
|
||||
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
|
||||
diff *= 1000.0;
|
||||
printf("diff %f milliSeconds\n",diff);
|
||||
diff = diff/1000.0; // convert from milliseconds to seconds
|
||||
diff = diff/ntimes; // seconds per outer loop
|
||||
diff = diff*1e6; // converty to microseconds
|
||||
printf("time per iteration %f microseconds\n",diff);
|
||||
diff = diff/(numNodes*2); // convert to per addTail/removeHead
|
||||
printf("time per addTail/removeHead %f microseconds\n",diff);
|
||||
assert(basicList->isEmpty());
|
||||
delete basicList;
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
typedef std::list<Basic *> stdList;
|
||||
static void testArrayListTime() {
|
||||
epicsTimeStamp startTime;
|
||||
epicsTimeStamp endTime;
|
||||
int numNodes = 1000;
|
||||
|
||||
stdList basicList;
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
printf("\nTime ArrayList test\n");
|
||||
int ntimes = 1000;
|
||||
epicsTimeGetCurrent(&startTime);
|
||||
for(int i=0; i<ntimes; i++) {
|
||||
for(int j=0;j<numNodes;j++) basicList.push_back(basics[j]);
|
||||
while(basicList.size()>0) {
|
||||
basicList.begin();
|
||||
basicList.pop_front();
|
||||
}
|
||||
}
|
||||
epicsTimeGetCurrent(&endTime);
|
||||
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
|
||||
diff *= 1000.0;
|
||||
printf("diff %f milliSeconds\n",diff);
|
||||
diff = diff/1000.0; // convert from milliseconds to seconds
|
||||
diff = diff/ntimes; // seconds per outer loop
|
||||
diff = diff*1e6; // converty to microseconds
|
||||
printf("time per iteration %f microseconds\n",diff);
|
||||
diff = diff/(numNodes*2); // convert to per addTail/removeHead
|
||||
printf("time per addTail/removeHead %f microseconds\n",diff);
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
static void testArrayListTimeLocked() {
|
||||
epicsTimeStamp startTime;
|
||||
epicsTimeStamp endTime;
|
||||
int numNodes = 1000;
|
||||
Mutex *mutex = new Mutex();
|
||||
|
||||
stdList basicList;
|
||||
Basic *basics[numNodes];
|
||||
for(int i=0; i<numNodes; i++) {
|
||||
basics[i] = new Basic(i);
|
||||
}
|
||||
printf("\nTime ArrayList test locked\n");
|
||||
int ntimes = 1000;
|
||||
epicsTimeGetCurrent(&startTime);
|
||||
for(int i=0; i<ntimes; i++) {
|
||||
for(int j=0;j<numNodes;j++) {
|
||||
Lock xx(mutex);
|
||||
basicList.push_back(basics[j]);
|
||||
}
|
||||
while(basicList.size()>0) {
|
||||
Lock xx(mutex);
|
||||
basicList.begin();
|
||||
basicList.pop_front();
|
||||
}
|
||||
}
|
||||
epicsTimeGetCurrent(&endTime);
|
||||
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
|
||||
diff *= 1000.0;
|
||||
printf("diff %f milliSeconds\n",diff);
|
||||
diff = diff/1000.0; // convert from milliseconds to seconds
|
||||
diff = diff/ntimes; // seconds per outer loop
|
||||
diff = diff*1e6; // converty to microseconds
|
||||
printf("time per iteration %f microseconds\n",diff);
|
||||
diff = diff/(numNodes*2); // convert to per addTail/removeHead
|
||||
printf("time per addTail/removeHead %f microseconds\n",diff);
|
||||
for(int i=0; i<numNodes; i++) delete basics[i];
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char *fileName = 0;
|
||||
if(argc>1) fileName = argv[1];
|
||||
FILE * fd = stdout;
|
||||
if(fileName!=0 && fileName[0]!=0) {
|
||||
fd = fopen(fileName,"w+");
|
||||
}
|
||||
testBasic(fd);
|
||||
testQueue(fd);
|
||||
testStack(fd);
|
||||
testList(fd);
|
||||
testRandomInsertRemove(fd);
|
||||
testOrderedQueue(fd);
|
||||
testTime();
|
||||
testTimeLocked();
|
||||
testArrayListTime();
|
||||
testArrayListTimeLocked();
|
||||
int totalConstructList = LinkedListVoid::getTotalConstruct();
|
||||
int totalDestructList = LinkedListVoid::getTotalDestruct();
|
||||
int totalConstructListNode = LinkedListVoidNode::getTotalConstruct();
|
||||
int totalDestructListNode = LinkedListVoidNode::getTotalDestruct();
|
||||
fprintf(fd,"totalConstructList %d totalDestructList %d",
|
||||
totalConstructList,totalDestructList);
|
||||
fprintf(fd," totalConstructListNode %d totalDestructListNode %d\n",
|
||||
totalConstructListNode,totalDestructListNode);
|
||||
assert(totalConstructList==totalDestructList);
|
||||
assert(totalConstructListNode==totalDestructListNode);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -38,9 +38,20 @@ namespace epics { namespace pvData {
|
||||
class PVStructure;
|
||||
class PVStructureArray;
|
||||
|
||||
|
||||
typedef std::map<String,PVScalar * > PVScalarMap;
|
||||
typedef PVScalarMap::const_iterator PVScalarMapIter;
|
||||
typedef PVStructure * PVStructurePtr;
|
||||
typedef PVStructurePtr* PVStructurePtrArray;
|
||||
typedef PVField* PVFieldPtr;
|
||||
typedef PVFieldPtr * PVFieldPtrArray;
|
||||
typedef bool * BooleanArray;
|
||||
typedef int8 * ByteArray;
|
||||
typedef int16 * ShortArray;
|
||||
typedef int32 * IntArray;
|
||||
typedef int64 * LongArray;
|
||||
typedef float * FloatArray;
|
||||
typedef double * DoubleArray;
|
||||
typedef String * StringArray;
|
||||
|
||||
class PVAuxInfo : private NoDefaultMethods {
|
||||
public:
|
||||
@@ -147,8 +158,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
typedef PVStructure * PVStructurePtr;
|
||||
typedef PVStructurePtr* PVStructurePtrArray;
|
||||
class StructureArrayData {
|
||||
public:
|
||||
PVStructurePtrArray data;
|
||||
@@ -177,8 +186,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
typedef PVField* PVFieldPtr;
|
||||
typedef PVFieldPtr * PVFieldPtrArray;
|
||||
|
||||
class PVStructure : public PVField,public BitSetSerializable {
|
||||
public:
|
||||
@@ -311,8 +318,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
typedef bool * BooleanArray;
|
||||
class BooleanArrayData {
|
||||
public:
|
||||
BooleanArray data;
|
||||
@@ -334,7 +339,6 @@ namespace epics { namespace pvData {
|
||||
};
|
||||
|
||||
|
||||
typedef int8 * ByteArray;
|
||||
class ByteArrayData {
|
||||
public:
|
||||
ByteArray data;
|
||||
@@ -355,8 +359,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
typedef int16 * ShortArray;
|
||||
class ShortArrayData {
|
||||
public:
|
||||
ShortArray data;
|
||||
@@ -377,7 +379,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
typedef int32 * IntArray;
|
||||
class IntArrayData {
|
||||
public:
|
||||
IntArray data;
|
||||
@@ -398,8 +399,6 @@ namespace epics { namespace pvData {
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
typedef int64 * LongArray;
|
||||
class LongArrayData {
|
||||
public:
|
||||
LongArray data;
|
||||
@@ -421,7 +420,6 @@ namespace epics { namespace pvData {
|
||||
};
|
||||
|
||||
|
||||
typedef float * FloatArray;
|
||||
class FloatArrayData {
|
||||
public:
|
||||
FloatArray data;
|
||||
@@ -443,7 +441,6 @@ namespace epics { namespace pvData {
|
||||
};
|
||||
|
||||
|
||||
typedef double * DoubleArray;
|
||||
class DoubleArrayData {
|
||||
public:
|
||||
DoubleArrayData(){}
|
||||
@@ -467,10 +464,9 @@ namespace epics { namespace pvData {
|
||||
};
|
||||
|
||||
|
||||
typedef String * StringPtrArray;
|
||||
class StringArrayData {
|
||||
public:
|
||||
StringPtrArray data;
|
||||
StringArray data;
|
||||
int offset;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,3 +6,4 @@ system ("./testIntrospect.pl");
|
||||
system ("./testPVData.pl");
|
||||
system ("./testPVStructureArray.pl");
|
||||
system ("./testPVAuxInfo.pl");
|
||||
system ("./testLinkedList.pl");
|
||||
|
||||
20
test/testLinkedList
Normal file
20
test/testLinkedList
Normal file
@@ -0,0 +1,20 @@
|
||||
basic addTail 0 1 2 3 4 4 3 2 1 0
|
||||
basic addHead 0 1 2 3 4
|
||||
basic addTail insertAfter 0 1 2 3 4
|
||||
basic addTail insertBefore 0 1 2 3 4
|
||||
|
||||
Queue test
|
||||
queue 0 1 2 3 4
|
||||
|
||||
Stack test
|
||||
stack 4 3 2 1 0
|
||||
|
||||
testList
|
||||
list 0 1 2 3 4
|
||||
|
||||
Random insert/remove test
|
||||
stack 4 3 2 1 0
|
||||
|
||||
Ordered Queue test
|
||||
list 0 1 2 3 4
|
||||
totalConstructList 8 totalDestructList 8 totalConstructListNode 4038 totalDestructListNode 4038
|
||||
12
test/testLinkedList.pl
Executable file
12
test/testLinkedList.pl
Executable file
@@ -0,0 +1,12 @@
|
||||
eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
if $running_under_some_shell; # testLinkedList.pl
|
||||
$EPICS_HOST_ARCH = "linux-x86";
|
||||
system ("rm testLinkedList");
|
||||
system ("rm testLinkedListDiff");
|
||||
system ("../bin/${EPICS_HOST_ARCH}/testLinkedList testLinkedList");
|
||||
system ("diff testLinkedList testLinkedListGold >> testLinkedListDiff");
|
||||
if(-z "testLinkedListDiff") {
|
||||
print "testLinkedList OK\n";
|
||||
} else {
|
||||
print "testLinkedList Failed\n";
|
||||
}
|
||||
0
test/testLinkedListDiff
Normal file
0
test/testLinkedListDiff
Normal file
20
test/testLinkedListGold
Normal file
20
test/testLinkedListGold
Normal file
@@ -0,0 +1,20 @@
|
||||
basic addTail 0 1 2 3 4 4 3 2 1 0
|
||||
basic addHead 0 1 2 3 4
|
||||
basic addTail insertAfter 0 1 2 3 4
|
||||
basic addTail insertBefore 0 1 2 3 4
|
||||
|
||||
Queue test
|
||||
queue 0 1 2 3 4
|
||||
|
||||
Stack test
|
||||
stack 4 3 2 1 0
|
||||
|
||||
testList
|
||||
list 0 1 2 3 4
|
||||
|
||||
Random insert/remove test
|
||||
stack 4 3 2 1 0
|
||||
|
||||
Ordered Queue test
|
||||
list 0 1 2 3 4
|
||||
totalConstructList 8 totalDestructList 8 totalConstructListNode 4038 totalDestructListNode 4038
|
||||
Reference in New Issue
Block a user