Logo Search packages:      
Sourcecode: tagcoll version File versions  Download package

SmartHierarchy.h

Go to the documentation of this file.
#ifndef TAGCOLL_SMARTHIERARCHY_H
#define TAGCOLL_SMARTHIERARCHY_H

/** \file
 * Auto-expanding trees and smart hierarchy interface
 */

/* 
 * Copyright (C) 2003,2004,2005  Enrico Zini <enrico@debian.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 */

#include <tagcoll/CardinalityStore.h>
#include <vector>

namespace Tagcoll
{

// Base class for the auto-expanding tree nodes
template<class ITEM, class TAG>
class HierarchyNode
{
protected:
      // Tag name
      TAG _tag;
      CardinalityStore<ITEM, TAG>* coll;
      std::vector<HierarchyNode<ITEM, TAG>*> children;
      OpSet<ITEM> items;
      HierarchyNode<ITEM, TAG>* _parent;

public:
      HierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll)
            : _tag(tag), coll(new CardinalityStore<ITEM, TAG>(coll)), _parent(0) {}
      HierarchyNode(HierarchyNode<ITEM, TAG>* parent, const TAG& tag, const CardinalityStore<ITEM, TAG>& coll)
            : _tag(tag), coll(new CardinalityStore<ITEM, TAG>(coll)), _parent(parent) {}
      virtual ~HierarchyNode();

      typedef typename std::vector<HierarchyNode<ITEM, TAG>*>::iterator iterator;

      // Get the node tag (const version)
      const TAG& tag() const { return _tag; }

      // Get the node tag
      TAG tag() { return _tag; }

      // Get the parent of this node (0 if it is the root node)
      HierarchyNode<ITEM, TAG>* parent() const { return _parent; }

      // Expand the collection in the children of this node
      virtual void expand() = 0;

      // Get the number of child nodes
      int size()
      {
            if (coll)
                  expand();
            return children.size();
      }

      iterator begin()
      {
            if (coll)
                  expand();
            return children.begin();
      }

      iterator end()
      {
            if (coll)
                  expand();
            return children.end();
      }

      // Get a child node by index
      HierarchyNode<ITEM, TAG>* operator[](int idx)
      {
            if (coll)
                  expand();
            return children[idx];
      }

      // Get the set of items present in this node
      const OpSet<ITEM>& getItems()
      {
            if (coll)
                  expand();
            return items;
      }
};

// Hierarchy of items where information is replicated to acheive intuitive
// navigability of the resulting structure
template<class ITEM, class TAG>
class SmartHierarchyNode : public HierarchyNode<ITEM, TAG>
{
protected:
      OpSet<ITEM> unexpandedItems;

      // Threshold of child items below which the child hierarchy is flattened
      // and they all become children of this node
      int flattenThreshold;
      
      // Expand the collection in the children of this node
      virtual void expand();

public:
      SmartHierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
            throw () :
                  HierarchyNode<ITEM, TAG>(tag, coll),
                  flattenThreshold(flattenThreshold) {}

      SmartHierarchyNode(
                  HierarchyNode<ITEM, TAG>* parent,
                  const TAG& tag,
                  const CardinalityStore<ITEM, TAG>& coll,
                  int flattenThreshold = 0)
            throw () :
                  HierarchyNode<ITEM, TAG>(parent, tag, coll.getChildCollection(tag)),
                  flattenThreshold(flattenThreshold)
            {
                  OpSet<TAG> tags; tags += tag;
                  unexpandedItems = coll.getItemsExactMatch(tags);
            }

      virtual ~SmartHierarchyNode() {}
};


// SmartHierarchyNode which also does merging of equivalent tags
template<class ITEM, class TAG>
class CleanSmartHierarchyNode : public SmartHierarchyNode<ITEM, TAG>
{
protected:
      // Expand the collection in the children of this node
      virtual void expand();

      TAG setTag(const TAG& tag) { return this->_tag = tag; }
      HierarchyNode<ITEM, TAG>* setParent(HierarchyNode<ITEM, TAG>* parent) { return this->_parent = parent; }

public:
      CleanSmartHierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
            : SmartHierarchyNode<ITEM, TAG>(tag, coll, flattenThreshold) {}
      CleanSmartHierarchyNode(HierarchyNode<ITEM, TAG>* parent, const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
            : SmartHierarchyNode<ITEM, TAG>(parent, tag, coll, flattenThreshold) {}
      virtual ~CleanSmartHierarchyNode() {}
};

};

// vim:set ts=4 sw=4:
#endif

Generated by  Doxygen 1.6.0   Back to index