#ifndef __LISTMAN_H
#define __LISTMAN_H
#include "dfile.h"
typedef ulong filepos; /* file position type */
template <class T> struct TDSingleLinkNode {
filepos Next, Free;
T Data;
};
template <class T> struct TDDoubleLinkNode {
filepos Prev, Next, Free;
T Data;
};
template <class T> struct TDBinarySearchTreeNode {
filepos Left, Right, Free;
T Data;
};
template <class Nd, class FM> class TDListManager
{ /* Nd is node type, FM is File manager type */
FM *_Fm; /* -> file manager */
struct header {
filepos Head, Tail, Free;
ulong NodesAllocated; /* total count */
ulong ItemCount; /* active count */
} _Hdr;
#define HDRSIZE sizeof(header)
/* BEG_OFFSET places 1st node at specified offset
* into container file (see vectman.h).....
*/
#ifndef BEG_OFFSET
#define BEG_OFFSET HDRSIZE
#endif
public:
TDListManager(const char *fname, int nn, int m) {
_Fm = new FM( nn, sizeof(Nd), fname, m );
_Hdr.Head = _Hdr.Tail = _Hdr.Free = 0;
_Hdr.ItemCount = _Hdr.NodesAllocated = 0;
_Fm->ReadAt( 0, (void *) &_Hdr, HDRSIZE );
}
~TDListManager() { WriteHeader();
delete _Fm; }
filepos Head() const { return _Hdr.Head; }
void Head(filepos hd) { _Hdr.Head = hd; }
filepos Tail() const { return _Hdr.Tail; }
void Tail(filepos tl) { _Hdr.Tail = tl; }
ulong ItemCount() const { return _Hdr.ItemCount; }
void ItemCount( ulong c ) { _Hdr.ItemCount = c; }
ulong ListSize() const
{ return _Hdr.NodesAllocated; }
int WriteHeader();
void GetFree( Nd& );
void PutFree( Nd& );
virtual int ReadNode(Nd& t, ulong pos)
{ return _Fm->ReadNode( (void *) &t, pos ); }
virtual int WriteNode(const Nd& t, ulong pos) {
return _Fm->WriteNode((const void *) &t, pos );
}
};
template <class Nd,class FM>
int TDListManager<Nd,FM>::WriteHeader()
{
if( _Fm->tempused() )
return 1; /* return if non-persistent */
return _Fm->WriteAt( 0, (void *) &_Hdr, HDRSIZE );
}
template <class Nd,class FM>
void TDListManager<Nd,FM>::GetFree( Nd& node )
{ /* Get address of next free node in the file;
* Assign new address to node.Free ....... */
if( _Hdr.Free == 0 ) /* get new node */
node.Free = ( _Hdr.NodesAllocated++
* sizeof(Nd) ) + BEG_OFFSET;
else { /* Get next free node from file... */
filepos _free = _Hdr.Free;
ReadNode( node, _free );
_Hdr.Free = node.Free;
node.Free = _free;
}
}
template <class Nd,class FM>
void TDListManager<Nd,FM>::PutFree( Nd& node ) {
filepos _free = node.Free;
node.Free = _Hdr.Free;
_Hdr.Free = _free;
WriteNode( node, _free );
}
#endif // EOF