#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