dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Arr_rat_arc/Cache.h

319 lines
10 KiB
C++

// Copyright (c) 2011 Tel-Aviv University (Israel), INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Cache.h $
// $Id: Cache.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Oren Salzman <orenzalz@post.tau.ac.il >
// Michael Hemmer <Michael.Hemmer@sophia.inria.fr>
#ifndef CGAL_RATIONAL_ARC_CACHE
#define CGAL_RATIONAL_ARC_CACHE
#include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/Arr_rat_arc/Base_rational_arc_ds_1.h>
#include <CGAL/Arr_rat_arc/Rational_function.h>
#include <CGAL/Arr_rat_arc/Rational_function_pair.h>
#include <CGAL/Arr_rat_arc/Rational_function_canonicalized_pair.h>
namespace CGAL {
namespace Arr_rational_arc {
//-------------------
//Cache
//-------------------
template <typename AlgebraicKernel_d_1>
class Cache : public Base_rational_arc_ds_1<AlgebraicKernel_d_1>
{
public:
typedef AlgebraicKernel_d_1 Algebraic_kernel_d_1;
typedef Base_rational_arc_ds_1<Algebraic_kernel_d_1> Base;
typedef Cache<Algebraic_kernel_d_1> Self;
typedef typename Base::Polynomial_1 Polynomial_1;
typedef typename Base::Rational Rational;
typedef typename Base::Algebraic_real_1 Algebraic_real_1;
typedef typename Base::Integer Integer ;
typedef typename Base::FT_rat_1 FT_rat_1;
typedef typename Base::Polynomial_traits_1 Polynomial_traits_1;
typedef CGAL::Arr_rational_arc::Rational_function<Algebraic_kernel_d_1>
Rational_function;
typedef CGAL::Arr_rational_arc::Rational_function_canonicalized_pair<Algebraic_kernel_d_1>
Rational_function_canonicalized_pair;
typedef CGAL::Arr_rational_arc::Rational_function_pair<Algebraic_kernel_d_1>
Rational_function_pair;
typedef std::pair<Polynomial_1,Polynomial_1> Rational_function_key;
class Less_compare_rational_function_key
{
public:
Comparison_result compare(const Rational_function_key& k1,
const Rational_function_key& k2) const
{
Comparison_result cr =
typename Polynomial_traits_1::Compare()(k1.first, k2.first);
if (cr != CGAL::EQUAL)
return (cr);
cr = typename Polynomial_traits_1::Compare()(k1.second, k2.second);
return cr;
}
bool operator()(const Rational_function_key& k1,
const Rational_function_key& k2) const
{
Comparison_result cr = compare(k1,k2);
return ((cr == CGAL::LARGER) ? true : false);
}
};
typedef typename std::map<Rational_function_key,
Rational_function,
Less_compare_rational_function_key>
Rational_function_map;
typedef typename Rational_function::Id_type Rational_function_id_type;
typedef std::pair<Rational_function_id_type, Rational_function_id_type>
Rational_function_canonicalized_pair_key;
class Less_compare_rational_function_pair_key
{
public:
bool operator()(const Rational_function_canonicalized_pair_key& k1,
const Rational_function_canonicalized_pair_key& k2) const
{
return (k1<k2);
}
};
typedef typename std::map< Rational_function_canonicalized_pair_key,
Rational_function_canonicalized_pair,
Less_compare_rational_function_pair_key>
Rational_function_canonicalized_pair_map;
public:
Cache() :
_rat_func_map_watermark(128), _rat_pair_map_watermark(128), _ak_ptr(nullptr){};
void initialize(Algebraic_kernel_d_1* ak_ptr)
{
_ak_ptr = ak_ptr;
}
void initialize(const Self& other, Algebraic_kernel_d_1* ak_ptr)
{
//copy kernel pointer
_ak_ptr = ak_ptr;
//copy rational function map
typename Rational_function_map::const_iterator iter1;
for ( iter1 = other.rat_func_map().begin();
iter1 != other.rat_func_map().end();
++iter1)
{
if (iter1->second.is_shared())
{
Rational_function_key key = iter1->first;
//construct new instance
Rational_function f(iter1->second.numer(), iter1->second.denom(),
_ak_ptr);
_rat_func_map.insert(std::make_pair(key,f));
}
}
//copy rational function pair map
typename Rational_function_canonicalized_pair_map::const_iterator iter2;
for ( iter2 = other.rat_pair_map().begin();
iter2 != other.rat_pair_map().end();
++iter2)
{
if (iter2->second.is_shared())
{
Rational_function_canonicalized_pair_key key = iter2->first;
//construct new instance
Rational_function_canonicalized_pair p(iter2->second.f(),
iter2->second.g(), _ak_ptr);
_rat_pair_map.insert(std::make_pair(key,p));
}
}
}
const Rational_function_map& rat_func_map() const
{
return _rat_func_map;
}
const Rational_function_canonicalized_pair_map& rat_pair_map() const
{
return _rat_pair_map;
}
const Rational_function& get_rational_function(const Polynomial_1& numer,
const Polynomial_1& denom) const
{
CGAL_precondition (_ak_ptr != nullptr);
Rational_function_key key = get_key(numer,denom);
//look if element exists in cache already
typename Rational_function_map::iterator it = _rat_func_map.lower_bound(key);
if(it != _rat_func_map.end() && !(_rat_func_map.key_comp()(key, it->first)))
{
return it->second; //iterator to a type <key,value>
}
else //element does not exist, create it & insert to cache
{
//first check if to clean up cache
if (_rat_func_map.size() > _rat_func_map_watermark)
rat_func_map_clean_up();
//then insert the new element
Rational_function f(numer,denom,_ak_ptr);
typename Rational_function_map::iterator it2 =
_rat_func_map.insert(it,std::make_pair(key,f));
return it2->second;
}
}
const Rational_function& get_rational_function( const Rational& rat) const
{
Integer numer,denom;
typename FT_rat_1::Decompose()(rat,numer,denom);
Polynomial_1 numer_poly =
typename Polynomial_traits_1::Construct_polynomial()(numer);
Polynomial_1 denom_poly =
typename Polynomial_traits_1::Construct_polynomial()(denom);
return get_rational_function (numer_poly,denom_poly);
}
const Rational_function_pair get_rational_pair(const Rational_function& f,
const Rational_function& g) const
{
CGAL_precondition (_ak_ptr != nullptr);
CGAL_precondition(!(f==g));
Rational_function_canonicalized_pair_key key = get_key(f,g);
bool is_opposite = (f.id() < g.id()) ? false : true ;
//look if element exists in cache already
typename Rational_function_canonicalized_pair_map::iterator it =
_rat_pair_map.lower_bound(key);
if(it != _rat_pair_map.end() && !(_rat_pair_map.key_comp()(key, it->first)))
{
return (Rational_function_pair(it->second,is_opposite));
}
else //element does not exist,
{
//first check if to clean up cache
if (_rat_pair_map.size() > _rat_pair_map_watermark)
rat_pair_map_clean_up();
//create it & insert to cache
Rational_function_canonicalized_pair p(f, g, _ak_ptr);
std::pair<typename Rational_function_canonicalized_pair_map::const_iterator, bool> res =
_rat_pair_map.insert(std::make_pair(key,p));
return (Rational_function_pair(res.first->second,is_opposite));
}
}
void cleanup() const
{
rat_pair_map_clean_up();
rat_func_map_clean_up();
}
private:
Rational_function_key get_key(const Polynomial_1& numer,
const Polynomial_1& denom) const
{
return Rational_function_key(numer, denom);
}
Rational_function_key get_key(const Rational_function& f) const
{
return get_key(f.numer(), f.denom());
}
Rational_function_canonicalized_pair_key
get_key(const Rational_function& f, const Rational_function& g) const
{
return (f.id() < g.id()) ?
Rational_function_canonicalized_pair_key( f.id(),g.id() ):
Rational_function_canonicalized_pair_key( g.id(),f.id() );
}
void rat_func_map_clean_up() const
{
//find eraseable rational functions
std::vector<Rational_function_key> eraseable;
typename Rational_function_map::iterator iter1;
for ( iter1 = _rat_func_map.begin();
iter1 != _rat_func_map.end();
++iter1)
{
if (iter1->second.is_shared() == false)
eraseable.push_back(iter1->first);
}
//erase functions
typename std::vector<Rational_function_key>::iterator iter2;
for ( iter2 = eraseable.begin();
iter2 != eraseable.end();
++iter2)
{
_rat_func_map.erase(*iter2);
}
//re-set watermark
_rat_func_map_watermark
= static_cast<unsigned int>((std::max)(2* _rat_func_map.size(),
typename Rational_function_map::size_type(128)));
return;
}
void rat_pair_map_clean_up() const
{
//find eraseable rational functions
std::vector<Rational_function_canonicalized_pair_key> eraseable;
typename Rational_function_canonicalized_pair_map::iterator iter1;
for ( iter1 = _rat_pair_map.begin();
iter1 != _rat_pair_map.end();
++iter1)
{
if (iter1->second.is_shared() == false)
eraseable.push_back(iter1->first);
}
//erase functions
typename std::vector<Rational_function_canonicalized_pair_key>::iterator iter2;
for ( iter2 = eraseable.begin();
iter2 != eraseable.end();
++iter2)
{
_rat_pair_map.erase(*iter2);
}
//re-set watermark
_rat_pair_map_watermark =
static_cast<unsigned int>((std::max)(2* _rat_pair_map.size(),
typename Rational_function_canonicalized_pair_map::size_type(128)));
}
private:
mutable Rational_function_map _rat_func_map;
mutable unsigned int _rat_func_map_watermark;
mutable Rational_function_canonicalized_pair_map _rat_pair_map;
mutable unsigned int _rat_pair_map_watermark;
mutable Algebraic_kernel_d_1* _ak_ptr;
}; //Cache
} //namespace Arr_rational_arc
} //namespace CGAL {
#endif //CGAL_RATIONAL_ARC_CACHE