diff --git a/CHANGELOG.md b/CHANGELOG.md index 69533920..6632391c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,17 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/) et ce pr ### Added ### Changed + +- `Cache` : Export de toutes les classes implémentées dans Cache dans leurs propres fichiers. Les fichiers ajoutés sont : + * `CurlPool` + * `ProjPool` + * `StoragePool` + * `IndexCache` + * `IndexElement` + * `TmsBook` + * `StyleBook` + * `CrsBook` + ### Deprecated ### Removed ### Fixed diff --git a/README.md b/README.md index 0ab83793..089caf0a 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,11 @@ Le programme qui suit charge une pyramide SCAN1000 à partir de son descripteur, #include #include #include -#include "rok4/utils/Cache.h" +#include "rok4/utils/CrsBook.h" +#include "rok4/utils/TmsBook.h" +#include "rok4/utils/ProjPool.h" +#include "rok4/utils/IndexCache.h" +#include "rok4/utils/StoragePool.h" int main( int argc, char *argv[] ) { diff --git a/include/rok4/image/Image.h b/include/rok4/image/Image.h index 1a32238f..495391a1 100644 --- a/include/rok4/image/Image.h +++ b/include/rok4/image/Image.h @@ -51,8 +51,8 @@ #include #include "rok4/utils/BoundingBox.h" -#include "rok4/utils/CRS.h" -#include "rok4/utils/Cache.h" +#include "rok4/utils/CrsBook.h" + #define METER_PER_DEG 111319.492 diff --git a/include/rok4/processors/Grid.h b/include/rok4/processors/Grid.h index 06dabe0c..cbfc36bd 100644 --- a/include/rok4/processors/Grid.h +++ b/include/rok4/processors/Grid.h @@ -49,6 +49,7 @@ #include "rok4/utils/CRS.h" #include #include +#include "rok4/utils/ProjPool.h" /** * \author Institut national de l'information géographique et forestière diff --git a/include/rok4/style/Style.h b/include/rok4/style/Style.h index 766a22d6..33bc9556 100644 --- a/include/rok4/style/Style.h +++ b/include/rok4/style/Style.h @@ -57,6 +57,7 @@ class Style; #include "rok4/style/Aspect.h" #include "rok4/enums/Interpolation.h" #include "rok4/utils/Configuration.h" +#include "rok4/utils/StoragePool.h" #include "rok4/enums/Format.h" /** diff --git a/include/rok4/utils/CRS.h b/include/rok4/utils/CRS.h index ab29e51e..2cf8d0ea 100644 --- a/include/rok4/utils/CRS.h +++ b/include/rok4/utils/CRS.h @@ -47,7 +47,11 @@ #pragma once #include +#include +#include #include "rok4/utils/BoundingBox.h" +#include "rok4/utils/ProjPool.h" +#include "rok4/utils/Utils.h" /** * \~french \brief Code utilisé en cas de non correspondance avec les référentiel de Proj diff --git a/include/rok4/utils/Cache.h b/include/rok4/utils/Cache.h deleted file mode 100644 index 811a7d0e..00000000 --- a/include/rok4/utils/Cache.h +++ /dev/null @@ -1,1096 +0,0 @@ -/* - * Copyright © (2011) Institut national de l'information - * géographique et forestière - * - * Géoportail SAV - * - * This software is a computer program whose purpose is to publish geographic - * data using OGC WMS and WMTS protocol. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * - * knowledge of the CeCILL-C license and that you accept its terms. - */ - -/** - * \file Cache.h - ** \~french - * \brief Définition des classes IndexCache, CurlPool, StoragePool et ProjPool - ** \~english - * \brief Define classes IndexCache, CurlPool, StoragePool and ProjPool - */ - -#pragma once - -#include // pour uint8_t -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "rok4/utils/TileMatrixSet.h" -#include "rok4/style/Style.h" -#include "rok4/utils/Utils.h" -#include "rok4/utils/CRS.h" -#include "rok4/storage/Context.h" - -#define ROK4_TMS_DIRECTORY "ROK4_TMS_DIRECTORY" -#define ROK4_TMS_NO_CACHE "ROK4_TMS_NO_CACHE" -#define ROK4_STYLES_DIRECTORY "ROK4_STYLES_DIRECTORY" -#define ROK4_STYLES_NO_CACHE "ROK4_STYLES_NO_CACHE" - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un pool d'environnement Curl - * \details Cette classe est prévue pour être utilisée sans instance - */ -class CurlPool { - -private: - - /** - * \~french \brief Annuaire des objet Curl - * \details La clé est l'identifiant du thread - * \~english \brief Curl object book - * \details Key is the thread's ID - */ - static std::map pool; - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - CurlPool(){}; - -public: - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~CurlPool(){}; - - /** - * \~french \brief Retourne un objet Curl propre au thread appelant - * \details Si il n'existe pas encore d'objet curl pour ce tread, on le crée et on l'initialise - * \~english \brief Get the curl object specific to the calling thread - * \details If curl object doesn't exist for this thread, it is created and initialized - */ - static CURL* get_curl_env() { - pthread_t i = pthread_self(); - - std::map::iterator it = pool.find ( i ); - if ( it == pool.end() ) { - CURL* c = curl_easy_init(); - pool.insert ( std::pair(i,c) ); - return c; - } else { - curl_easy_reset(it->second); - return it->second; - } - } - - /** - * \~french \brief Affiche le nombre d'objet curl dans l'annuaire - * \~english \brief Print the number of curl objects in the book - */ - static void print_curls_count () { - BOOST_LOG_TRIVIAL(info) << "Nombre de contextes curl : " << pool.size(); - } - - /** - * \~french \brief Nettoie tous les objets curl dans l'annuaire et le vide - * \~english \brief Clean all curl objects in the book and empty it - */ - static void clean_curls () { - std::map::iterator it; - for (it = pool.begin(); it != pool.end(); ++it) { - curl_easy_cleanup(it->second); - } - pool.clear(); - } - -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un pool de contextes Proj - * \details Cette classe est prévue pour être utilisée sans instance - */ -class ProjPool { - -private: - - /** - * \~french \brief Annuaire des contextes Proj - * \details La clé est l'identifiant du thread - * \~english \brief Proj contexts book - * \details Key is the thread's ID - */ - static std::map pool; - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - ProjPool(){}; - -public: - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~ProjPool(){}; - - /** - * \~french \brief Retourne un contexte Proj propre au thread appelant - * \details Si il n'existe pas encore de contexte Proj pour ce tread, on le crée et on l'initialise - * \~english \brief Get the Proj context specific to the calling thread - * \details If Proj context doesn't exist for this thread, it is created and initialized - */ - static PJ_CONTEXT* get_proj_env() { - pthread_t i = pthread_self(); - - std::map::iterator it = pool.find ( i ); - if ( it == pool.end() ) { - PJ_CONTEXT* pjc = proj_context_create(); - proj_log_level(pjc, PJ_LOG_NONE); - pool.insert ( std::pair(i,pjc) ); - return pjc; - } else { - return it->second; - } - } - - /** - * \~french \brief Affiche le nombre de contextes proj dans l'annuaire - * \~english \brief Print the number of proj contexts in the book - */ - static void print_projs_count () { - BOOST_LOG_TRIVIAL(info) << "Nombre de contextes proj : " << pool.size() ; - } - - /** - * \~french \brief Nettoie tous les contextes proj dans l'annuaire et le vide - * \~english \brief Clean all proj objects in the book and empty it - */ - static void clean_projs () { - std::map::iterator it; - for (it = pool.begin(); it != pool.end(); ++it) { - proj_context_destroy(it->second); - } - pool.clear(); - } - -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un pool de contextes de stockage - * \details Cette classe est prévue pour être utilisée sans instance - */ -class StoragePool { - -private: - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - StoragePool(){}; - - /** - * \~french \brief Annuaire de contextes - * \details La clé est une paire composée du type de stockage et du contenant du contexte - * \~english \brief Book of contexts - * \details Key is a pair composed of type of storage and the context's bucket - */ - static std::map,Context*> pool; - - -public: - - - /** - * \~french \brief Retourne une chaîne de caracère décrivant l'annuaire - * \~english \brief Return a string describing the pool - */ - static std::string to_string() { - std::ostringstream oss; - oss.setf ( std::ios::fixed,std::ios::floatfield ); - oss << "------ Context pool -------" << std::endl; - oss << "\t- context number = " << pool.size() << std::endl; - - std::map, Context*>::iterator it = pool.begin(); - while (it != pool.end()) { - std::pair key = it->first; - oss << "\t\t- pot = " << key.first << "/" << key.second << std::endl; - oss << it->second->to_string() << std::endl; - it++; - } - - return oss.str() ; - } - - /** - * \~french - * \brief Récupère un contexte de stockage - * \details Si un contexte existe déjà pour ce nom de contenant, on ne crée pas de nouveau contexte et on retourne celui déjà existant. Le nouveau contexte n'est pas connecté. - * \param[in] type type de stockage pour lequel on veut créer un contexte - * \param[in] tray Nom du contenant pour lequel on veut créer un contexte - * \param[in] reference_context Contexte de stockage de référence - - * \brief Get a context storage - * \details If a context already exists for this tray's name, we don't create a new one and the existing is returned. New context is not connected. - * \param[in] type Storage Type for which context is created - * \param[in] tray Tray's name for which context is created - * \param[in] reference_context Reference storage context - - */ - static Context * get_context(ContextType::eContextType type,std::string tray, Context* reference_context = 0) ; - - - /** - * \~french \brief Retourne le nombre de contextes de stockage dans l'annuaire par type - * \param[out] file_count Nombre de contexte de stockage fichier - * \param[out] s3_count Nombre de contexte de stockage S3 - * \param[out] ceph_count Nombre de contexte de stockage Ceph - * \param[out] swift_count Nombre de contexte de stockage Swift - * \~english \brief Return the number of storage contexts in the book per type - * \param[out] file_count File storage context count - * \param[out] s3_count S3 storage context count - * \param[out] ceph_count Ceph storage context count - * \param[out] swift_count Swift storage context count - */ - static void get_storages_count (int& file_count, int& s3_count, int& ceph_count, int& swift_count) { - file_count = 0; - s3_count = 0; - ceph_count = 0; - swift_count = 0; - std::map, Context*>::iterator it = pool.begin(); - while (it != pool.end()) { - std::pair key = it->first; - switch(key.first) { -#if CEPH_ENABLED - case ContextType::CEPHCONTEXT: - ceph_count++; - break; -#endif - case ContextType::SWIFTCONTEXT: - swift_count++; - break; - case ContextType::S3CONTEXT: - s3_count++; - break; - case ContextType::FILECONTEXT: - file_count++; - break; - } - it++; - } - } - - /** - * \~french \brief Obtient l'annuaire de contextes - * \details La clé est une paire composée du type de stockage et du contenant du contexte - * \~english \brief Get book of contexts - * \details Key is a pair composed of type of storage and the context's bucket - */ - static std::map,Context*> get_pool() { - return pool; - } - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~StoragePool() {}; - - /** - * \~french \brief Nettoie tous les contextes de stockage dans l'annuaire et le vide - * \~english \brief Clean all storage context objects in the book and empty it - */ - static void clean_storages () { - std::map,Context*>::iterator it; - for (it=pool.begin(); it!=pool.end(); ++it) { - delete it->second; - it->second = NULL; - } - } - -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Élément du cache des index de dalle - */ -class IndexElement { -friend class IndexCache; - -protected: - /** - * \~french \brief Date d'enregistrement dans le cache - * \~english \brief Cache date - */ - std::time_t date; - /** - * \~french \brief Clé sous laquelle l'élément est enregistré dans le cache - * \~english \brief Cache key - */ - std::string key; - /** - * \~french \brief Nom de la dalle dans laquelle lire la donnée - * \~english \brief Data slab to read - */ - std::string name; - /** - * \~french \brief Contexte de stockage de la dalle de donnée - * \~english \brief Data slab storage context - */ - Context* context; - /** - * \~french \brief Offsets des tuiles dans la dalle - * \~english \brief Tiles' offsets - */ - std::vector offsets; - /** - * \~french \brief Tailles des tuiles dans la dalle - * \~english \brief Tiles' sizes - */ - std::vector sizes; - - /** \~french - * \brief Constructeur - * \param[in] k clé d'enregistrement dans le cache - * \param[in] s nom de la dalle - * \param[in] c contexte de stockage de la dalle - * \param[in] tiles_number nombre de tuiles dans la dalles - * \param[in] os offsets bruts des tuiles - * \param[in] ss tailles brutes des tuiles - ** \~english - * \brief Constructor - * \param[in] k cache key - * \param[in] s data slab name - * \param[in] c data slab storage context - * \param[in] tiles_number tiles number - * \param[in] os raw tiles' offsets - * \param[in] ss raw tiles' sizes - */ - IndexElement(std::string k, Context* c, std::string n, int tiles_number, uint8_t* os, uint8_t* ss) { - key = k; - context = c; - name = n; - date = std::time(NULL); - for (int i = 0; i < tiles_number; i++) { - offsets.push_back(*((uint32_t*) (os + i*4))); - sizes.push_back(*((uint32_t*) (ss + i*4))); - } - }; -}; - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un cache des index de dalle - * \details Cette classe est prévue pour être utilisée sans instance - */ -class IndexCache { - -private: - - /** - * \~french \brief Liste des éléments en cache - * \~english \brief Cache elements list - */ - static std::list cache; - /** - * \~french \brief Map d'index des éléments du cache - * \~english \brief Cache element index map - */ - static std::unordered_map::iterator> map; - /** - * \~french \brief Taille du cache en nombre d'élément - * \details 100 par défaut - * \~english \brief Cache size - * \details Default value : 100 - */ - static int size; - /** - * \~french \brief Durée de validité en seconde d'un élément du cache - * \details 300 par défaut (5 minutes) - * \~english \brief Cache element's validity period, in seconds - * \details Default value : 300 (5 minutes) - */ - static int validity; - - /** - * \~french \brief Exclusion mutuelle - * \details Pour éviter les modifications concurrentes du cache des index - * \~english \brief Mutual exclusion - * \details To avoid concurrent index cache updates - */ - static std::mutex mtx; - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - IndexCache(){}; - -public: - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~IndexCache(){}; - - /** \~french - * \brief Définit la taille du cache - * \param[in] s taille du cache - ** \~english - * \brief Define cache size - * \param[in] s cache size - */ - static void setCacheSize(int s) { - size = s; - }; - - /** \~french - * \brief Définit la durée de validité - * \param[in] s durée de validité du cache, en secondes - ** \~english - * \brief Define cache validity - * \param[in] s cache validity, in seconds - */ - static void set_validity(int v) { - validity = v; - }; - - /** \~french - * \brief Ajoute un élément au cache - * \param[in] origin_slab_name nom d'interrogation de la dalle - * \param[in] data_context contexte de stockage de la dalle de donnée - * \param[in] data_slab_name nom de la dalle réelle contenant les données - * \param[in] tiles_number nombre de tuiles dans la dalles - * \param[in] os offsets bruts des tuiles - * \param[in] ss tailles brutes des tuiles - ** \~english - * \brief Add element to cache - * \param[in] origin_slab_name Slab request name - * \param[in] data_context data slab storage context - * \param[in] data_slab_name data slab name - * \param[in] tiles_number tiles number - * \param[in] os raw tiles' offsets - * \param[in] ss raw tiles' sizes - */ - static void add_slab_infos(std::string origin_slab_name, Context* data_context, std::string data_slab_name, int tiles_number, uint8_t* offsets, uint8_t* sizes) { - // On utilise le nom original de la dalle (celle à lire a priori) comme clé dans la map - // Potentiellement ce nom est différent de la vraie dalle contenant la donnée (dans le cas d'une dalle symbolique) - // mais c'est via cette dalle symbolique que la donnée est a priori requêtée - // donc c'est ce nom qu'on utilisera pour l'interrogation du cache - - mtx.lock(); - - IndexElement* elem = new IndexElement(origin_slab_name, data_context, data_slab_name, tiles_number, offsets, sizes); - - // L'information n'est a priori pas dans le cache car - // Soit elle était dans le cache et valide, alors on aurait utilisé ce cache et on n'aurait pas fait appel à cet ajout - // Soit elle était dans le cache mais obsolète, alors on l'aurait déjà supprimé du cache - - if (cache.size() == size) { - // On récupère le dernier élément du cache - IndexElement* last = cache.back(); - // On le vire du cache - cache.pop_back(); - // On le déréférence de la map d'accès - map.erase(last->key); - delete last; - } - - // update reference - cache.push_front(elem); - map[origin_slab_name] = cache.begin(); - - mtx.unlock(); - }; - - /** \~french - * \brief Demande un élément du cache - * \param[in] key nom d'interrogation de la dalle - * \param[in] tile_number numéro de la tuile voulue - * \param[out] data_context contexte de stockage de la dalle de donnée - * \param[out] data_slab_name nom de la dalle contenant les données - * \param[out] offset offset de la tuile - * \param[out] size taille de la tuile - ** \~english - * \brief Ask element from cache - * \param[in] key Slab request name - * \param[in] tile_number tile indice - * \param[out] data_context data slab storage context - * \param[out] data_slab_name Real data slab - * \param[out] offset tile's offset - * \param[out] size tile's size - */ - static bool get_slab_infos(std::string key, int tile_number, Context** data_context, std::string* data_slab_name, uint32_t* offset, uint32_t* size) { - std::unordered_map::iterator>::iterator it = map.find ( key ); - if ( it == map.end() ) { - return false; - } else { - // Gestion de la péremption du cache (une heure max) - std::time_t now = std::time(NULL); - if (now - (*(it->second))->date > validity) { - mtx.lock(); - - // on le cherche à nouveau pour vérifier qu'il n'a pas déjà été supprimé par un thread concurrent - it = map.find ( key ); - - if ( it != map.end() ) { - delete *(it->second); - cache.erase(it->second); - map.erase(it); - } - - mtx.unlock(); - - return false; - } - - *data_slab_name = (*(it->second))->name; - *data_context = (*(it->second))->context; - *offset = (*(it->second))->offsets.at(tile_number); - *size = (*(it->second))->sizes.at(tile_number); - - // On fait le choix de ne pas remettre en tête du cache cet élément, même s'il vient d'être accéder - // C'est parce qu'en plus d'avoir une taille limite, les élément cachés ont une date de péromption - // Il serait donc dommage de remettre en avant (donc plus loin d'une suppression par taille de cache atteinte) - // un élément qui va de toute manière finir par être obsolète. - // C'est une différence avec une cache LRU classique - - return true; - } - }; - - /** - * \~french \brief Nettoie tous les objets dans le cache - * \~english \brief Clean all element from the cache - */ - static void clean_indexes () { - mtx.lock(); - std::list::iterator it; - for (it = cache.begin(); it != cache.end(); ++it) { - delete *it; - } - cache.clear(); - mtx.unlock(); - } -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un annuaire de Tile Matrix Sets - * \details Cette classe est prévue pour être utilisée sans instance - */ -class TmsBook { - -private: - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - TmsBook(){}; - - /** - * \~french - * \brief Répertoire de stockage des TMS - * \~english - * \brief TMS storage directory - */ - static std::string directory; - - /** - * \~french \brief Annuaire de TMS - * \details La clé est l'identifiant du TMS - * \~english \brief Book of TMS - * \details Key is a the TMS identifier - */ - static std::map book; - - /** - * \~french \brief Corbeille de TMS à supprimer - * \~english \brief TMS trash to delete - */ - static std::vector trash; - - /** - * \~french \brief Exclusion mutuelle - * \details Pour éviter les modifications concurrentes du cache de TMS - * \~english \brief Mutual exclusion - * \details To avoid concurrent TMS cache updates - */ - static std::mutex mtx; - -public: - - - /** - * \~french \brief Vide l'annuaire et met le contenu à la corbeille - * \~english \brief Empty book and put content into trash - */ - static void send_to_trash () { - mtx.lock(); - std::map::iterator it; - for (it = book.begin(); it != book.end(); ++it) { - trash.push_back(it->second); - } - book.clear(); - mtx.unlock(); - } - - /** - * \~french \brief Vide la corbeille - * \~english \brief Empty trash - */ - static void empty_trash () { - mtx.lock(); - for (int i = 0; i < trash.size(); i++) { - delete trash.at(i); - } - trash.clear(); - mtx.unlock(); - } - - - /** - * \~french \brief Renseigne le répertoire des TMS - * \~english \brief Set TMS directory - */ - static void set_directory (std::string d) { - // Suppression du slash final - if (d.compare ( d.size()-1,1,"/" ) == 0) { - d.pop_back(); - } - directory = d; - } - - /** - * \~french \brief Retourne l'ensemble de l'annuaire - * \~english \brief Return the book - */ - static std::map get_book () { - return book; - } - - /** - * \~french - * \brief Retourne le TMS d'après son identifiant - * \details Si le TMS demandé n'est pas encore dans l'annuaire, ou que l'on ne veut pas de cache, il est recherché dans le répertoire connu et chargé - * \param[in] id Identifiant du TMS voulu - - * \brief Return the TMS according to its identifier - * \details If TMS is still not in the book, or cache is disabled, it is searched in the known directory and loaded - * \param[in] id Wanted TMS identifier - */ - static TileMatrixSet* get_tms(std::string id) { - std::map::iterator it = book.find ( id ); - if ( it != book.end() ) { - return it->second; - } - - std::string d; - if (directory.empty()) { - char* e = getenv (ROK4_TMS_DIRECTORY); - if (e == NULL) { - d.assign("/usr/share/rok4/tilematrixsets"); - } else { - d.assign(e); - } - } else { - d = directory; - } - - std::string tms_path = d + "/" + id; - - mtx.lock(); - // Si on fait du cache de TMS, on revérifie que ce TMS n'a pas déjà été ajouté par un thread concurrent entre temps - if(getenv (ROK4_TMS_NO_CACHE) == NULL) { - if ( it != book.end() ) { - // On a effectivement depuis déjà enregistré ce TMS - return it->second; - } - } - - TileMatrixSet* tms = new TileMatrixSet(tms_path); - if ( ! tms->is_ok() ) { - BOOST_LOG_TRIVIAL(error) << tms->get_error_message(); - delete tms; - mtx.unlock(); - return NULL; - } - - if(getenv (ROK4_TMS_NO_CACHE) == NULL) { - // On veut utiliser le cache, on met donc ce nouveau TMS dans l'annuaire pour le trouver la prochaine fois - book.insert ( std::pair(id, tms) ); - } else { - // On met le TMS directement dans la corbeille, pour que le nettoyage se fasse bien - trash.push_back(tms); - } - - mtx.unlock(); - - return tms; - } - - /** - * \~french \brief Retourne le nombre de TMS dans l'annuaire - * \~english \brief Return the number of TMS in the book - */ - static int get_tms_count () { - return book.size(); - } - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~TmsBook() {}; - -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un annuaire de styles - * \details Cette classe est prévue pour être utilisée sans instance - */ -class StyleBook { - -private: - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - StyleBook(){}; - - /** - * \~french - * \brief Répertoire de stockage des styles - * \~english - * \brief TMS storage directory - */ - static std::string directory; - - /** - * \~french \brief Annuaire de styles - * \details La clé est l'identifiant du style - * \~english \brief Book of styles - * \details Key is a the style identifier - */ - static std::map book; - - /** - * \~french \brief Corbeille de styles à supprimer - * \~english \brief Styles trash to delete - */ - static std::vector trash; - - /** - * \~french \brief Exclusion mutuelle - * \details Pour éviter les modifications concurrentes du cache de styles - * \~english \brief Mutual exclusion - * \details To avoid concurrent styles cache updates - */ - static std::mutex mtx; - -public: - - - /** - * \~french \brief Vide l'annuaire et met le contenu à la corbeille - * \~english \brief Empty book and put content into trash - */ - static void send_to_trash () { - mtx.lock(); - std::map::iterator it; - for (it = book.begin(); it != book.end(); ++it) { - trash.push_back(it->second); - } - book.clear(); - mtx.unlock(); - } - - /** - * \~french \brief Vide la corbeille - * \~english \brief Empty trash - */ - static void empty_trash () { - mtx.lock(); - for (int i = 0; i < trash.size(); i++) { - delete trash.at(i); - } - trash.clear(); - mtx.unlock(); - } - - - /** - * \~french \brief Renseigne le répertoire des style - * \~english \brief Set styles directory - */ - static void set_directory (std::string d) { - // Suppression du slash final - if (d.compare ( d.size()-1,1,"/" ) == 0) { - d.pop_back(); - } - directory = d; - } - - /** - * \~french \brief Retourne l'ensemble de l'annuaire - * \~english \brief Return the book - */ - static std::map get_book () { - return book; - } - - /** - * \~french - * \brief Retourne le style d'après son identifiant - * \details Si le style demandé n'est pas encore dans l'annuaire, ou que l'on ne veut pas de cache, il est recherché dans le répertoire connu et chargé - * \param[in] id Identifiant du style voulu - - * \brief Return the style according to its identifier - * \details If style is still not in the book, or cache is disabled, it is searched in the known directory and loaded - * \param[in] id Wanted style identifier - */ - static Style* get_style(std::string id) { - - std::map::iterator it = book.find ( id ); - if ( it != book.end() ) { - return it->second; - } - - std::string d; - if (directory.empty()) { - char* e = getenv (ROK4_STYLES_DIRECTORY); - if (e == NULL) { - d.assign("/usr/share/rok4/styles"); - } else { - d.assign(e); - } - } else { - d = directory; - } - - std::string style_path = d + "/" + id; - - mtx.lock(); - // Si on fait du cache de style, on revérifie que ce style n'a pas déjà été ajouté par un thread concurrent entre temps - if(getenv (ROK4_STYLES_NO_CACHE) == NULL) { - if ( it != book.end() ) { - // On a effectivement depuis déjà enregistré ce style - return it->second; - } - } - - Style* style = new Style(style_path); - if ( ! style->is_ok() ) { - BOOST_LOG_TRIVIAL(error) << style->get_error_message(); - delete style; - mtx.unlock(); - return NULL; - } - - if ( contain_chars(style->get_identifier(), "<>") ) { - BOOST_LOG_TRIVIAL(error) << "Style identifier contains forbidden chars" ; - delete style; - mtx.unlock(); - return NULL; - } - - if(getenv (ROK4_STYLES_NO_CACHE) == NULL) { - // On veut utiliser le cache, on met donc ce nouveau style dans l'annuaire pour le trouver la porchaine fois - book.insert ( std::pair(id, style) ); - } else { - // On met le style directement dans la corbeille, pour que le nettoyage se fasse bien - trash.push_back(style); - } - - mtx.unlock(); - return style; - } - - /** - * \~french \brief Retourne le nombre de styles dans l'annuaire - * \~english \brief Return the number of styles in the book - */ - static int get_styles_count () { - return book.size(); - } - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~StyleBook() {}; - -}; - - -/** - * \author Institut national de l'information géographique et forestière - * \~french - * \brief Création d'un annuaire de CRS - * \details Cette classe est prévue pour être utilisée sans instance - */ -class CrsBook { - -private: - - /** - * \~french - * \brief Constructeur - * \~english - * \brief Constructeur - */ - CrsBook(){}; - - /** - * \~french \brief Annuaire de styles - * \details La clé est l'identifiant du style - * \~english \brief Book of styles - * \details Key is a the style identifier - */ - static std::map book; - - /** - * \~french \brief Exclusion mutuelle - * \details Pour éviter les modifications concurrentes du cache de CRS - * \~english \brief Mutual exclusion - * \details To avoid concurrent CRS cache updates - */ - static std::mutex mtx; - -public: - - - /** - * \~french - * \brief Retourne le CRS d'après son identifiant (code de requête) - * \param[in] id Identifiant du CRS voulu - - * \brief Return the style according to its identifier - * \param[in] id Wanted style identifier - */ - static CRS* get_crs(std::string id) { - - id = to_upper_case(id); - - std::map::iterator it = book.find ( id ); - if ( it != book.end() ) { - return it->second; - } - - mtx.lock(); - - CRS* crs = new CRS(id); - // Le CRS est potentiellement non défini (si il n'est pas valide), on le mémorise pour ne pas réessayer la prochaine fois - book.emplace(id, crs); - - mtx.unlock(); - return crs; - } - - /** - * \~french \brief Nettoie tous les CRS dans l'annuaire et le vide - * \~english \brief Clean all CRS objects in the book and empty it - */ - static void clean_crss () { - mtx.lock(); - std::map::iterator it; - for (it = book.begin(); it != book.end(); ++it) { - delete it->second; - } - book.clear(); - mtx.unlock(); - } - - /** - * \~french - * \brief Destructeur - * \~english - * \brief Destructor - */ - ~CrsBook() {}; - -}; - - diff --git a/include/rok4/utils/CrsBook.h b/include/rok4/utils/CrsBook.h new file mode 100644 index 00000000..6c608760 --- /dev/null +++ b/include/rok4/utils/CrsBook.h @@ -0,0 +1,117 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file CrsBook.h + ** \~french + * \brief Définition de la classe CrsBook + ** \~english + * \brief Define classe CrsBook + */ + +#pragma once + +#include +#include +#include +#include + +#include "rok4/utils/CRS.h" +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un annuaire de CRS + * \details Cette classe est prévue pour être utilisée sans instance + */ +class CrsBook { + +private: + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + CrsBook(); + + /** + * \~french \brief Annuaire de styles + * \details La clé est l'identifiant du style + * \~english \brief Book of styles + * \details Key is a the style identifier + */ + static std::map book; + + /** + * \~french \brief Exclusion mutuelle + * \details Pour éviter les modifications concurrentes du cache de CRS + * \~english \brief Mutual exclusion + * \details To avoid concurrent CRS cache updates + */ + static std::mutex mtx; + +public: + + + /** + * \~french + * \brief Retourne le CRS d'après son identifiant (code de requête) + * \param[in] id Identifiant du CRS voulu + + * \brief Return the style according to its identifier + * \param[in] id Wanted style identifier + */ + static CRS* get_crs(std::string id); + + /** + * \~french \brief Nettoie tous les CRS dans l'annuaire et le vide + * \~english \brief Clean all CRS objects in the book and empty it + */ + static void clean_crss (); + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~CrsBook(); + +}; + + diff --git a/include/rok4/utils/CurlPool.h b/include/rok4/utils/CurlPool.h new file mode 100644 index 00000000..0f239b18 --- /dev/null +++ b/include/rok4/utils/CurlPool.h @@ -0,0 +1,101 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +#pragma once + +#include +#include +#include +#include + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un pool d'environnement Curl + * \details Cette classe est prévue pour être utilisée sans instance + */ +class CurlPool { + +private: + + /** + * \~french \brief Annuaire des objet Curl + * \details La clé est l'identifiant du thread + * \~english \brief Curl object book + * \details Key is the thread's ID + */ + static std::map pool; + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + CurlPool(){}; + +public: + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~CurlPool(); + + /** + * \~french \brief Retourne un objet Curl propre au thread appelant + * \details Si il n'existe pas encore d'objet curl pour ce tread, on le crée et on l'initialise + * \~english \brief Get the curl object specific to the calling thread + * \details If curl object doesn't exist for this thread, it is created and initialized + */ + static CURL* get_curl_env(); + + /** + * \~french \brief Affiche le nombre d'objet curl dans l'annuaire + * \~english \brief Print the number of curl objects in the book + */ + static void print_curls_count (); + + /** + * \~french \brief Nettoie tous les objets curl dans l'annuaire et le vide + * \~english \brief Clean all curl objects in the book and empty it + */ + static void clean_curls (); + +}; diff --git a/include/rok4/utils/IndexCache.h b/include/rok4/utils/IndexCache.h new file mode 100644 index 00000000..37080b9f --- /dev/null +++ b/include/rok4/utils/IndexCache.h @@ -0,0 +1,182 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file IndexCache.h + ** \~french + * \brief Définition de la classes IndexCache + ** \~english + * \brief Define classe IndexCache + */ + +#pragma once + +#include // pour uint8_t +#include +#include +#include +#include +#include +#include +#include + +#include "rok4/utils/IndexElement.h" +#include "rok4/storage/Context.h" + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un cache des index de dalle + * \details Cette classe est prévue pour être utilisée sans instance + */ +class IndexCache { + +private: + + /** + * \~french \brief Liste des éléments en cache + * \~english \brief Cache elements list + */ + static std::list cache; + /** + * \~french \brief Map d'index des éléments du cache + * \~english \brief Cache element index map + */ + static std::unordered_map::iterator> map; + /** + * \~french \brief Taille du cache en nombre d'élément + * \details 100 par défaut + * \~english \brief Cache size + * \details Default value : 100 + */ + static int size; + /** + * \~french \brief Durée de validité en seconde d'un élément du cache + * \details 300 par défaut (5 minutes) + * \~english \brief Cache element's validity period, in seconds + * \details Default value : 300 (5 minutes) + */ + static int validity; + + /** + * \~french \brief Exclusion mutuelle + * \details Pour éviter les modifications concurrentes du cache des index + * \~english \brief Mutual exclusion + * \details To avoid concurrent index cache updates + */ + static std::mutex mtx; + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + IndexCache(); + +public: + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~IndexCache(); + + /** \~french + * \brief Définit la taille du cache + * \param[in] s taille du cache + ** \~english + * \brief Define cache size + * \param[in] s cache size + */ + static void setCacheSize(int s); + + /** \~french + * \brief Définit la durée de validité + * \param[in] s durée de validité du cache, en secondes + ** \~english + * \brief Define cache validity + * \param[in] s cache validity, in seconds + */ + static void set_validity(int v); + + /** \~french + * \brief Ajoute un élément au cache + * \param[in] origin_slab_name nom d'interrogation de la dalle + * \param[in] data_context contexte de stockage de la dalle de donnée + * \param[in] data_slab_name nom de la dalle réelle contenant les données + * \param[in] tiles_number nombre de tuiles dans la dalles + * \param[in] os offsets bruts des tuiles + * \param[in] ss tailles brutes des tuiles + ** \~english + * \brief Add element to cache + * \param[in] origin_slab_name Slab request name + * \param[in] data_context data slab storage context + * \param[in] data_slab_name data slab name + * \param[in] tiles_number tiles number + * \param[in] os raw tiles' offsets + * \param[in] ss raw tiles' sizes + */ + static void add_slab_infos(std::string origin_slab_name, Context* data_context, std::string data_slab_name, int tiles_number, uint8_t* offsets, uint8_t* sizes); + + /** \~french + * \brief Demande un élément du cache + * \param[in] key nom d'interrogation de la dalle + * \param[in] tile_number numéro de la tuile voulue + * \param[out] data_context contexte de stockage de la dalle de donnée + * \param[out] data_slab_name nom de la dalle contenant les données + * \param[out] offset offset de la tuile + * \param[out] size taille de la tuile + ** \~english + * \brief Ask element from cache + * \param[in] key Slab request name + * \param[in] tile_number tile indice + * \param[out] data_context data slab storage context + * \param[out] data_slab_name Real data slab + * \param[out] offset tile's offset + * \param[out] size tile's size + */ + static bool get_slab_infos(std::string key, int tile_number, Context** data_context, std::string* data_slab_name, uint32_t* offset, uint32_t* size); + + /** + * \~french \brief Nettoie tous les objets dans le cache + * \~english \brief Clean all element from the cache + */ + static void clean_indexes (); +}; \ No newline at end of file diff --git a/include/rok4/utils/IndexElement.h b/include/rok4/utils/IndexElement.h new file mode 100644 index 00000000..591619cb --- /dev/null +++ b/include/rok4/utils/IndexElement.h @@ -0,0 +1,112 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file IndexElement.h + ** \~french + * \brief Définition de la classe IndexElement + ** \~english + * \brief Define classe IndexElement + */ + +#pragma once + +#include +#include +#include + +#include "rok4/storage/Context.h" + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Élément du cache des index de dalle + */ +class IndexElement { +friend class IndexCache; + +protected: + /** + * \~french \brief Date d'enregistrement dans le cache + * \~english \brief Cache date + */ + std::time_t date; + /** + * \~french \brief Clé sous laquelle l'élément est enregistré dans le cache + * \~english \brief Cache key + */ + std::string key; + /** + * \~french \brief Nom de la dalle dans laquelle lire la donnée + * \~english \brief Data slab to read + */ + std::string name; + /** + * \~french \brief Contexte de stockage de la dalle de donnée + * \~english \brief Data slab storage context + */ + Context* context; + /** + * \~french \brief Offsets des tuiles dans la dalle + * \~english \brief Tiles' offsets + */ + std::vector offsets; + /** + * \~french \brief Tailles des tuiles dans la dalle + * \~english \brief Tiles' sizes + */ + std::vector sizes; + + /** \~french + * \brief Constructeur + * \param[in] k clé d'enregistrement dans le cache + * \param[in] s nom de la dalle + * \param[in] c contexte de stockage de la dalle + * \param[in] tiles_number nombre de tuiles dans la dalles + * \param[in] os offsets bruts des tuiles + * \param[in] ss tailles brutes des tuiles + ** \~english + * \brief Constructor + * \param[in] k cache key + * \param[in] s data slab name + * \param[in] c data slab storage context + * \param[in] tiles_number tiles number + * \param[in] os raw tiles' offsets + * \param[in] ss raw tiles' sizes + */ + IndexElement(std::string k, Context* c, std::string n, int tiles_number, uint8_t* os, uint8_t* ss); +}; \ No newline at end of file diff --git a/include/rok4/utils/Level.h b/include/rok4/utils/Level.h index f7735902..f695597e 100644 --- a/include/rok4/utils/Level.h +++ b/include/rok4/utils/Level.h @@ -53,7 +53,6 @@ class Level; #include "rok4/utils/Configuration.h" #include "rok4/utils/Level.h" #include "rok4/utils/Table.h" -#include "rok4/utils/Cache.h" /** */ diff --git a/include/rok4/utils/ProjPool.h b/include/rok4/utils/ProjPool.h new file mode 100644 index 00000000..71a83385 --- /dev/null +++ b/include/rok4/utils/ProjPool.h @@ -0,0 +1,99 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +#pragma once + +#include +#include +#include + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un pool de contextes Proj + * \details Cette classe est prévue pour être utilisée sans instance + */ +class ProjPool { + +private: + + /** + * \~french \brief Annuaire des contextes Proj + * \details La clé est l'identifiant du thread + * \~english \brief Proj contexts book + * \details Key is the thread's ID + */ + static std::map pool; + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + ProjPool(); + +public: + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~ProjPool(); + + /** + * \~french \brief Retourne un contexte Proj propre au thread appelant + * \details Si il n'existe pas encore de contexte Proj pour ce tread, on le crée et on l'initialise + * \~english \brief Get the Proj context specific to the calling thread + * \details If Proj context doesn't exist for this thread, it is created and initialized + */ + static PJ_CONTEXT* get_proj_env(); + + /** + * \~french \brief Affiche le nombre de contextes proj dans l'annuaire + * \~english \brief Print the number of proj contexts in the book + */ + static void print_projs_count (); + + /** + * \~french \brief Nettoie tous les contextes proj dans l'annuaire et le vide + * \~english \brief Clean all proj objects in the book and empty it + */ + static void clean_projs (); +}; diff --git a/include/rok4/utils/Pyramid.h b/include/rok4/utils/Pyramid.h index 42149baa..ea05370f 100644 --- a/include/rok4/utils/Pyramid.h +++ b/include/rok4/utils/Pyramid.h @@ -49,7 +49,7 @@ class Pyramid; #include "rok4/style/Style.h" #include "rok4/enums/Interpolation.h" #include "rok4/utils/Configuration.h" -#include "rok4/utils/Cache.h" +#include "rok4/utils/TmsBook.h" #include "rok4/storage/Context.h" #define DEFAULT_NODATAVALUE 255 diff --git a/include/rok4/utils/StoragePool.h b/include/rok4/utils/StoragePool.h new file mode 100644 index 00000000..c3f6e04e --- /dev/null +++ b/include/rok4/utils/StoragePool.h @@ -0,0 +1,136 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +#pragma once + +#include "rok4/utils/StyleBook.h" +#include "rok4/storage/Context.h" + +#if CEPH_ENABLED + #include "storage/ceph/CephPoolContext.h" +#endif + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un pool de contextes de stockage + * \details Cette classe est prévue pour être utilisée sans instance + */ +class StoragePool { + +private: + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + StoragePool(); + + /** + * \~french \brief Annuaire de contextes + * \details La clé est une paire composée du type de stockage et du contenant du contexte + * \~english \brief Book of contexts + * \details Key is a pair composed of type of storage and the context's bucket + */ + static std::map,Context*> pool; + + +public: + + + /** + * \~french \brief Retourne une chaîne de caracère décrivant l'annuaire + * \~english \brief Return a string describing the pool + */ + static std::string to_string(); + + /** + * \~french + * \brief Récupère un contexte de stockage + * \details Si un contexte existe déjà pour ce nom de contenant, on ne crée pas de nouveau contexte et on retourne celui déjà existant. Le nouveau contexte n'est pas connecté. + * \param[in] type type de stockage pour lequel on veut créer un contexte + * \param[in] tray Nom du contenant pour lequel on veut créer un contexte + * \param[in] reference_context Contexte de stockage de référence + + * \brief Get a context storage + * \details If a context already exists for this tray's name, we don't create a new one and the existing is returned. New context is not connected. + * \param[in] type Storage Type for which context is created + * \param[in] tray Tray's name for which context is created + * \param[in] reference_context Reference storage context + + */ + static Context * get_context(ContextType::eContextType type,std::string tray, Context* reference_context = 0) ; + + + /** + * \~french \brief Retourne le nombre de contextes de stockage dans l'annuaire par type + * \param[out] file_count Nombre de contexte de stockage fichier + * \param[out] s3_count Nombre de contexte de stockage S3 + * \param[out] ceph_count Nombre de contexte de stockage Ceph + * \param[out] swift_count Nombre de contexte de stockage Swift + * \~english \brief Return the number of storage contexts in the book per type + * \param[out] file_count File storage context count + * \param[out] s3_count S3 storage context count + * \param[out] ceph_count Ceph storage context count + * \param[out] swift_count Swift storage context count + */ + static void get_storages_count (int& file_count, int& s3_count, int& ceph_count, int& swift_count); + + /** + * \~french \brief Obtient l'annuaire de contextes + * \details La clé est une paire composée du type de stockage et du contenant du contexte + * \~english \brief Get book of contexts + * \details Key is a pair composed of type of storage and the context's bucket + */ + static std::map,Context*> get_pool(); + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~StoragePool(); + + /** + * \~french \brief Nettoie tous les contextes de stockage dans l'annuaire et le vide + * \~english \brief Clean all storage context objects in the book and empty it + */ + static void clean_storages (); +}; \ No newline at end of file diff --git a/include/rok4/utils/StyleBook.h b/include/rok4/utils/StyleBook.h new file mode 100644 index 00000000..53e6c95a --- /dev/null +++ b/include/rok4/utils/StyleBook.h @@ -0,0 +1,164 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file StyleBook.h + ** \~french + * \brief Définition de la classe StyleBook + ** \~english + * \brief Define classe StyleBook + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "rok4/style/Style.h" +#include "rok4/utils/Utils.h" + +#define ROK4_STYLES_DIRECTORY "ROK4_STYLES_DIRECTORY" +#define ROK4_STYLES_NO_CACHE "ROK4_STYLES_NO_CACHE" + + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un annuaire de styles + * \details Cette classe est prévue pour être utilisée sans instance + */ +class StyleBook { + +private: + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + StyleBook(); + + /** + * \~french + * \brief Répertoire de stockage des styles + * \~english + * \brief TMS storage directory + */ + static std::string directory; + + /** + * \~french \brief Annuaire de styles + * \details La clé est l'identifiant du style + * \~english \brief Book of styles + * \details Key is a the style identifier + */ + static std::map book; + + /** + * \~french \brief Corbeille de styles à supprimer + * \~english \brief Styles trash to delete + */ + static std::vector trash; + + /** + * \~french \brief Exclusion mutuelle + * \details Pour éviter les modifications concurrentes du cache de styles + * \~english \brief Mutual exclusion + * \details To avoid concurrent styles cache updates + */ + static std::mutex mtx; + +public: + + + /** + * \~french \brief Vide l'annuaire et met le contenu à la corbeille + * \~english \brief Empty book and put content into trash + */ + static void send_to_trash (); + + /** + * \~french \brief Vide la corbeille + * \~english \brief Empty trash + */ + static void empty_trash (); + + + /** + * \~french \brief Renseigne le répertoire des style + * \~english \brief Set styles directory + */ + static void set_directory (std::string d); + + /** + * \~french \brief Retourne l'ensemble de l'annuaire + * \~english \brief Return the book + */ + static std::map get_book (); + + /** + * \~french + * \brief Retourne le style d'après son identifiant + * \details Si le style demandé n'est pas encore dans l'annuaire, ou que l'on ne veut pas de cache, il est recherché dans le répertoire connu et chargé + * \param[in] id Identifiant du style voulu + + * \brief Return the style according to its identifier + * \details If style is still not in the book, or cache is disabled, it is searched in the known directory and loaded + * \param[in] id Wanted style identifier + */ + static Style* get_style(std::string id); + + /** + * \~french \brief Retourne le nombre de styles dans l'annuaire + * \~english \brief Return the number of styles in the book + */ + static int get_styles_count (); + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~StyleBook(); + +}; \ No newline at end of file diff --git a/include/rok4/utils/TileMatrixSet.h b/include/rok4/utils/TileMatrixSet.h index fd6ea72b..18f1616c 100644 --- a/include/rok4/utils/TileMatrixSet.h +++ b/include/rok4/utils/TileMatrixSet.h @@ -52,9 +52,8 @@ #include #include "rok4/utils/TileMatrix.h" -#include "rok4/utils/CRS.h" -#include "rok4/utils/Keyword.h" -#include "rok4/utils/Configuration.h" +#include "rok4/utils/CrsBook.h" +#include "rok4/utils/StoragePool.h" typedef std::function, std::pair)> ComparatorTileMatrix; @@ -96,6 +95,7 @@ typedef std::function, std::pair + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file TmsBook.h + ** \~french + * \brief Définition de la classe TmsBook + ** \~english + * \brief Define classe TmsBook + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include "rok4/utils/TileMatrixSet.h" + +#define ROK4_TMS_DIRECTORY "ROK4_TMS_DIRECTORY" +#define ROK4_TMS_NO_CACHE "ROK4_TMS_NO_CACHE" + +/** + * \author Institut national de l'information géographique et forestière + * \~french + * \brief Création d'un annuaire de Tile Matrix Sets + * \details Cette classe est prévue pour être utilisée sans instance + */ +class TmsBook { + +private: + + /** + * \~french + * \brief Constructeur + * \~english + * \brief Constructeur + */ + TmsBook(); + + /** + * \~french + * \brief Répertoire de stockage des TMS + * \~english + * \brief TMS storage directory + */ + static std::string directory; + + /** + * \~french \brief Annuaire de TMS + * \details La clé est l'identifiant du TMS + * \~english \brief Book of TMS + * \details Key is a the TMS identifier + */ + static std::map book; + + /** + * \~french \brief Corbeille de TMS à supprimer + * \~english \brief TMS trash to delete + */ + static std::vector trash; + + /** + * \~french \brief Exclusion mutuelle + * \details Pour éviter les modifications concurrentes du cache de TMS + * \~english \brief Mutual exclusion + * \details To avoid concurrent TMS cache updates + */ + static std::mutex mtx; + +public: + + + /** + * \~french \brief Vide l'annuaire et met le contenu à la corbeille + * \~english \brief Empty book and put content into trash + */ + static void send_to_trash (); + + /** + * \~french \brief Vide la corbeille + * \~english \brief Empty trash + */ + static void empty_trash (); + + + /** + * \~french \brief Renseigne le répertoire des TMS + * \~english \brief Set TMS directory + */ + static void set_directory (std::string d); + + /** + * \~french \brief Retourne l'ensemble de l'annuaire + * \~english \brief Return the book + */ + static std::map get_book (); + + /** + * \~french + * \brief Retourne le TMS d'après son identifiant + * \details Si le TMS demandé n'est pas encore dans l'annuaire, ou que l'on ne veut pas de cache, il est recherché dans le répertoire connu et chargé + * \param[in] id Identifiant du TMS voulu + + * \brief Return the TMS according to its identifier + * \details If TMS is still not in the book, or cache is disabled, it is searched in the known directory and loaded + * \param[in] id Wanted TMS identifier + */ + static TileMatrixSet* get_tms(std::string id); + + /** + * \~french \brief Retourne le nombre de TMS dans l'annuaire + * \~english \brief Return the number of TMS in the book + */ + static int get_tms_count (); + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + ~TmsBook(); + +}; \ No newline at end of file diff --git a/src/datasource/StoreDataSource.cpp b/src/datasource/StoreDataSource.cpp index d60e7fa2..b9c9f19a 100644 --- a/src/datasource/StoreDataSource.cpp +++ b/src/datasource/StoreDataSource.cpp @@ -52,7 +52,6 @@ #include #include #include -#include "utils/Cache.h" #include "enums/Format.h" #include "storage/Context.h" diff --git a/src/datasource/StoreDataSource.h b/src/datasource/StoreDataSource.h index 79e916e0..0421fc9e 100644 --- a/src/datasource/StoreDataSource.h +++ b/src/datasource/StoreDataSource.h @@ -54,6 +54,8 @@ #include "datasource/DataSource.h" #include "storage/Context.h" +#include "rok4/utils/StoragePool.h" +#include "rok4/utils/IndexCache.h" /** * \author Institut national de l'information géographique et forestière diff --git a/src/image/file/Rok4Image.cpp b/src/image/file/Rok4Image.cpp index 0bae3420..5abd7202 100644 --- a/src/image/file/Rok4Image.cpp +++ b/src/image/file/Rok4Image.cpp @@ -56,7 +56,6 @@ #include #include "utils/Utils.h" #include "datasource/DataSource.h" -#include "utils/Cache.h" #include #include #include diff --git a/src/processors/Grid.cpp b/src/processors/Grid.cpp index 0a6d8b34..bb99d8fa 100644 --- a/src/processors/Grid.cpp +++ b/src/processors/Grid.cpp @@ -48,8 +48,6 @@ #include "processors/Grid.h" #include -#include "utils/Cache.h" - #include #include diff --git a/src/storage/S3Context.cpp b/src/storage/S3Context.cpp index c956d4d4..4261c985 100644 --- a/src/storage/S3Context.cpp +++ b/src/storage/S3Context.cpp @@ -49,16 +49,10 @@ #include "storage/S3Context.h" -#include #include -#include #include #include -#include "S3Context.h" -#include "utils/Cache.h" -#include "utils/LibcurlStruct.h" - std::vector S3Context::env_hosts; std::vector S3Context::env_keys; std::vector S3Context::env_secret_keys; diff --git a/src/storage/S3Context.h b/src/storage/S3Context.h index e2827e07..e49bc152 100644 --- a/src/storage/S3Context.h +++ b/src/storage/S3Context.h @@ -53,6 +53,7 @@ #include #include "storage/Context.h" #include "utils/LibcurlStruct.h" +#include "utils/CurlPool.h" #define ROK4_S3_URL "ROK4_S3_URL" #define ROK4_S3_KEY "ROK4_S3_KEY" diff --git a/src/storage/SwiftContext.cpp b/src/storage/SwiftContext.cpp index c50f9ac8..8c557d41 100644 --- a/src/storage/SwiftContext.cpp +++ b/src/storage/SwiftContext.cpp @@ -48,10 +48,7 @@ */ #include "storage/SwiftContext.h" -#include "utils/LibcurlStruct.h" -#include #include -#include "utils/Cache.h" #include SwiftContext::SwiftContext (std::string cont) : Context(), ssl_no_verify(false), keystone_auth(false), container_name(cont), use_token_from_file(true) { diff --git a/src/storage/SwiftContext.h b/src/storage/SwiftContext.h index e3b02e96..ffb30706 100644 --- a/src/storage/SwiftContext.h +++ b/src/storage/SwiftContext.h @@ -54,6 +54,7 @@ #include "storage/Context.h" #include "utils/LibcurlStruct.h" #include +#include "utils/CurlPool.h" #define ROK4_SWIFT_AUTHURL "ROK4_SWIFT_AUTHURL" diff --git a/src/style/Style.cpp b/src/style/Style.cpp index fd2c65c2..4962dc81 100644 --- a/src/style/Style.cpp +++ b/src/style/Style.cpp @@ -50,7 +50,6 @@ #include #include #include -#include "utils/Cache.h" #include "storage/Context.h" diff --git a/src/utils/BoundingBox.cpp b/src/utils/BoundingBox.cpp index ffd68382..bc63d8a4 100644 --- a/src/utils/BoundingBox.cpp +++ b/src/utils/BoundingBox.cpp @@ -45,7 +45,6 @@ #include "utils/BoundingBox.h" #include "utils/CRS.h" -#include "utils/Cache.h" template bool BoundingBox::is_in_crs_area(CRS* c) { diff --git a/src/utils/CRS.cpp b/src/utils/CRS.cpp index 187acf0f..e4268e1a 100644 --- a/src/utils/CRS.cpp +++ b/src/utils/CRS.cpp @@ -43,12 +43,7 @@ * \brief implement the reference systems handler */ -#include -#include - #include "utils/CRS.h" -#include "utils/Cache.h" -#include "utils/Utils.h" CRS CRS::epsg4326; diff --git a/src/utils/CrsBook.cpp b/src/utils/CrsBook.cpp new file mode 100644 index 00000000..00e54047 --- /dev/null +++ b/src/utils/CrsBook.cpp @@ -0,0 +1,83 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file CrsBook.cpp + ** \~french + * \brief Implémentation de la classe CrsBook + ** \~english + * \brief Implements classe CrsBook + */ + + +#include "rok4/utils/CrsBook.h" + +CrsBook::CrsBook(){ + +} + + +CRS* CrsBook::get_crs(std::string id) { + id = to_upper_case(id); + std::map::iterator it = book.find ( id ); + if ( it != book.end() ) { + return it->second; + } + mtx.lock(); + CRS* crs = new CRS(id); + // Le CRS est potentiellement non défini (si il n'est pas valide), on le mémorise pour ne pas réessayer la prochaine fois + book.emplace(id, crs); + mtx.unlock(); + return crs; +} + +void CrsBook::clean_crss () { + mtx.lock(); + std::map::iterator it; + for (it = book.begin(); it != book.end(); ++it) { + delete it->second; + } + book.clear(); + mtx.unlock(); +} + +CrsBook::~CrsBook() { + +} + +std::map CrsBook::book; +std::mutex CrsBook::mtx; diff --git a/src/utils/CurlPool.cpp b/src/utils/CurlPool.cpp new file mode 100644 index 00000000..246a3282 --- /dev/null +++ b/src/utils/CurlPool.cpp @@ -0,0 +1,78 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + + /** + * \file CurlPool.cpp + ** \~french + * \brief Implémentation de la classe CurlPool + ** \~english + * \brief Implements classe CurlPool + */ + +#include "utils/CurlPool.h" + +CurlPool::~CurlPool(){ + +} + +CURL *CurlPool::get_curl_env() { + pthread_t i = pthread_self(); + + std::map::iterator it = pool.find ( i ); + if ( it == pool.end() ) { + CURL* c = curl_easy_init(); + pool.insert ( std::pair(i,c) ); + return c; + } else { + curl_easy_reset(it->second); + return it->second; + } +} + +void CurlPool::print_curls_count() { + BOOST_LOG_TRIVIAL(info) << "Nombre de contextes curl : " << pool.size(); +} + +void CurlPool::clean_curls() { + std::map::iterator it; + for (it = pool.begin(); it != pool.end(); ++it) { + curl_easy_cleanup(it->second); + } + pool.clear(); +} + +std::map CurlPool::pool; diff --git a/src/utils/IndexCache.cpp b/src/utils/IndexCache.cpp new file mode 100644 index 00000000..99160300 --- /dev/null +++ b/src/utils/IndexCache.cpp @@ -0,0 +1,154 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file IndexCache.cpp + ** \~french + * \brief Implémentation de la classe IndexCache + ** \~english + * \brief Implements classe IndexCache + */ + +#include "rok4/utils/IndexCache.h" + +IndexCache::IndexCache() { + +} + +IndexCache::~IndexCache() { + +} + +void IndexCache::setCacheSize(int s) { + size = s; +} + +void IndexCache::set_validity(int v) { + validity = v; +} + +void IndexCache::add_slab_infos(std::string origin_slab_name, Context *data_context, std::string data_slab_name, int tiles_number, uint8_t *offsets, uint8_t *sizes) { + // On utilise le nom original de la dalle (celle à lire a priori) comme clé dans la map + // Potentiellement ce nom est différent de la vraie dalle contenant la donnée (dans le cas d'une dalle symbolique) + // mais c'est via cette dalle symbolique que la donnée est a priori requêtée + // donc c'est ce nom qu'on utilisera pour l'interrogation du cache + + mtx.lock(); + + IndexElement *elem = new IndexElement(origin_slab_name, data_context, data_slab_name, tiles_number, offsets, sizes); + + // L'information n'est a priori pas dans le cache car + // Soit elle était dans le cache et valide, alors on aurait utilisé ce cache et on n'aurait pas fait appel à cet ajout + // Soit elle était dans le cache mais obsolète, alors on l'aurait déjà supprimé du cache + + if (cache.size() == size) + { + // On récupère le dernier élément du cache + IndexElement *last = cache.back(); + // On le vire du cache + cache.pop_back(); + // On le déréférence de la map d'accès + map.erase(last->key); + delete last; + } + + // update reference + cache.push_front(elem); + map[origin_slab_name] = cache.begin(); + + mtx.unlock(); +} + +bool IndexCache::get_slab_infos(std::string key, int tile_number, Context **data_context, std::string *data_slab_name, uint32_t *offset, uint32_t *size) { + std::unordered_map::iterator>::iterator it = map.find(key); + if (it == map.end()) + { + return false; + } + else + { + // Gestion de la péremption du cache (une heure max) + std::time_t now = std::time(NULL); + if (now - (*(it->second))->date > validity) + { + mtx.lock(); + + // on le cherche à nouveau pour vérifier qu'il n'a pas déjà été supprimé par un thread concurrent + it = map.find(key); + + if (it != map.end()) + { + delete *(it->second); + cache.erase(it->second); + map.erase(it); + } + + mtx.unlock(); + + return false; + } + + *data_slab_name = (*(it->second))->name; + *data_context = (*(it->second))->context; + *offset = (*(it->second))->offsets.at(tile_number); + *size = (*(it->second))->sizes.at(tile_number); + + // On fait le choix de ne pas remettre en tête du cache cet élément, même s'il vient d'être accéder + // C'est parce qu'en plus d'avoir une taille limite, les élément cachés ont une date de péromption + // Il serait donc dommage de remettre en avant (donc plus loin d'une suppression par taille de cache atteinte) + // un élément qui va de toute manière finir par être obsolète. + // C'est une différence avec une cache LRU classique + + return true; + } +} + +void IndexCache::clean_indexes() { + mtx.lock(); + std::list::iterator it; + for (it = cache.begin(); it != cache.end(); ++it) { + delete *it; + } + cache.clear(); + mtx.unlock(); +} + +std::list IndexCache::cache; +std::unordered_map::iterator> IndexCache::map; +int IndexCache::size = 100; +int IndexCache::validity = 300; +std::mutex IndexCache::mtx; diff --git a/src/utils/IndexElement.cpp b/src/utils/IndexElement.cpp new file mode 100644 index 00000000..ab09b029 --- /dev/null +++ b/src/utils/IndexElement.cpp @@ -0,0 +1,57 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file IndexElement.cpp + ** \~french + * \brief Implémentation de la classe IndexElement + ** \~english + * \brief Implements classe IndexElement + */ + +#include "rok4/utils/IndexElement.h" + +IndexElement::IndexElement(std::string k, Context *c, std::string n, int tiles_number, uint8_t *os, uint8_t *ss) { + key = k; + context = c; + name = n; + date = std::time(NULL); + for (int i = 0; i < tiles_number; i++) { + offsets.push_back(*((uint32_t*) (os + i*4))); + sizes.push_back(*((uint32_t*) (ss + i*4))); + } +} \ No newline at end of file diff --git a/src/utils/ProjPool.cpp b/src/utils/ProjPool.cpp new file mode 100644 index 00000000..b90e9962 --- /dev/null +++ b/src/utils/ProjPool.cpp @@ -0,0 +1,82 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file ProjPool.cpp + ** \~french + * \brief Implémentation de la classe ProjPool + ** \~english + * \brief Implements classe ProjPool + */ + + +#include "rok4/utils/ProjPool.h" + +ProjPool::ProjPool(){ +} + +ProjPool::~ProjPool(){ +} + +PJ_CONTEXT *ProjPool::get_proj_env() { + pthread_t i = pthread_self(); + + std::map::iterator it = pool.find ( i ); + if ( it == pool.end() ) { + PJ_CONTEXT* pjc = proj_context_create(); + proj_log_level(pjc, PJ_LOG_NONE); + pool.insert ( std::pair(i,pjc) ); + return pjc; + } else { + return it->second; + } +} + +void ProjPool::print_projs_count() { + BOOST_LOG_TRIVIAL(info) << "Nombre de contextes proj : " << pool.size() ; +} + +void ProjPool::clean_projs() { + std::map::iterator it; + for (it = pool.begin(); it != pool.end(); ++it) { + proj_context_destroy(it->second); + } + pool.clear(); +} + +std::map ProjPool::pool; + diff --git a/src/utils/Pyramid.cpp b/src/utils/Pyramid.cpp index eafa2ed2..b032449e 100644 --- a/src/utils/Pyramid.cpp +++ b/src/utils/Pyramid.cpp @@ -48,7 +48,6 @@ #include "image/ExtendedCompoundImage.h" #include "enums/Format.h" #include "utils/Level.h" -#include "utils/Cache.h" #include #include "image/EmptyImage.h" diff --git a/src/utils/Cache.cpp b/src/utils/StoragePool.cpp similarity index 69% rename from src/utils/Cache.cpp rename to src/utils/StoragePool.cpp index fb4fdf8f..0b6219d3 100644 --- a/src/utils/Cache.cpp +++ b/src/utils/StoragePool.cpp @@ -35,46 +35,86 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -/** - * \file Cache.cpp + /** + * \file StoragePool.cpp ** \~french - * \brief Implémentation des classes IndexCache, CurlPool, StoragePool et ProjPool + * \brief Implémentation de la classe StoragePool ** \~english - * \brief Implements classes IndexCache, CurlPool, StoragePool and ProjPool + * \brief Implements classe StoragePool */ -#include "utils/Cache.h" +#include "utils/StoragePool.h" #include "storage/FileContext.h" #include "storage/SwiftContext.h" #include "storage/S3Context.h" -#if CEPH_ENABLED - #include "storage/ceph/CephPoolContext.h" -#endif -std::map CurlPool::pool; +StoragePool::StoragePool(){ + +} + +std::string StoragePool::to_string() { + std::ostringstream oss; + oss.setf ( std::ios::fixed,std::ios::floatfield ); + oss << "------ Context pool -------" << std::endl; + oss << "\t- context number = " << pool.size() << std::endl; + + std::map, Context*>::iterator it = pool.begin(); + while (it != pool.end()) { + std::pair key = it->first; + oss << "\t\t- pot = " << key.first << "/" << key.second << std::endl; + oss << it->second->to_string() << std::endl; + it++; + } + + return oss.str() ; + } + + -std::map ProjPool::pool; +void StoragePool::get_storages_count (int& file_count, int& s3_count, int& ceph_count, int& swift_count) { + file_count = 0; + s3_count = 0; + ceph_count = 0; + swift_count = 0; + std::map, Context*>::iterator it = pool.begin(); + while (it != pool.end()) { + std::pair key = it->first; + switch(key.first) { + #if CEPH_ENABLED + case ContextType::CEPHCONTEXT: + ceph_count++; + break; + #endif + case ContextType::SWIFTCONTEXT: + swift_count++; + break; + case ContextType::S3CONTEXT: + s3_count++; + break; + case ContextType::FILECONTEXT: + file_count++; + break; + } + it++; + } + } -std::map,Context*> StoragePool::pool; +std::map,Context*> StoragePool::get_pool() { + return pool; + } -std::list IndexCache::cache; -std::unordered_map::iterator> IndexCache::map; -int IndexCache::size = 100; -int IndexCache::validity = 300; -std::mutex IndexCache::mtx; +StoragePool::~StoragePool(){ -std::map TmsBook::book; -std::vector TmsBook::trash; -std::string TmsBook::directory = ""; -std::mutex TmsBook::mtx; +} -std::map StyleBook::book; -std::vector StyleBook::trash; -std::string StyleBook::directory = ""; -std::mutex StyleBook::mtx; -std::map CrsBook::book; -std::mutex CrsBook::mtx; +void StoragePool::clean_storages () { + std::map,Context*>::iterator it; + for (it=pool.begin(); it!=pool.end(); ++it) { + delete it->second; + it->second = NULL; + } +} Context * StoragePool::get_context(ContextType::eContextType type, std::string tray, Context* reference_context) { @@ -153,4 +193,6 @@ Context * StoragePool::get_context(ContextType::eContextType type, std::string t return ctx; } -} \ No newline at end of file +} + +std::map,Context*> StoragePool::pool; \ No newline at end of file diff --git a/src/utils/StyleBook.cpp b/src/utils/StyleBook.cpp new file mode 100644 index 00000000..640e9a7c --- /dev/null +++ b/src/utils/StyleBook.cpp @@ -0,0 +1,144 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file StyleBook.cpp + ** \~french + * \brief Implémentation de la classe StyleBook + ** \~english + * \brief Implements classe StyleBook + */ + + +#include "rok4/utils/StyleBook.h" + +StyleBook::StyleBook(){ + +} + +void StyleBook::send_to_trash() { + mtx.lock(); + std::map::iterator it; + for (it = book.begin(); it != book.end(); ++it) { + trash.push_back(it->second); + } + book.clear(); + mtx.unlock(); +} + +void StyleBook::empty_trash() { + mtx.lock(); + for (int i = 0; i < trash.size(); i++) { + delete trash.at(i); + } + trash.clear(); + mtx.unlock(); +} + +void StyleBook::set_directory(std::string d) { + // Suppression du slash final + if (d.compare ( d.size()-1,1,"/" ) == 0) { + d.pop_back(); + } + directory = d; +} + +std::map StyleBook::get_book() { + return book; +} + +Style *StyleBook::get_style(std::string id) { + std::map::iterator it = book.find ( id ); + if ( it != book.end() ) { + return it->second; + } + std::string d; + if (directory.empty()) { + char* e = getenv (ROK4_STYLES_DIRECTORY); + if (e == NULL) { + d.assign("/usr/share/rok4/styles"); + } else { + d.assign(e); + } + } else { + d = directory; + } + std::string style_path = d + "/" + id; + mtx.lock(); + // Si on fait du cache de style, on revérifie que ce style n'a pas déjà été ajouté par un thread concurrent entre temps + if(getenv (ROK4_STYLES_NO_CACHE) == NULL) { + if ( it != book.end() ) { + // On a effectivement depuis déjà enregistré ce style + return it->second; + } + } + Style* style = new Style(style_path); + if ( ! style->is_ok() ) { + BOOST_LOG_TRIVIAL(error) << style->get_error_message(); + delete style; + mtx.unlock(); + return NULL; + } + if ( contain_chars(style->get_identifier(), "<>") ) { + BOOST_LOG_TRIVIAL(error) << "Style identifier contains forbidden chars" ; + delete style; + mtx.unlock(); + return NULL; + } + if(getenv (ROK4_STYLES_NO_CACHE) == NULL) { + // On veut utiliser le cache, on met donc ce nouveau style dans l'annuaire pour le trouver la porchaine fois + book.insert ( std::pair(id, style) ); + } else { + // On met le style directement dans la corbeille, pour que le nettoyage se fasse bien + trash.push_back(style); + } + mtx.unlock(); + return style; +} + +int StyleBook::get_styles_count() { + return book.size(); +} + +StyleBook::~StyleBook() { + +} + +std::map StyleBook::book; +std::vector StyleBook::trash; +std::string StyleBook::directory = ""; +std::mutex StyleBook::mtx; \ No newline at end of file diff --git a/src/utils/TileMatrixSet.cpp b/src/utils/TileMatrixSet.cpp index 0e311c4c..78ef2c93 100644 --- a/src/utils/TileMatrixSet.cpp +++ b/src/utils/TileMatrixSet.cpp @@ -45,9 +45,6 @@ #include "utils/TileMatrixSet.h" -#include "utils/Utils.h" -#include "utils/Cache.h" -#include "storage/Context.h" #include #include diff --git a/src/utils/TmsBook.cpp b/src/utils/TmsBook.cpp new file mode 100644 index 00000000..8f45ba44 --- /dev/null +++ b/src/utils/TmsBook.cpp @@ -0,0 +1,139 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file TmsBook.cpp + ** \~french + * \brief Implémentation de la classe TmsBook + ** \~english + * \brief Implements classe TmsBook + */ + + +#include "rok4/utils/TmsBook.h" + +TmsBook::TmsBook(){ + +} + +void TmsBook::send_to_trash() { + mtx.lock(); + std::map::iterator it; + for (it = book.begin(); it != book.end(); ++it) { + trash.push_back(it->second); + } + book.clear(); + mtx.unlock(); +} + +void TmsBook::empty_trash() { + mtx.lock(); + for (int i = 0; i < trash.size(); i++) { + delete trash.at(i); + } + trash.clear(); + mtx.unlock(); +} + +void TmsBook::set_directory(std::string d) { + // Suppression du slash final + if (d.compare ( d.size()-1,1,"/" ) == 0) { + d.pop_back(); + } + directory = d; +} + +std::map TmsBook::get_book() { + return book; +} + +TileMatrixSet *TmsBook::get_tms(std::string id) { + std::map::iterator it = book.find ( id ); + if ( it != book.end() ) { + return it->second; + } + std::string d; + if (directory.empty()) { + char* e = getenv (ROK4_TMS_DIRECTORY); + if (e == NULL) { + d.assign("/usr/share/rok4/tilematrixsets"); + } else { + d.assign(e); + } + } else { + d = directory; + } + std::string tms_path = d + "/" + id; + mtx.lock(); + // Si on fait du cache de TMS, on revérifie que ce TMS n'a pas déjà été ajouté par un thread concurrent entre temps + if(getenv (ROK4_TMS_NO_CACHE) == NULL) { + if ( it != book.end() ) { + // On a effectivement depuis déjà enregistré ce TMS + return it->second; + } + } + TileMatrixSet* tms = new TileMatrixSet(tms_path); + if ( ! tms->is_ok() ) { + BOOST_LOG_TRIVIAL(error) << tms->get_error_message(); + delete tms; + mtx.unlock(); + return NULL; + } + if(getenv (ROK4_TMS_NO_CACHE) == NULL) { + // On veut utiliser le cache, on met donc ce nouveau TMS dans l'annuaire pour le trouver la prochaine fois + book.insert ( std::pair(id, tms) ); + } else { + // On met le TMS directement dans la corbeille, pour que le nettoyage se fasse bien + trash.push_back(tms); + } + + mtx.unlock(); + return tms; +} + +int TmsBook::get_tms_count() { + return book.size(); +} + +TmsBook::~TmsBook(){ + +} + +std::map TmsBook::book; +std::vector TmsBook::trash; +std::string TmsBook::directory = ""; +std::mutex TmsBook::mtx; \ No newline at end of file