Commit b68b8034 authored by Pavel Vainerman's avatar Pavel Vainerman

(2.0): Удалил неиспользуемые или устаревшие интерфейсы

parent 57778fb5
......@@ -352,6 +352,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
- possible use of the property 'iotype' in uniset-codegen
- refactoring <depends> mechanism
- add iofront=[01,10] to IOBase
- remove deprecated interfaces (Storages,CycleStorage,TableStorage,TextIndex,..)
* Tue Dec 10 2013 Pavel Vainerman <pv@altlinux.ru> 1.7-alt3
- add RRDServer
......
......@@ -217,7 +217,6 @@ AC_CONFIG_FILES([Makefile
include/Makefile
include/modbus/Makefile
tests/Makefile
tests/JrnTests/Makefile
tests/UniXmlTest/Makefile
docs/Makefile
docs/UniSetDox.cfg
......
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
*/
// --------------------------------------------------------------------------
#ifndef StorageInterface_H_
#define StorageInterface_H_
// ---------------------------------------------------------------------------
#include "IOController_i.hh"
// ---------------------------------------------------------------------------
/*! */
class StorageInterface
{
public:
StorageInterface(){};
virtual ~StorageInterface(){};
virtual IOController_i::DigitalIOInfo find( const IOController_i::SensorInfo& si )=0;
virtual void push( IOController_i::DigitalIOInfo& di )=0;
virtual void remove(const IOController_i::SensorInfo& si)=0;
virtual bool getState(const IOController_i::SensorInfo& si)=0;
virtual long getValue(const IOController_i::SensorInfo& si)=0;
virtual void saveState(const IOController_i::DigitalIOInfo& di,bool st)=0;
virtual void saveValue(const IOController_i::SensorIOInfo& ai, long val)=0;
protected:
private:
};
// ---------------------------------------------------------------------------
class STLStorage:
public StorageInterface
{
public:
STLStorage();
~STLStorage();
virtual IOController_i::DigitalIOInfo find( const IOController_i::SensorInfo& si );
virtual void push( IOController_i::DigitalIOInfo& di );
virtual void remove(const IOController_i::SensorInfo& si);
virtual bool getState(const IOController_i::SensorInfo& si);
virtual long getValue(const IOController_i::SensorInfo& si);
virtual void saveState(const IOController_i::DigitalIOInfo& di,bool st);
virtual void saveValue(const IOController_i::SensorIOInfo& ai, long val);
protected:
private:
};
// ---------------------------------------------------------------------------
#endif
// ---------------------------------------------------------------------------
/* This file is part of the UniSet project
* Copyright (c) 2009 Free Software Foundation, Inc.
* Copyright (c) 2009 Ivan Donchevskiy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Ivan Donchevskiy
*/
// --------------------------------------------------------------------------
#ifndef Storages_H_
#define Storages_H_
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <string>
/*! Эти 2 значения используются в TableBlockStorage как флаги для поля count, чтобы не вводить лишнее поле
в структуре TableBlockStorageElem */
#define EMPTY_BLOCK -5
#define EMPTY_ELEM -1
#define key_size 20
/*! Заголовок таблицы с элементами класса TableBlockStorage */
struct StorageAttr
{
int k_size, inf_size,size,block_number;
int lim, seekpos;
} __attribute__((__packed__));
/*! Заголовок журнала с элементами класса CycleStorage */
struct CycleStorageAttr
{
int size, inf_size, seekpos;
} __attribute__((__packed__));
/*! Основная структура класса TableStorage */
struct TableStorageElem
{
char status;
char key[key_size];
} __attribute__((__packed__));
/*! Основная структура класса TableBlockStorage */
struct TableBlockStorageElem
{
int count;
} __attribute__((__packed__));
/*! Основная структура класса CycleStorage */
struct CycleStorageElem
{
char status;
} __attribute__((__packed__));
class TableStorage
{
FILE *file;
int size,seekpos, inf_size;
int head;
public:
TableStorage(const char* name, int inf_sz, int sz, int seek);
~TableStorage();
int addRow(char* key, char* val);
int delRow(char* key);
char* findKeyValue(char* key, char* val);
};
class TableBlockStorage
{
public:
/*! Конструктор по умолчанию не открывает и не создает новой таблицы */
TableBlockStorage();
/*! Конструктор вызывает функцию Open, а при параметре create=true создает новую таблицу при
несовпадении заголовков или отсутствии старой */
TableBlockStorage(const char* name, int byte_sz, int key_sz, int inf_sz, int inf_count, int block_num, int block_lim, int seek, bool create=false);
~TableBlockStorage();
/*!
\param inf_sz - размер поля информации,
\param key_sz - размер поля ключа,
\param inf_count - кол-во записей в одном блоке таблицы (размером inf_sz+key_sz
+sizeof(int) на ключевое поле)
\param block_num - кол-во блоков (при этом кол-во записей во всей таблице = inf_count*block_num,
\param block_lim - число перезаписей на блок,
\param seek - отступ от начала файла (указывает место, где расположена таблица)
размер всей таблицы будет равен inf_count*block_num*(inf_sz+key_sz+sizeof(int)) +
sizeof(StorageAttr), где последнее слагаемое - размер заголовка,
размер можно получить, вызвав функцию getByteSize()
*/
bool open(const char* name, int byte_sz, int inf_sz, int key_sz, int inf_count, int block_num, int block_lim, int seek);
bool create(const char* name, int byte_sz, int inf_sz, int key_sz, int inf_count, int block_num, int block_lim, int seek);
/*! Добавление информации по ключу, возможна перезапись при совпадении ключа с существующим */
bool addRow(void* key, void* val);
/*! Удаление информации по ключу, фактически освобождения места не происходит, оно только помечается удаленным*/
bool delRow(void* key);
/*! Поиск информации по ключу, при неудаче возвращается 0 */
void* findKeyValue(void* key, void* val);
/*! Получение текущего блока (для тестовой программы) */
int getCurBlock(void);
inline int getByteSize() { return (size*full_size + sizeof(StorageAttr)); }
bool checkAttr( int key_sz, int inf_sz, int sz, int block_num, int block_lim, int seek );
protected:
FILE *file;
int inf_size;
private:
int max,cur_block;
TableBlockStorageElem* mem;
int k_size, lim,seekpos;
int size,block_size,block_number,full_size;
void filewrite(int seek, bool needflush=true);
bool copyToNextBlock();
bool keyCompare(int i, void* key);
void* keyPointer(int num);
void* valPointer(int num);
TableBlockStorageElem* elemPointer(int num);
};
class CycleStorage
{
public:
class CycleStorageIterator
{
public:
typedef CycleStorageIterator Self;
CycleStorageIterator():
str(NULL), cs(NULL), current(0) {}
CycleStorageIterator(CycleStorage* cstor)
{
cs = cstor;
current = 0;
}
CycleStorageIterator(CycleStorage* cstor, int num)
{
cs = cstor;
if( num<0 || num>=cs->getSize() ) current = 0;
current = num;
}
void* operator *() const
{
return str;
}
Self& operator++();
Self operator++(int);
Self& operator--();
Self operator--(int);
inline bool operator==(const Self& other) const
{
if( str==NULL || other.str==NULL )
{
if( str==NULL && other.str==NULL )
return true;
else
return false;
}
if( memcmp(str, other.str, cs->getInfSize())==0 )
return true;
return false;
}
inline bool operator!=(const Self& other) const
{
if( str==NULL || other.str==NULL )
{
if( str==NULL && other.str==NULL )
return false;
else
return true;
}
if( memcmp(str, other.str, cs->getInfSize())==0 )
return false;
return true;
}
private:
void* str;
CycleStorage* cs;
int current;
};
typedef CycleStorageIterator iterator;
/*! Конструктор по умолчанию не открывает и не создает нового журнала */
CycleStorage();
/*! Конструктор вызывает функцию Open, а при параметре create=true создает новый журнал при
несовпадении заголовков или отсутствии старого */
CycleStorage(const char* name, int byte_sz, int inf_sz, int inf_count, int seek,bool create=false);
~CycleStorage();
/*!
\param inf_sz - размер поля информации,
\param inf_count - количество записей (размером inf_sz +1 на ключевое поле)
\param seek - отступ от начала файла (указывает место, где расположен журнал)
размер всего журнала будет равен inf_count*(inf_sz+1) + sizeof(CycleStorageAttr),
где последнее слагаемое - размер заголовка
размер можно получить, вызвав функцию getByteSize()
*/
bool open(const char* name, int byte_sz, int inf_sz, int inf_count, int seek);
bool create(const char* name, int byte_sz, int inf_sz, int inf_count, int seek);
bool isOpen(){ return (file!=NULL); }
/*! Добавление информации в конец журнала */
bool addRow(void* str);
/*! Удаление информации с номером ряда row */
bool delRow(int row);
/*! Очистка журнала */
bool delAllRows(void);
/*! \return Функция возвращает информацию из ряда с номером num */
void* readRow(int num, void* str);
/*! Получение кол-ва итерации при поиске начала/конца журнала (для тестовой программы) */
int getIter(void);
/*! Изменение размера журнала (количества записей в нем) */
bool setSize(int count);
inline int getByteSize() { return (size*full_size + sizeof(CycleStorageAttr)); }
inline int getSize(){ return size; }
inline int getInfSize(){ return inf_size; }
inline int getFullSize(){ return full_size; }
bool checkAttr(int inf_sz, int inf_count, int seek);
inline int getHead(){ return head; }
inline int getTail(){ return tail; }
iterator begin()
{
return iterator(this);
}
iterator end()
{
return iterator(this,this->getTail());
}
protected:
FILE *file;
int inf_size;
int head,tail;
private:
int size,seekpos, iter;
int full_size;
void filewrite(CycleStorageElem* jrn,int seek, bool needflush=true);
void* valPointer(void* pnt);
bool findHead();
};
#endif
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*! \file
* \author Vitaly Lipatov
* \par
* Базовый класс получения строки по её индексу
*/
#include <string>
class TextDBIndex
{
public:
virtual ~TextDBIndex(){}
// Получить строку по коду
virtual std::string getText(int id){ return ""; }
};
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*! \file
* \author Vitaly Lipatov
* \par
* Базовый класс получения строки по её индексу
*/
#include <string>
class TextIndex
{
public:
virtual ~TextIndex(){}
// Получить строку по коду
virtual std::string getText(int id)=0;
};
/* This file is part of the UniSet project
* Copyright (c) 2009 Free Software Foundation, Inc.
* Copyright (c) 2009 Ivan Donchevskiy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Ivan Donchevskiy
*/
// --------------------------------------------------------------------------
/*! Функции класса CycleStorage, циклически переписываемого журнала,
перезаписываются самые старые элемениты при полном заполнении журнала
*/
#include "Storages.h"
CycleStorage::CycleStorage()
{
file=NULL;
}
CycleStorage::CycleStorage(const char* name, int byte_sz, int inf_sz, int inf_count, int seek, bool cr):
file(NULL)
{
if(!open(name, byte_sz, inf_sz, inf_count, seek))
{
if(cr)
create(name, byte_sz, inf_sz, inf_count, seek);
}
}
CycleStorage::~CycleStorage()
{
if( file!=NULL ) fclose(file);
}
void* CycleStorage::valPointer(void* pnt)
{
return (char*)pnt+sizeof(CycleStorageElem);
}
void CycleStorage::filewrite(CycleStorageElem* jrn,int seek,bool needflush)
{
fseek(file,seekpos+seek*full_size,0);
fwrite(jrn,full_size,1,file);
if(needflush)
fflush(file);
}
/*! Ищем голову и хвост по значениям jrn->status: 0 - пусто, 1 - гоова, 2,4 - два типа существующих элементов
(или 2 слева от головы - 4 справа, или наоборот), 3 - удаленный 2, 5 - удаленный 4, 6 - удаленный 1.
Для нахождения головы|хвоста используется двоичный поиск
*/
bool CycleStorage::findHead()
{
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
int l=-1,r=size,mid;
iter=0;
fread(jrn,full_size,1,file);
if(jrn->status==0)
{
head=-1;
tail=-1;
}
else if((jrn->status==1)||(jrn->status==6))
{
/*! Если первый элемент - голова списка */
head=0;
/*! В этом случае журнал может быть е полностью заполнен, поэтому хвост нужно искать */
while( (r-l)>1 )
{
mid = (l+r)/2;
fseek(file,seekpos+mid*full_size,0);
fread(jrn,full_size,1,file);
iter++;
if( jrn->status==0 )
r = mid;
else
l = mid;
}
tail = (r<size) ? (r-1) : (size-1);
}
else
{
int i,j;
/*! i равно или 2-ум, или 4-ем, в зависимости от этого слева головы списка 2-ки, а справа 4-ки
или наоборот */
i=jrn->status-jrn->status%2;
j = (i==2) ? 4 : 2;
while((jrn->status!=1)&&(jrn->status!=6)&&(r - l > 1))
{
mid = (l+r)/2;
fseek(file,seekpos+mid*full_size,0);
fread(jrn,full_size,1,file);
iter++;
if((jrn->status==i)||(jrn->status==i+1))
l = mid;
else if((jrn->status==j)||(jrn->status==j+1))
r = mid;
else if((jrn->status==1)||(jrn->status==6))
{
r=mid;
break;
}
else
{
delete[] jrn;
return false;
}
}
head = (r<size) ? r : (size-1);
/*! хвост списка на 1 левее головы, т.к. если голова не в начале, то журнал весь заполнен */
tail=head-1;
if(tail<0) tail=size-1;
}
delete[] jrn;
return true;
}
/*! Использовать для проверки совпадения заголовков */
bool CycleStorage::checkAttr(int inf_sz, int inf_count, int seek)
{
if( file==NULL ) return false;
if( fseek(file,seek,0)==-1 )
{
fclose(file);
file=NULL;
return false;
}
/*! Читаем заголовок */
CycleStorageAttr csa;
fread(&csa, sizeof(csa), 1, file);
/*! Проверяем заголовок на совпадение с нашими значениями */
if( ( csa.size!=inf_count ) || ( csa.inf_size!=inf_sz ) || ( csa.seekpos!=seek ) )
{
fclose(file);
file=NULL;
return false;
}
return true;
}
bool CycleStorage::open(const char* name, int byte_sz, int inf_sz, int inf_count, int seek)
{
/*! Если уже был открыт файл в переменной данного класса, он закрывается и открывается новый
*/
if( file!=NULL )
fclose(file);
file = fopen(name, "r+");
if( file==NULL ) return false;
if( fseek(file,seek,0)==-1 )
{
fclose(file);
file=NULL;
return false;
}
if( !checkAttr(inf_sz, inf_count, seek) )
return false;
inf_size=inf_sz;
full_size=sizeof(CycleStorageElem)+inf_size;
size=inf_count;
seekpos=seek+sizeof(CycleStorageAttr);
if( ( byte_sz<getByteSize() ) || !findHead() )
{
fclose(file);
file = NULL;
return false;
}
return true;
}
bool CycleStorage::create(const char* name, int byte_sz, int inf_sz, int inf_count, int seek)
{
if(file!=NULL) fclose(file);
file = fopen(name, "r+");
inf_size=inf_sz;
full_size=sizeof(CycleStorageElem)+inf_size;
size=inf_count;
iter=0;
seekpos=seek;
if( byte_sz<getByteSize() )
{
if( file!= NULL )
fclose(file);
file = NULL;
return false;
}
/*! Создаем файл, если его нет */
if(file==NULL)
{
FILE *f=fopen(name,"w");
if( f==NULL ) return false;
fclose(f);
file = fopen(name, "r+");
}
if( file==NULL ) return false;
if(fseek(file,seekpos,0)==-1) return false;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
for( int i=0; i<full_size; i++ )
*((char*)jrn+i) = 0;
jrn->status=0;
/*! Записываем заголовок журнала */
CycleStorageAttr csa;
csa.inf_size=inf_size;
csa.size=size;
csa.seekpos=seekpos;
fwrite(&csa,sizeof(CycleStorageAttr),1,file);
fflush(file);
seekpos+=sizeof(CycleStorageAttr);
/*! Создаем журнал нужного размера */
for(int i=0;i<size;i++)
{
filewrite(jrn,i,false);
}
fflush(file);
head=tail=-1;
delete[] jrn;
return true;
}
bool CycleStorage::addRow(void* str)
{
if(file==NULL) return false;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
int i=0;
for( i=0; i<full_size; i++ )
*((char*)jrn+i) = 0;
/*! Первые 2 случая - список пуст (head=-1), в списке 1 элемент(head=tail=0) рассматриваю отдельно)
*/
memcpy(valPointer(jrn),str,inf_size);
if(head==-1)
{
jrn->status=1;
filewrite(jrn,0);
head=0;
tail=0;
delete[] jrn;
return true;
}
if(head==tail)
{
jrn->status=2;
filewrite(jrn,1);
tail=1;
delete[] jrn;
return true;
}
fseek(file,seekpos+tail*full_size,0);
fread(jrn,full_size,1,file);
/*! Статус элемента совпадает со статусом последнего элемента в журнале 2, 3 -> 2; 4, 5 -> 4
*/
i = ((jrn->status==2)||(jrn->status==3)) ? 2 : 4;
/*! Если последний элемент журнала в крайней правой позиции выделенной части файла,
переходим в начало части файла и инвертируем статус 2->4, 4->2
*/
if(tail==size-1)
{
fseek(file,seekpos,0);
tail=0;
i = (i==2) ? 4 : 2;
}
else tail++;
fread(jrn,full_size,1,file);
memcpy(valPointer(jrn),str,inf_size);
if(jrn->status==0)
{
jrn->status=2;
filewrite(jrn,tail);
}
else
{
/*! Переписываем головной элемент новым, а второй от начала делаем головным,
т. е. сдвигаем голову на 1 элемент вперед
*/
head++;
if(head>=size) head=0;
jrn->status=i;
filewrite(jrn,tail);
fseek(file,seekpos+head*full_size,0);
fread(jrn,full_size,1,file);
if((jrn->status==3)||(jrn->status==5)) jrn->status=6;
else jrn->status=1;
filewrite(jrn,head);
}
delete[] jrn;
return true;
}
bool CycleStorage::delRow(int row)
{
int i=(head+row)%size,j;
if( row >= size ) return false;
if(file==NULL) return false;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
fseek(file,seekpos+i*full_size,0);
fread(jrn,full_size,1,file);
/*! При удалении меняем стутус 1->6, 2->3, 4->5 или возвращаем false
*/
if(jrn->status==1)
{
jrn->status=6;
filewrite(jrn,i);
delete[] jrn;
return true;
}
if(jrn->status==2) j=3;
else if(jrn->status==4) j=5;
else
{
delete[] jrn;
return false;
}
jrn->status=j;
filewrite(jrn,i);
delete[] jrn;
return true;
}
bool CycleStorage::delAllRows()
{
/*! Переписываем статусы всех элементов нулями */
if(file==NULL) return false;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
int i;
fseek(file,seekpos,0);
for(i=0;i<size;i++)
{
fread(jrn,full_size,1,file);
if(jrn->status!=0)
{
jrn->status=0;
filewrite(jrn,i,false);
}
}
fflush(file);
head=tail=-1;
delete[] jrn;
return true;
}
/*! TODO: можно убрать из параметров str, просто возвращать значение */
void* CycleStorage::readRow(int num, void* str)
{
if( size <= 0 ) return NULL;
/*! Отсчитываем номер элемента от головы журнала */
int j=(head+num)%size;
if((file==NULL)||(num>=size)) return NULL;
if((head!=tail+1)&&(num>tail)&&(head!=tail)) return NULL;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
fseek(file,seekpos+j*full_size,0);
fread(jrn,full_size,1,file);
if((jrn->status==1)||(jrn->status==2)||(jrn->status==4))
{
memcpy(str,valPointer(jrn),inf_size);
delete[] jrn;
return str;
}
delete[] jrn;
return NULL;
}
int CycleStorage::getIter()
{
return iter;
}
/*! Функция для изменения размера журнала. Удаляет все записи, если новый размер меньше. Заполняет новое место
записями, аналогичными удаленным, если новый размер больше. Вызывать лучше не часто, т. к. переписывается заголовок
журнала, расположенный статически в одном месте */
bool CycleStorage::setSize(int count)
{
if( file==NULL ) return false;
if( count==size ) return true;
fseek(file,seekpos-sizeof(CycleStorageAttr),0);
/*! Записываем заголовок журнала */
CycleStorageAttr csa;
csa.inf_size=inf_size;
csa.size=count;
csa.seekpos=seekpos-sizeof(CycleStorageAttr);
fwrite(&csa,sizeof(CycleStorageAttr),1,file);
fflush(file);
if(count<size)
{
if( head>count-1 )
{
head = 0;
tail = count - 1;
}
if( tail>count-1 )
tail = count - 1;
size=count;
return true;
}
int num = count - size;
size = count;
CycleStorageElem *jrn = (CycleStorageElem*)new char[full_size];
if(( head==tail+1 ) || (( tail==size-num-1 ) && ( head==0 )))
{
if( head<size-num-1 )
fseek(file, seekpos + (size-num-1)*full_size, 0);
else
fseek(file, seekpos, 0);
fread(jrn, full_size, 1, file);
if(( jrn->status==2 ) || (jrn->status==3 ))
jrn->status = ( head<size-num-1 ) ? 3 : 5;
else if(( jrn->status==4 ) || (jrn->status==5 ))
jrn->status = ( head<size-num-1 ) ? 5 : 3;
else
{
delete[] jrn;
return false;
}
for( int i=num; i>0; i-- )
{
filewrite(jrn, size-i, false);
}
fflush(file);
if( head==0 )
tail = size-1;
}
else
{
jrn->status=0;
for( int i=num; i>0; i-- )
filewrite(jrn, size-i, false);
fflush(file);
}
delete[] jrn;
return true;
}
/*! Некоторые операции для итератора */
CycleStorage::iterator& CycleStorage::iterator::operator++()
{
current++;
if( current>=cs->getSize() )
{
str = NULL;
current = cs->getSize();
return *this;
}
cs->readRow(current,str);
return *this;
}
CycleStorage::iterator CycleStorage::iterator::operator++(int)
{
Self temp = *this;
temp.current++;
if(temp.current>=temp.cs->getSize())
{
temp.str = NULL;
temp.current = temp.cs->getSize();
return temp;
}
temp.cs->readRow(current,str);
return temp;
}
CycleStorage::iterator& CycleStorage::iterator::operator--()
{
current--;
if(current<=0)
{
str = NULL;
current = -1;;
return *this;
}
cs->readRow(current,str);
return *this;
}
CycleStorage::iterator CycleStorage::iterator::operator--(int)
{
Self temp = *this;
temp.current--;
if(temp.current<=0)
{
temp.str = NULL;
temp.current = -1;
return temp;
}
temp.cs->readRow(current,str);
return temp;
}
\ No newline at end of file
......@@ -5,11 +5,8 @@
noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc TextIndex.cc \
Restorer_XML.cc \
RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc \
WDTInterface.cc \
CycleStorage.cc TableStorage.cc TableBlockStorage.cc
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc \
Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc
include $(top_builddir)/conf/setting.mk
......
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include "StorageInterface.h"
#include "Configuration.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
// --------------------------------------------------------------------------
STLStorage::STLStorage()
{
}
STLStorage::~STLStorage()
{
}
// --------------------------------------------------------------------------
IOController_i::DigitalIOInfo STLStorage::find( const IOController_i::SensorInfo& si )
{
throw NameNotFound();
}
// --------------------------------------------------------------------------
void STLStorage::push( IOController_i::DigitalIOInfo& di )
{
}
// --------------------------------------------------------------------------
void STLStorage::remove(const IOController_i::SensorInfo& si)
{
}
// --------------------------------------------------------------------------
bool STLStorage::getState(const IOController_i::SensorInfo& si)
{
return false;
}
// --------------------------------------------------------------------------
long STLStorage::getValue(const IOController_i::SensorInfo& si)
{
return 0;
}
// --------------------------------------------------------------------------
void STLStorage::saveState(const IOController_i::DigitalIOInfo& di,bool st)
{
}
// --------------------------------------------------------------------------
void STLStorage::saveValue(const IOController_i::SensorIOInfo& ai, long val)
{
}
// --------------------------------------------------------------------------
/* This file is part of the UniSet project
* Copyright (c) 2009 Free Software Foundation, Inc.
* Copyright (c) 2009 Ivan Donchevskiy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Ivan Donchevskiy
*/
// --------------------------------------------------------------------------
/*! Функции класса TableBlockStorage, таблицы ключ-значение с ограниченным кол-вом перезаписей для
каждого блока памяти, при достижении предела, происходит переход в следующий блок
*/
#include "Storages.h"
TableBlockStorage::TableBlockStorage():
file(NULL),
mem(0)
{
}
TableBlockStorage::TableBlockStorage(const char* name, int byte_sz, int key_sz, int inf_sz, int inf_count, int block_num, int block_lim, int seek, bool cr):
file(NULL),
mem(0)
{
if(!open(name, byte_sz, key_sz, inf_sz, inf_count, block_num, block_lim, seek))
{
if(cr)
create(name, byte_sz, key_sz, inf_sz, inf_count, block_num, block_lim, seek);
else
file=NULL;
}
}
TableBlockStorage::~TableBlockStorage()
{
delete mem;
if(file!=NULL) fclose(file);
}
bool TableBlockStorage::keyCompare(int i, void* key)
{
return !memcmp((char*)elemPointer(i)+sizeof(TableBlockStorageElem),key,k_size);
}
TableBlockStorageElem* TableBlockStorage::elemPointer(int num)
{
return (TableBlockStorageElem*)((char*)mem+num*full_size);
}
void* TableBlockStorage::keyPointer(int num)
{
return (char*)elemPointer(num) + sizeof(TableBlockStorageElem);
}
void* TableBlockStorage::valPointer(int num)
{
return (char*)elemPointer(num) + sizeof(TableBlockStorageElem) + k_size;
}
void TableBlockStorage::filewrite(int seek, bool needflush)
{
/*! Запись элемента с номером i из памяти в текущий блок файла */
fseek(file,seekpos+(seek+cur_block*block_size)*full_size,0);
fwrite(elemPointer(seek),full_size,1,file);
if(needflush) fflush(file);
}
bool TableBlockStorage::copyToNextBlock(void)
{
/*! Переход на следующий блок файла */
max=-1;
int tmp=mem->count;
mem->count=EMPTY_BLOCK;
filewrite(0,false);
mem->count=tmp;
if(cur_block>=block_number-1)
cur_block=0;
else
cur_block++;
/*! Параллельно заново заполняются счетчики записей */
for(int i=0;i<block_size;i++)
{
if(elemPointer(i)->count>=0)
{
elemPointer(i)->count=++max;
filewrite(i,false);
}
}
fflush(file);
/*! если достигнут максимальный, возвращается false */
if(cur_block>=block_number-1)
return false;
return true;
}
/*! Использовать для проверки совпадения заголовков */
bool TableBlockStorage::checkAttr( int key_sz, int inf_sz, int inf_count, int block_num, int block_lim, int seek )
{
if( file==NULL ) return false;
int tmpsize=inf_count*block_num;
fseek(file, seek, 0);
/*! Чтение заголовка таблицы */
StorageAttr sa;
fread(&sa,sizeof(StorageAttr),1,file);
/*! Проверяем заголовок на совпадение с нашими значениями */
if((sa.k_size!=key_sz)||(sa.inf_size!=inf_sz)||(sa.size!=tmpsize)||(sa.block_number!=block_num)||(sa.lim!=block_lim)||(sa.seekpos!=seek))
{
fclose(file);
file=NULL;
return false;
}
return true;
}
bool TableBlockStorage::open(const char* name, int byte_sz, int key_sz, int inf_sz, int inf_count, int block_num, int block_lim, int seek)
{
/*! Если уже был открыт файл в переменной данного класса, он закрывается и открывается новый */
if(file!=NULL) fclose(file);
file = fopen(name, "r+");
if(file==NULL) return false;
seekpos=seek;
if(fseek(file,seekpos,0)==-1)
{
fclose(file);
file=NULL;
return false;
}
full_size = sizeof(TableBlockStorageElem)+key_sz+inf_sz;
if( !checkAttr(key_sz, inf_sz, inf_count, block_num, block_lim, seek ) )
return false;
k_size=key_sz;
inf_size=inf_sz;
lim=block_lim;
block_number=block_num;
block_size=inf_count;
size=block_size*block_num;
if( byte_sz<getByteSize() )
{
fclose(file);
file=NULL;
return false;
}
max=-1;
/*! Инициализация памяти */
mem = (TableBlockStorageElem*) new char[block_size*full_size];
TableBlockStorageElem *t = (TableBlockStorageElem*)new char[full_size];
seekpos+=sizeof(StorageAttr);
/*! Поиск непустого блока, либо если все пустые, текущий устанавливается 0 */
for(cur_block=0; cur_block < block_num; cur_block++)
{
fseek(file,seekpos+cur_block*block_size*(full_size),0);
fread(t,(full_size),1,file);
if(t->count >= 0)
break;
}
if( t->count < 0 )
cur_block = 0;
/*! Чтение в память из нужного блока */
fseek(file,seekpos+(cur_block*block_size)*(full_size),0);
for(int i=0;i<block_size;i++)
{
fread(elemPointer(i),(full_size),1,file);
if(elemPointer(i)->count>max) max=elemPointer(i)->count;
}
delete[] t;
return true;
}
bool TableBlockStorage::create(const char* name, int byte_sz, int key_sz, int inf_sz, int inf_count, int block_num, int block_lim, int seek)
{
if(file!=NULL) fclose(file);
file = fopen(name, "r+");
k_size=key_sz;
inf_size=inf_sz;
seekpos=seek;
lim=block_lim;
full_size = sizeof(TableBlockStorageElem)+k_size+inf_size;
int i;
block_number=block_num;
block_size=inf_count;
size=block_size*block_num;
max=-1;
if( byte_sz<getByteSize() )
{
if( file!=NULL ) fclose(file);
file=NULL;
return false;
}
if(file==NULL)
{
FILE *f=fopen(name,"w");
if( f==NULL ) return false;
fclose(f);
file = fopen(name, "r+");
}
if(fseek(file,seekpos,0)==-1) return false;
/*! Инициализация памяти */
mem = (TableBlockStorageElem*) new char[block_size*full_size];
for( i=0; i<block_size*full_size; i++ )
*((char*)mem+i) = 0;
StorageAttr sa;
sa.k_size=k_size;
sa.inf_size=inf_size;
sa.size=size;
sa.block_number=block_number;
sa.lim=lim;
sa.seekpos=seekpos;
/*! Запись заголовка таблицы */
cur_block=0;
fwrite(&sa,sizeof(StorageAttr),1,file);
fflush(file);
seekpos+=sizeof(StorageAttr);
/*! Поле счетчика записей при создании служит флагом на используемость блока и на пустоту ячейки записи:
EMPTY_BLOCK=(-5) - заполняются первые элементы каждого блока, если там другое значение, то этот блок используется, EMPTY_ELEM=(-1) - все остальные пустые записи
*/
mem->count=EMPTY_BLOCK;
for(i=1;i<block_size;i++)
elemPointer(i)->count=EMPTY_ELEM;
/*! Цикл инициализирует все блоки в файле*/
for(i=0;i<size;i++)
{
if((i!=0)&&(i%block_size==0)) cur_block++;
filewrite(i%block_size,false);
}
cur_block=0;
fflush(file);
return true;
}
bool TableBlockStorage::addRow(void* key, void* value)
{
int i=0,pos=-1,empty=-1;
if(file==NULL) return false;
if(max==lim-1) copyToNextBlock();
for(i=0;i<block_size;i++)
{
if(elemPointer(i)->count>=0)
if(keyCompare(i,key)) pos = i;
if((elemPointer(i)->count<0)&&(empty<0)) empty=i;
}
/*! если нашли совпадение ключа, то pos>=0, записываем на это место, иначе пишем на пустое место empty */
if(pos>=0) empty=pos;
else
{
if( empty<0 ) return false; /*! Возвращаем false, если место в блоке закончилось */
memcpy(keyPointer(empty),key,k_size);
}
elemPointer(empty)->count=++max;
memcpy(valPointer(empty),value,inf_size);
filewrite(empty);
return true;
}
bool TableBlockStorage::delRow(void* key)
{
int i;
if(file==NULL) return false;
/*! При удалении счетчик перезаписей также увеличивается */
if(max==lim-1) copyToNextBlock();
for(i=0;i<block_size;i++)
{
if(elemPointer(i)->count < 0)
continue;
if(keyCompare(i,key))
{
elemPointer(i)->count=++max;
memset(keyPointer(i),0,k_size);
filewrite(i);
return true;
}
}
return false;
}
/*! TODO: можно убрать из параметров val, просто возвращать значение */
void* TableBlockStorage::findKeyValue(void* key, void* val)
{
int i;
if(file==NULL) return 0;
for(i=0;i<block_size;i++)
{
/*! Сравниваем ключи только если счетчик >= 0, т.е. запись существует */
if(elemPointer(i)->count < 0)
continue;
if(keyCompare(i,key))
{
memcpy(val,valPointer(i),inf_size);
return val;
}
}
return NULL;
}
int TableBlockStorage::getCurBlock()
{
return cur_block;
}
/* This file is part of the UniSet project
* Copyright (c) 2009 Free Software Foundation, Inc.
* Copyright (c) 2009 Ivan Donchevskiy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Ivan Donchevskiy
*/
// --------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Storages.h"
TableStorage::TableStorage( const char* name, int inf_sz, int sz, int seek ):
file(0)
{
file = fopen(name, "r+");
inf_size=inf_sz;
int l=-1,r=size,mid;
size=sz/(sizeof(TableStorageElem)+inf_size);
TableStorageElem *t = (TableStorageElem*)malloc(sizeof(TableStorageElem)+inf_size);
if(file==NULL)
{
file = fopen(name,"w");
memset(t,0,sizeof(*t));
for(int i=0;i<size;i++) fwrite(t,(sizeof(TableStorageElem)+inf_size),1,file);
fclose(file);
file = fopen(name,"r+");
seekpos=0;
head=-1;
}
else
{
seekpos=seek;
fseek(file,seekpos,0);
fread(t,(sizeof(TableStorageElem)+inf_size),1,file);
if(t->status==0)
{
head=-1;
}
else if((t->status==1)||(t->status==6))
{
head=0;
}
else if((t->status==2)||(t->status==3))
{
while((t->status!=1)&&(t->status!=6)&&(r - l > 1))
{
mid = (l+r)/2;
fseek(file,seekpos+mid*(sizeof(TableStorageElem)+inf_size),0);
fread(t,(sizeof(TableStorageElem)+inf_size),1,file);
if((t->status==2)||(t->status==3))
l = mid;
else if((t->status==4)||(t->status==5))
r = mid;
else
{
r=mid;
break;
}
}
if(r<size)
head=r;
else head=size-1;
}
else
{
while((t->status!=1)&&(t->status!=6)&&(r - l > 1))
{
mid = (l+r)/2;
fseek(file,seekpos+mid*(sizeof(TableStorageElem)+inf_size),0);
fread(t,(sizeof(TableStorageElem)+inf_size),1,file);
if((t->status==2)||(t->status==3))
r = mid;
else if((t->status==4)||(t->status==5))
l = mid;
else
{
r=mid;
break;
}
}
if(r<size)
head=r;
else head=size-1;
}
}
free(t);
}
TableStorage::~TableStorage()
{
if( file )
fclose(file);
}
int TableStorage::addRow(char* key, char* value)
{
TableStorageElem *tbl = (TableStorageElem*)malloc(sizeof(TableStorageElem)+inf_size);
int i,k,j,st;
if(file!=NULL)
{
if(head==-1)
{
fseek(file,seekpos,0);
tbl->status=1;
strcpy(tbl->key,key);
for(k=0;k<inf_size;k++)
*((char*)(tbl)+sizeof(TableStorageElem)+k)=*(value+k);
fwrite(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
head=0;
free(tbl);
return 0;
}
fseek(file,seekpos+head*(sizeof(TableStorageElem)+inf_size),0);
j=head;
for(i=0;i<size;i++)
{
fread(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
if(tbl->status==0) break;
if(!strcmp(tbl->key,key)&&((tbl->status==2)||(tbl->status==4)||(tbl->status==1)))
{
for(k=0;k<inf_size;k++)
*((char*)(tbl)+sizeof(TableStorageElem)+k)=*(value+k);
fseek(file,seekpos+i*(sizeof(TableStorageElem)+inf_size),0);
fwrite(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
free(tbl);
return 0;
}
j++;
if(j>=size)
{
j=0;
fseek(file,seekpos,0);
}
}
fseek(file,seekpos+j*(sizeof(TableStorageElem)+inf_size),0);
if(j==head)
{
if((tbl->status==2)||(tbl->status==3)) st=2;
else st=4;
if(j==0) {
if(st==2) st=4;
else st=2;
}
tbl->status=st;
strcpy(tbl->key,key);
for(k=0;k<inf_size;k++)
*((char*)(tbl)+sizeof(TableStorageElem)+k)=*(value+k);
fwrite(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
j++;
if(j>=size)
{
j=0;
fseek(file,seekpos,0);
}
fread(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
if((tbl->status==3)||(tbl->status==5)) tbl->status=6;
else tbl->status=1;
fseek(file,seekpos+j*(sizeof(TableStorageElem)+inf_size),0);
fwrite(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
head++;
if(head>=size) head=0;
free(tbl);
return 0;
}
}
free(tbl);
return 1;
}
int TableStorage::delRow(char* key)
{
TableStorageElem *tbl = (TableStorageElem*)malloc(sizeof(TableStorageElem)+inf_size);
int i,j;
if(file!=NULL)
{
fseek(file,seekpos+head*(sizeof(TableStorageElem)+inf_size),0);
j=head;
for(i=0;i<size;i++)
{
fread(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
if(!strcmp(tbl->key,key)&&((tbl->status==2)||(tbl->status==4)||(tbl->status==1)))
{
//tbl->key[0]=0;
if(tbl->status==1) tbl->status=6;
else if(tbl->status==2) tbl->status=3;
else tbl->status=5;
fseek(file,seekpos+j*(sizeof(TableStorageElem)+inf_size),0);
fwrite(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
free(tbl);
return 0;
}
j++;
if(j>=size)
{
j=0;
fseek(file,seekpos,0);
}
}
}
free(tbl);
return 1;
}
char* TableStorage::findKeyValue(char* key, char* val)
{
TableStorageElem *tbl = (TableStorageElem*)malloc(sizeof(TableStorageElem)+inf_size);
int i,k;
if(file!=NULL)
{
fseek(file,seekpos,0);
for(i=0;i<size;i++)
{
fread(tbl,(sizeof(TableStorageElem)+inf_size),1,file);
if(!strcmp(tbl->key,key)&&((tbl->status==2)||(tbl->status==4)||(tbl->status==1)))
{
for(k=0;k<inf_size;k++)
*(val+k)=*((char*)(tbl)+sizeof(TableStorageElem)+k);
free(tbl);
return val;
}
}
}
free(tbl);
return 0;
}
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Vitaly Lipatov
* \par
* Базовый класс получения строки по её индексу
*/
// --------------------------------------------------------------------------
#include "TextIndex.h"
/*
std::string TextIndex::getText(int id)
{
};
*/
/* This file is part of the UniSet project
* Copyright (c) 2009 Free Software Foundation, Inc.
* Copyright (c) 2009 Ivan Donchevskiy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Ivan Donchevskiy
*/
// --------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Storages.h>
#include <UniXML.h>
#include <UniSetTypes.h>
int seek=0;
int b_size=25000;
int bj_size=1300000;
void testTable1(void)
{
char *chr=new char[20];
char *val=new char[40];
TableStorage *t;
t = new TableStorage("table.test", 40, 1220, 0);
int i;
for(i=0;i<20;i++)
{
chr[0]=i;
sprintf(val,"%d",i);
t->addRow(chr,val);
}
printf("elements with values=keys added:\n");
for(i=0;i<40;i++)
{
chr[0]=i;
if(t->findKeyValue(chr,val)!=0) printf("%s, ",val);
}
printf("\n");
for(i=9;i<15;i++)
{
chr[0]=i;
t->delRow(chr);
}
printf("elements with keys from 9 to 14 deleted\n");
for(i=9;i<15;i++)
{
chr[0]=i;
sprintf(val,"%d",i+40);
t->addRow(chr,val);
}
printf("elements with keys from 9 to 14 with values=key+40 added, all elements:\n");
for(i=0;i<40;i++)
{
chr[0]=i;
if(t->findKeyValue(chr,val)!=0) printf("%s, ",val);
}
printf("\n");
}
bool testTable2(void)
{
char *val=new char[40];
TableBlockStorage t0;
t0.create("small_file.test", b_size, 4, 40, 100, 5,28,0);
t0.open("small_file.test", b_size, 4, 40, 100, 5,28,0);
TableBlockStorage t;
//t = new TableBlockStorage();
t.create("big_file.test", b_size, 4, 40, 100, 5,28,0);
seek=t.getByteSize();
printf("Table size in bytes = %d\n",seek);
int i;
for(i=1;i<20;i++)
{
if(t.findKeyValue(&i,val)!=0) printf("%s, ",val);
}
printf("\n");
t0.addRow((char*)&i,val);
if(t.getCurBlock()!=0)
{
delete[] val;
return false;
}
for(i=1;i<11;i++)
{
sprintf(val,"%d",i);
t.addRow((char*)&i,val);
}
if(t.getCurBlock()!=0)
{
delete[] val;
return false;
}
for(i=1;i<20;i++)
{
if(t.findKeyValue(&i,val)!=0) printf("%s, ",val);
if(val[0]==0)
{
delete[] val;
return false;
}
}
printf("\n");
if(t.getCurBlock()!=0)
{
delete[] val;
return false;
}
for(i=1;i<8;i++)
{
sprintf(val,"%d",i+10);
t.addRow(&i,val);
}
printf("deleteing 8-10 elements\n");
for(i=8;i<11;i++)
{
t.delRow(&i);
}
for(i=1;i<20;i++)
{
if(t.findKeyValue(&i,val)!=0)
{
printf("%s, ",val);
if((i > 7)&&(i <11))
{
delete[] val;
return false;
}
}
if((val[0] == 0)&&(i < 8))
{
delete[] val;
return false;
}
}
printf("\nrewriting 3-10 elements with values=keys+40\n");
if(t.getCurBlock()!=0)
{
delete[] val;
return false;
}
for(i=3;i<11;i++)
{
sprintf(val,"%d",i+40);
t.addRow(&i,val);
}
for(i=1;i<20;i++)
{
if(t.findKeyValue(&i,val)!=0) printf("%s, ",val);
if((UniSetTypes::uni_atoi(val) != i+40) && (i>2) && (i<11))
{
delete[] val;
return false;
}
if((UniSetTypes::uni_atoi(val) != i+10) && (i<3))
{
delete[] val;
return false;
}
}
if(t.getCurBlock()!=0)
{
delete[] val;
return false;
}
printf("\n");
strcpy(val,"new block");
i=9;
t.addRow(&i,val);
for(i=1;i<20;i++)
{
if(t.findKeyValue((char*)&i,val)!=0) printf("%s, ",val);
}
if(t.getCurBlock()!=1)
{
delete[] val;
return false;
}
printf("after reopen:\n");
t.open("big_file.test", b_size, 4, 40, 100, 5,28,0);
for(i=1;i<20;i++)
{
if(t.findKeyValue(&i,val)!=0) printf("%s, ",val);
}
if(t.getCurBlock()!=1)
{
delete[] val;
return false;
}
delete[] val;
return true;
}
bool reOpen()
{
CycleStorage j;
int i,k=0;
char *str = new char[30];
printf("the same after reopen:\n");
if(!j.open("big_file.test",bj_size,30,33000,seek))
{
printf("Reopen file error\n");
delete[] str;
return false;
}
for(i=0;i<20;i++)
{
if(j.readRow(i,str))
{
printf("%s\n",str);
k++;
}
}
delete[] str;
if(k != 10)
return false;
return true;
}
bool testJournal1(void)
{
CycleStorage *jjj = new CycleStorage();
jjj->create("/dev/hdb2",bj_size,30,32000,seek);
delete jjj;
CycleStorage j("big_file.test",bj_size,30,32000,seek,true);
int i,k=0;
char *str = new char[30];
printf("journal test 1\n");
for(i=1;i<64001;i++)
{
sprintf(str,"%d",i);
j.addRow(str);
}
printf("first 30 elements:\n");
for(i=0;i<30;i++)
{
if(j.readRow(i,str))
{
printf("%s\n",str);
k++;
}
}
if(k < 30)
{
delete[] str;
return false;
}
k = 0;
printf("size changed to 33000 rows (increased)\n");
j.setSize(33000);
TableBlockStorage t("big_file.test", b_size, 4, 40, 100, 5,28,0);
printf("test of 2 classes working in 1 file together\n");
char *val = new char[40];
for(i=1;i<20;i++)
{
if(t.findKeyValue((char*)&i,val)!=0) printf("%s, ",val);
if((UniSetTypes::uni_atoi(val) != i+10) && (i<3))
{
delete[] val;
delete[] str;
return false;
}
}
delete[] val;
printf("\nfirst 30 elements after deleting first 20:\n");
for(i=0;i<20;i++)
{
j.delRow(i);
}
for(i=0;i<30;i++)
{
if(j.readRow(i,str))
{
printf("%s\n",str);
k++;
}
}
if(k != 10)
{
delete[] str;
return false;
}
k = 0;
printf("first 20 after adding 10 elements\n");
for(i=10000001;i<10000011;i++)
{
sprintf(str,"%d",i);
j.addRow(str);
}
for(i=0;i<20;i++)
{
if(j.readRow(i,str))
{
printf("%s\n",str);
k++;
}
}
if(k != 10)
{
delete[] str;
return false;
}
k = 0;
if(!reOpen()){ delete[] str; return false; };
if(!reOpen()){ delete[] str; return false; };
printf("size changed back to 32000 rows\n");
j.setSize(32000);
for(i=0;i<20;i++)
{
if(j.readRow(i,str))
{
printf("%s\n",str);
k++;
}
}
if(k != 10)
{
delete[] str;
return false;
}
k = 0;
delete[] str;
return true;
}
void testJournal2(void)
{
CycleStorage j("big_file.test",bj_size,30,32000,seek);
int i,k;
char *str = new char[30];
printf("journal test 2 - checking number of iterations to find head/tail\n");
printf("iterations = %d\n",j.getIter());
for(i=0;i<20;i++)
{
for(k=1000;k<2999;k++)
{
sprintf(str,"%d",k);
j.addRow(str);
}
j.open("big_file.test",bj_size,30,32000,seek);
printf("i=%d, iterations = %d\n", i, j.getIter());
}
printf("\n");
delete[] str;
}
struct JItem
{
long id;
long val[10];
} __attribute__((__packed__));
bool testJournal3()
{
CycleStorage j("journal3.test",bj_size,sizeof(JItem),10,0,true);
if( !j.isOpen() )
{
printf("create journal3.test failed\n");
return false;
}
printf("Joural size=%d inf_size=%d full_size=%d byte_size=%d\n",
j.getSize(),
j.getInfSize(),
j.getFullSize(),
j.getByteSize()
);
JItem ji;
printf("write 35 elements:\n");
for(int i=0;i<35;i++)
{
JItem ji;
ji.id = i;
for( int k=0; k<10; k++ )
ji.val[k] = i;
j.addRow(&ji);
}
printf("read first 10 elements:\n");
for( int i=0;i<10;i++)
{
if( j.readRow(i,&ji) )
printf("read i=%d j.id=%ld\n", i, ji.id);
else
printf("read num=%d FAILED!\n",i);
}
return true;
}
int main(int args, char **argv)
{
//testTable1();
bool ok = true;
if(testTable2())
printf("\nTest for TableBlockStorage passed\n\n");
else
{
printf("\nTest for TableBlockStorage failed\n\n");
ok = false;
}
if(testJournal1())
printf("\nTest1 for CycleStorage passed\n\n");
else
{
printf("\nTest for CycleStorage failed\n\n");
ok = false;
}
if(ok)
{
testJournal2();
printf("TEST PASSED :)\n");
}
else
printf("TEST FAILED :(\n");
testJournal3();
return 0;
}
\ No newline at end of file
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_PROGRAMS = jrntest
jrntest_SOURCES = JrnTest.cc
jrntest_LDADD = $(top_builddir)/lib/libUniSet.la
jrntest_CPPFLAGS = -I$(top_builddir)/include
include $(top_builddir)/conf/setting.mk
......@@ -2,9 +2,7 @@
# This file is part of the UniSet library #
############################################################################
SUBDIRS=JrnTests
noinst_PROGRAMS = passivetimer hourglass delaytimer unixml ui umutex conftest iterator_test sscanf_hex calibration
noinst_PROGRAMS = passivetimer hourglass delaytimer unixml ui umutex conftest iterator_test sscanf_hex calibration threadtst
passivetimer_SOURCES = passivetimer.cc
passivetimer_LDADD = $(top_builddir)/lib/libUniSet.la
......@@ -31,8 +29,8 @@ ui_LDADD = $(top_builddir)/lib/libUniSet.la
ui_CPPFLAGS = -I$(top_builddir)/include
umutex_SOURCES = umutex.cc
umutex_LDADD = $(top_builddir)/lib/libUniSet.la
umutex_CPPFLAGS = -I$(top_builddir)/include
umutex_LDADD = $(top_builddir)/lib/libUniSet.la $(COMCPP_LIBS)
umutex_CPPFLAGS = -I$(top_builddir)/include $(COMCPP_CFLAGS)
conftest_SOURCES = conftest.cc
conftest_LDADD = $(top_builddir)/lib/libUniSet.la
......@@ -44,6 +42,10 @@ calibration_SOURCES = calibration.cc
calibration_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS}
calibration_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS}
threadtst_SOURCES = threadtst.cc
threadtst_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS} $(COMCPP_LIBS)
threadtst_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS} $(COMCPP_CFLAGS)
include $(top_builddir)/conf/setting.mk
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment