diff --git a/.gitattributes b/.gitattributes index 478171e2556..6a8d71d66cc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -41,6 +41,7 @@ Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/Curve_analysis_2.h -tex Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/Curve_pair_analysis_2.h -text Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/Curve_pair_vertical_line_1.h -text Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/Curve_vertical_line_1.h -text +Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/LRU_hashed_map.h -text Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/Xy_coordinate_2.h -text Algebraic_kernel_d/include/CGAL/Algebraic_kernel_1.h -text Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_real_pure.h -text diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/LRU_hashed_map.h b/Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/LRU_hashed_map.h new file mode 100755 index 00000000000..3acf7492415 --- /dev/null +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_curve_kernel_2/LRU_hashed_map.h @@ -0,0 +1,211 @@ +// TODO: Add licence +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL:$ +// $Id: $ +// +// +// Author(s) : Pavel Emeliyanenko +// +// +// ============================================================================ + +#ifndef CGAL_ALGEBRAIC_CURVE_KERNEL_HASHED_MAP_H +#define CGAL_ALGEBRAIC_CURVE_KERNEL_HASHED_MAP_H + +#include + +#include +#include +#include +#include +#include + +using boost::multi_index::multi_index_container; +using boost::multi_index::get; +using boost::multi_index::project; + +CGAL_BEGIN_NAMESPACE + +namespace CGALi { + +//! \brief this class defines hashed map container with LRU capabilities, +//! +//! stores pair of \c KeyType_ and \c ValueType_. Before adding to +//! the map the input is normialized using \c Canonicalizer_ +//! \c Pred_ is binary predicate acting as an equivalence relation on +//! values of \c KeyType_, \c Creator_ is a mapping from \c KeyType_ to +//! \c ValueType_, \c Hash_ is function object which returns hash values +//! for the keys +template , + class Creator_ = CGAL::Creator_1, + class Pred_ = std::equal_to > +class LRU_hashed_map +{ +public: + //!\name public typedefs + //!@{ + + //! this instance's first argument + typedef KeyType_ Key_type; + //! this instance's second argument + typedef ValueType_ Value_type; + //! input data canonicalizer + typedef Canonicalizer_ Canonicalizer; + //! equality predicate + typedef Pred_ Pred; + //! mapping \c KeyType_ -> \c ValueType_ + typedef Creator_ Creator; + //! hash function + typedef Hash_ Hash; + //! hashed map data type + typedef std::pair Data_type; + //! myself + typedef LRU_hashed_map Self; + + //!@} +private: + //!\name private members + //!@{ + + // try boost::identity ? + typedef boost::multi_index::multi_index_container< + Data_type, + boost::multi_index::indexed_by< + boost::multi_index::sequenced<>, + boost::multi_index::hashed_unique< + BOOST_MULTI_INDEX_MEMBER(Data_type, Key_type, first), + Hash, Pred > > > Hashed_map; + + //! hashed map instance + Hashed_map _m_hashed_map; + + //! maximal size allowed + unsigned _m_max_size; + + //!@} +public: + //!\name iterator types + //!@{ + + //! hashed index iterator + typedef typename + boost::multi_index::nth_index_iterator::type + Hashed_iterator; + + //! sequenced index iterator + typedef typename + boost::multi_index::nth_index_iterator::type + Sequenced_iterator; + + //! sequenced index const iterator + typedef typename + boost::multi_index::nth_index_const_iterator::type + Sequenced_const_iterator; + //!@} +public: + //!\name constructors and access functions + //!@{ + + //! \brief default constructor + LRU_hashed_map(unsigned max_size = -1u) : _m_hashed_map(), + _m_max_size(max_size) + { std::cout << "constructor LRU\n"; } + + ~LRU_hashed_map() + { + std::cout << "destructor LRU\n"; + } + + /*! \brief implements cache-like behaviour of the map + * + * If the object is not in the map, it is constructed using \c Creator + * and added to the map + */ + Value_type operator()(const Key_type& key_) + { + Canonicalizer canonicalize; + Key_type key = canonicalize(key_); + std::pair p = find(key); + + if(!p.second) { + std::cout << "not found\n"; + Creator create; + Value_type val = create(key); + std::cout << "result: " << + insert(Data_type(key, val)).second << "\n"; + return val; + } + return (p.first)->second; + } + + //! \brief looks for an entry with a specified key in the map + //! + //! returns a pair of iterator pointing to \c Data_type and a boolean + //! indicating whether an element with specified key was found + std::pair find(const Key_type& key) + { + typename boost::multi_index::nth_index::type& + idx = _m_hashed_map.get<1>(); + Hashed_iterator it = idx.find(key); + if(it == idx.end()) + return std::make_pair(it, false); + // otherwise put the accessed element on the top + _m_hashed_map.relocate(_m_hashed_map.begin(), + _m_hashed_map.project<0>(it)); + return std::make_pair(it, true); + } + + //! \brief inserts an entry to the map + //! + //! on successful insertion, \c p.first points to the element + //! inserted; otherwise \c p.first points to an element that caused + //! the insertion to be banned. If the map's size exceeds \c max_size + //! the least recently used entry is dropped + std::pair insert(const Data_type& data) + { + if(_m_hashed_map.size() > _m_max_size) + _m_hashed_map.pop_back(); + return _m_hashed_map.push_front(data); + } + + //! clears the map contents + void clear() { _m_hashed_map.clear(); } + + //! returns whether the map is empty. + bool is_empty() const { return _m_hashed_map.empty(); } + + //! returns the number of items in the map + unsigned size() { return _m_hashed_map.size(); } + + //! returns the largest possible size of the map (-1 if not set) + unsigned max_size() const { return _m_max_size; } + + //! \brief returns an iterator pointing to the beginning of the map + //! + //! all iterators run over sequenced indices + Sequenced_iterator begin() { return _m_hashed_map.begin(); } + + //! returns an iterator pointing to the end of the map + Sequenced_iterator end() { return _m_hashed_map.end(); } + + //! returns a const_iterator pointing to the beginning of the map + Sequenced_const_iterator begin() const + { return _m_hashed_map.begin(); } + + //! Returns a const_iterator pointing to the end of the map + Sequenced_const_iterator end() const + { return _m_hashed_map.end(); } + + //!@} +}; // class LRU_hashed_map + +} // namespace CGALi + +CGAL_END_NAMESPACE + +#endif // CGAL_ALGEBRAIC_CURVE_KERNEL_HASHED_MAP_H