Main Page   Class Hierarchy   Compound List   Header Files   Compound Members  

ddgcache.h

This is the verbatim text of the ddgcache.h include file.
/*
    Copyright (C) 1997, 1998, 1999, 2000 by Alex Pfaffe
        (Digital Dawn Graphics Inc)
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library 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
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _ddgCache_Class_
#define _ddgCache_Class_

#include "util/ddgerror.h"
typedef unsigned short ddgCacheIndex;

class WEXP ddgCacheNode
{
        friend class ddgCache;
        ddgCacheIndex   _next;
public:
        ddgCacheNode(void) : _next(0) {}
        inline ddgCacheIndex next(void) { return _next; }
        inline void next(ddgCacheIndex ci) { _next = ci; }
};

class WEXP ddgCache
{
        ddgCacheNode * _nList;
        ddgCacheIndex _fList;
        unsigned int _cacheSize;
        unsigned int _size;
        unsigned int _nodeSize;
        unsigned int _maxSize;

public:
        ddgCache(void );
    ~ddgCache(void);
        bool init( unsigned int cacheSize, unsigned int nodeSize );
        ddgCacheIndex allocNode(void);
        void freeNode(ddgCacheIndex n);
        inline unsigned int size(void) { return _size; }
        void reset(void);
        inline ddgCacheNode *get(ddgCacheIndex i)
        {
                ddgAsserts(i >= 0 && i < _cacheSize,"Invalid cache index");
                return &(_nList[i*_nodeSize]);
        }
};


class WEXP ddgLNode : public ddgCacheNode {
        friend class ddgLCache;
private:
        ddgCacheIndex _prev;
public:
        void prev(ddgCacheIndex ci ) { _prev = ci; }
        ddgCacheIndex prev(void) { return _prev; }
};

class WEXP ddgLCache : public ddgCache {
        typedef ddgCache super;
public:
        inline ddgLNode* get(ddgCacheIndex n)
        {
                return (ddgLNode*) super::get(n);
        }
        inline ddgCacheIndex insert(ddgCacheIndex nextNode)
        {
                ddgCacheIndex ci = allocNode();
                // Initialize the new node.
                ddgLNode *n = get(ci);
                // Insert at head of the list.
                n->next(nextNode);
                if (nextNode)
                {
                        n->prev(get(nextNode)->prev());
                        // Update the neighbours.
                        if (n->prev())
                                get(n->prev())->next(ci);
                        get(n->next())->prev(ci);
                }
                else
                        n->prev(0);
                ddgAssert(ci);
                return ci;
        }
        inline void remove(ddgCacheIndex ci)
        {
                ddgAssert(ci);
                ddgLNode *n = get(ci);
                if (n->prev())
                {
                        get(n->prev())->next(n->next());
                }
                if (n->next())
                {
                        get(n->next())->prev(n->prev());
                }
                freeNode(ci);
        }
        inline ddgCacheIndex insertHead(ddgCacheIndex nextNode)
        {
                ddgCacheIndex ci = allocNode();
                // Initialize the new node.
                ddgLNode *n = get(ci);
                // Insert at head of the list.
                n->next(nextNode);
                if (nextNode)
                {
                        get(n->next())->prev(ci);
                }
                n->prev(0);
                ddgAssert(ci);
                return ci;
        }
        inline ddgCacheIndex insertTail(ddgCacheIndex prevNode)
        {
                ddgCacheIndex ci = allocNode();
                // Initialize the new node.
                ddgLNode *n = get(ci);
                // Insert at head of the list.
                n->prev(prevNode);
                if (prevNode)
                {
                        get(n->prev())->next(ci);
                }
                n->next(0);
                ddgAssert(ci);
                return ci;
        }
};




class WEXP ddgSNode : public ddgLNode {
        friend class ddgSCache;
private:
        short   _bucket;

public:
        inline short bucket(void) { return _bucket; }
        inline void bucket(short b) { _bucket = b; }
};


class WEXP ddgSCache : public ddgLCache {
        typedef ddgLCache super;

        ddgCacheIndex   *_bucket;
        ddgCacheIndex   _head;
        ddgCacheIndex   _tail;
        short   _bucketNo;
        bool _reverse;

public:
        ddgSCache(void)
        {
                _bucket = 0;
                _bucketNo = 0;
                _head = 0;
                _tail = 0;
        }
        ~ddgSCache(void)
        {
                delete[] _bucket;
                _head = 0;
                _tail = 0;
                _bucket = 0;
        }
        inline void reset(void)
        {
                ddgCache::reset();
                _head = 0;
                _tail = 0;
                unsigned int i = _bucketNo;
                while (i)
                        _bucket[--i] = 0;
        }
        void init (unsigned int size, unsigned int nodeSize, unsigned int bn, bool r = false ) {
                ddgAssert(bn < 0xFFFF);
                _bucketNo = bn;
                _reverse = r;
                super::init(size,nodeSize);
                _bucket = new ddgCacheIndex[_bucketNo];
                ddgAsserts(_bucket, "Failed to allocate memory.");
                ddgMemorySet(ddgCacheIndex,_bucketNo);
                reset();
        }
        inline ddgSNode* get(unsigned short index)
        {
                return (ddgSNode*) ddgCache::get(index);
        }
        inline short bucketNo(void) { return _bucketNo; }
        inline short convert( short b )
        {
                return _reverse ? _bucketNo - b - 1 : b;
        }
        inline ddgCacheIndex insert(short b)
        {
                ddgAsserts(b >= 0 && b < _bucketNo,"Bucket key is out of range!");
                ddgAsserts(_bucket, "Failed to allocate memory.");
                if (_reverse)
                        b = _bucketNo - b - 1;
                ddgCacheIndex ci = super::insert(_bucket[b]);
                // Initialize the new node.
                ddgSNode *n = get(ci);
                n->bucket(b);
                // We are now the head of the list.
                _bucket[b] = ci;
                // Reset the head and tail of the queue if need be.
                if (_head < ddgCacheIndex(b))
                        _head = b;
                else if (_tail > ddgCacheIndex(b))
                        _tail = b;
                ddgAssert(ci);
                return ci;
        }
        inline void remove(ddgCacheIndex ci)
        {
                ddgAssert(ci);
                ddgSNode *n = get(ci);
                short           b = n->bucket();
                ddgAssert(b >= 0 && b < _bucketNo);
                ddgAsserts(_bucket, "Failed to allocate memory.");
                // If the deleted node was the head of the queue update the head.
                if (_bucket[b] == ci)
                {
                        _bucket[b] = n->next();
                }
                // Remove the actual item and free it.
                super::remove(ci);
        }
        inline ddgCacheIndex head(void)
        {
                while (!_bucket[_head] && _head > 0 )
                        _head--;
                return _bucket[_head];
        }
        inline ddgCacheIndex tail(void)
        {
                while (!_bucket[_tail] && _tail < _bucketNo-1 )
                        _tail++;
                return _bucket[_tail];
        }
        inline ddgCacheIndex next(ddgCacheIndex ci)
        {
                ddgAssert(ci);
                ddgSNode        *n = get(ci);
                short           b = n->bucket();
                const short     blim = (short)_tail;
                if (n->next())
                        return n->next();
                // Find next bucket with something in it.
                while (--b > blim && !_bucket[b] ){}
                return b < 0 ? 0 : _bucket[b];
        }
};
#endif

Generated at Sun Sep 17 19:27:54 2000 for Digital Dawn Graphics Toolkit by doxygen 0.49-991205 written by Dimitri van Heesch, © 1997-1999