DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ImageContainerByHashTree.h
1 
17 #pragma once
18 
32 #if defined(ImageContainerByHashTree_RECURSES)
33 #error Recursive header files inclusion detected in ImageContainerByHashTree.h
34 #else // defined(ImageContainerByHashTree_RECURSES)
35 
36 #define ImageContainerByHashTree_RECURSES
37 
38 #if !defined ImageContainerByHashTree_h
39 
40 #define ImageContainerByHashTree_h
41 
43 // Inclusions
44 #include <iostream>
45 #include "DGtal/base/Common.h"
46 #include "DGtal/base/CLabel.h"
47 #include "DGtal/base/ConstRangeAdapter.h"
48 #include "DGtal/kernel/domains/CDomain.h"
49 #include "DGtal/kernel/domains/HyperRectDomain.h"
50 #include "DGtal/kernel/SpaceND.h"
51 #include "DGtal/base/Bits.h"
52 //#include "DGtal/io/boards/Board2D.h"
53 #include "DGtal/images/Morton.h"
54 #include "DGtal/images/SetValueIterator.h"
55 #include "DGtal/io/Color.h"
56 #include "DGtal/base/ExpressionTemplates.h"
58 
59 namespace DGtal
60 {
62  // template class ImageContainerByHashTree
123  template < typename TDomain, typename TValue, typename THashKey = typename DGtal::uint64_t >
125  {
126 
127  protected:
128  class Node;
129 
130 
131  public:
132 
134 
135  typedef THashKey HashKey;
136 
139  typedef TDomain Domain;
140  typedef typename Domain::Point Point;
141  typedef typename Domain::Vector Vector;
142  typedef typename Domain::Integer Integer;
143  typedef typename Domain::Size Size;
144  typedef typename Domain::Dimension Dimension;
145  typedef Point Vertex;
146 
148  static const typename Domain::Dimension dimension = Domain::dimension;
149  static const typename Domain::Dimension dim = Domain::dimension;
150  static const unsigned int NbChildrenPerNode = POW<2, dimension>::VALUE;
151  static const HashKey ROOT_KEY = static_cast<HashKey>(1);
152 
154  //(since constructed from two points as a bounding box)
155  BOOST_STATIC_ASSERT ((boost::is_same< Domain,
157 
160  typedef TValue Value;
162 
165 
166 
167 
185  ImageContainerByHashTree(const unsigned int hashKeySize,
186  const unsigned int depth,
187  const Value defaultValue);
188 
207  ImageContainerByHashTree(const unsigned int hashKeySize,
208  const Point & p1,
209  const Point & p2,
210  const Value defaultValue);
211 
228  ImageContainerByHashTree(const Domain &aDomain,
229  const unsigned int hashKeySize = 3,
230  const Value defaultValue= NumberTraits<Value>::ZERO);
231 
232 
233  // TODO
234  // /**
235  // * Copy contructor.
236  // *
237  // * @param other object to copy.
238  // */
239  // ImageContainerByHashTree(const ImageContainerByHashTree<Domain, Value>& other);
240 
241  // /**
242  // * Assignment.
243  // *
244  // * @param other object to copy.
245  // */
246  // ImageContainerByHashTree(const ImageContainerByHashTree<Domain, Value>& other);
247 
248  // /**
249  // * Destructor
250  // * Free the memory allocated by @a myData
251  // */
252  // ~ImageContainerByHashTree();
253 
254 
258  const Domain &domain() const;
259 
264  ConstRange range() const;
265 
270 
271 
286  Value get(const HashKey key) const;
287 
288 
295  Value operator () (const HashKey key) const;
296 
303  Value operator()(const Point &aPoint) const;
304 
310  Value get(const Point & aPoint) const;
311 
312 
320  Value upwardGet(const HashKey key) const ;
321 
329  Value reverseGet(const HashKey key) const;
330 
331 
342  void setValue(const HashKey key, const Value object);
343 
354  void setValue(const Point& aPoint, const Value object);
355 
362  inline unsigned int getSpanSize() const
363  {
364  return mySpanSize;
365  }
366 
371  inline unsigned int getDepth() const
372  {
373  return myTreeDepth;
374  }
375 
384  bool isKeyValid(HashKey key) const;
385 
393  bool checkIntegrity(HashKey key = ROOT_KEY, bool leafAbove = false) const;
394 
395  int myDebugCounter; //debug
396 
397  //stuff that might be moved out of the class for reusability
398  HashKey getKey(const Point & aPoint) const;
399 
400  unsigned int getKeyDepth(HashKey key) const;
401 
402  int* getCoordinatesFromKey(HashKey key) const;
403 
404  /*
405  * Prints in the state of the container as a tree. (Calls
406  * printTree)
407  *
408  * @param out output stream.
409  * @param displayKeys boolean to decide if keys are displayed .
410  */
411  void printState(std::ostream& out, bool displayKeys = false) const;
412 
421  void printTree(HashKey key, std::ostream& out, bool displayKeys) const;
422 
431  void printInternalState(std::ostream& out, unsigned int nbBits = 0) const;
432 
447  void printInfo(std::ostream& out) const;
448 
452  unsigned int getNbEmptyLists() const;
453 
458  double getAverageCollisions() const;
459 
463  unsigned int getMaxCollisions() const;
464 
471  unsigned int getNbNodes(unsigned int intermediateKey) const;
472 
476  unsigned int getNbNodes()const;
477 
478 
479  // -------------------------------------------------------------
480  /* Iterator inner-class
481  *
482  * @brief Buil-in iterator on an HashTree. This iterator visits
483  * all node in the tree.
484  *
485  * -------------------------------------------------------------
486  */
487  class Iterator
488  {
489  public:
490  Iterator(Node** data, unsigned int position, unsigned int arraySize)
491  {
492  myArraySize = arraySize;
493  myContainerData = data;
494  myNode = data[0];
495  myCurrentCell = position;
496  while ((!myNode) && (myCurrentCell < myArraySize))
497  {
499  }
500  }
501  bool isAtEnd()const
502  {
503  return myCurrentCell >= myArraySize;
504  }
506  {
507  return myNode->getObject();
508  }
510  {
511  return next();
512  }
513  bool operator == (const Iterator& it)
514  {
515  if (isAtEnd() && it.isAtEnd())
516  return true;
517  else
518  return (myNode == it.myNode);
519  }
520  bool operator != (const Iterator& it)
521  {
522  if (isAtEnd() && it.isAtEnd())
523  return false;
524  else
525  return (myNode != it.myNode);
526  }
527  inline HashKey getKey() const
528  {
529  return myNode->getKey();
530  }
531  bool next();
532  protected:
534  unsigned int myCurrentCell;
535  unsigned int myArraySize;
537  };
538 
543  {
544  return Iterator(myData, 0, myArraySize);
545  }
546 
551  {
553  }
554 
555  void selfDisplay(std::ostream & out);
556 
557  bool isValid() const
558  {
559  return checkIntegrity();
560  }
561 
562  // ------------- realization CDrawableWithBoard2D --------------------
563  private:
564 
565 
566  public:
571  //DrawableWithBoard2D* defaultStyle() const;
572 
576  std::string className() const;
577 
578  protected:
579 
580  template <typename C>
581  void
582  recursiveDraw(HashKey key, const double p1[2], const double len, Board2D & board, const C& cmap) const;
583 
584 
585  // -------------------------------------------------------------
592  class Node
593  {
594  public:
595 
602  Node(Value aValue, HashKey key)
603  {
604  myData = aValue;
605  myKey = key;
606  }
607 
611  inline Node* getNext()
612  {
613  return myNext;
614  }
615 
616 
622  inline void setNext(Node* next)
623  {
624  myNext = next;
625  }
626 
631  inline HashKey getKey()
632  {
633  return myKey;
634  }
635 
640  inline Value& getObject()
641  {
642  return myData;
643  }
644  ~Node() { }
645  protected:
649  };// -----------------------------------------------------------
650 
651 
659  inline HashKey getIntermediateKey(const HashKey key) const;
660 
661 
671  Node* addNode(const Value object, const HashKey key)
672  {
673  Node* n = getNode(key);
674  if (n)
675  {
676  n->getObject() = object;
677  //n->setObject(object);
678  return n;
679  }
680  n = new Node(object, key);
681  HashKey key2 = getIntermediateKey(key);
682  n->setNext(myData[key2]);
683  myData[key2] = n;
684  return n;
685  }
686 
687  public:
695  inline Node* getNode(const HashKey key) const // very used !! // public because Display2DFactory !!!
696  {
697  Node* iter = myData[getIntermediateKey(key)];
698  while (iter != 0)
699  {
700  if (iter->getKey() == key)
701  return iter;
702  iter = iter->getNext();
703  }
704  return 0;
705  }
706  protected:
707 
713  bool removeNode(HashKey key);
714 
720  void recursiveRemoveNode(HashKey key, unsigned int nbRecursions);
721 
722 
729  void setDepth(unsigned int depth);
730 
737  Value blendChildren(HashKey key) const;
738 
739 
740  //----------------------- internal data --------------------------------
741  protected:
742 
747 
752 
758  unsigned int myKeySize;
759 
760  unsigned int myArraySize;
761 
765  unsigned int myTreeDepth;
766 
767  unsigned int mySpanSize;
768 
769 
770  // myN is number of children per node.
771  static const unsigned int myN=POW<2,dim>::VALUE;
772 
773 
774  public:
775  Point myOrigin; // public because Display2DFactory !!!
776  protected:
777 
782  HashKey myPreComputedIntermediateMask; // ~((~0) << _keySize)
783 
784  public:
786  Morton<HashKey, Point> myMorton; // public because Display2DFactory !!!
787 
788 
789  };
790 
797  template<typename TDomain, typename TValue, typename THashKey >
798  std::ostream&
799  operator<< ( std::ostream & out, ImageContainerByHashTree<TDomain, TValue, THashKey> & object )
800  {
801  object.selfDisplay( out);
802  return out;
803  }
804 
805 
806 
807 } // namespace DGtal
808 
810 // Includes inline functions.
811 #include "DGtal/images/ImageContainerByHashTree.ih"
812 
813 // //
815 
816 #endif // !defined ImageContainerByHashTree_h
817 
818 #undef ImageContainerByHashTree_RECURSES
819 #endif // else defined(ImageContainerByHashTree_RECURSES)