aboutsummaryrefslogtreecommitdiffstats
path: root/src/algo_factory/algo_cache.h
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-11-11 18:03:44 +0000
committerlloyd <[email protected]>2008-11-11 18:03:44 +0000
commit6a1e19928007c0047518e8e15b92bba116bf7a58 (patch)
tree70ce4ccb0f859884dac49895ebcff3e1d00b6b2e /src/algo_factory/algo_cache.h
parenta26685bf9feee9b9457bd1313b3943701aa37367 (diff)
Add a new cache at the level of Algorithm_Factory. Intent is to replace
the caches included in the Engines, allowing faster search/query along and making the Engine implementations mostly or entirely stateless, also removing the need for a two-phase initialization there. Stil buggy + incomplete.
Diffstat (limited to 'src/algo_factory/algo_cache.h')
-rw-r--r--src/algo_factory/algo_cache.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h
new file mode 100644
index 000000000..ab6778d14
--- /dev/null
+++ b/src/algo_factory/algo_cache.h
@@ -0,0 +1,111 @@
+/**
+* An algorithm cache (used by Algorithm_Factory)
+*/
+
+#ifndef BOTAN_ALGORITHM_CACHE_TEMPLATE_H__
+#define BOTAN_ALGORITHM_CACHE_TEMPLATE_H__
+
+#include <botan/scan_name.h>
+#include <botan/mutex.h>
+#include <stdexcept>
+#include <map>
+#include <string>
+
+namespace Botan {
+
+template<typename T>
+class Algorithm_Cache
+ {
+ public:
+ const T* get(const SCAN_Name& request);
+ void add(T* algo, const std::string& provider);
+
+ Algorithm_Cache(Mutex* m) : mutex(m) {}
+ ~Algorithm_Cache();
+ private:
+ Mutex* mutex;
+ std::map<std::string, std::map<std::string, T*> > algorithms;
+ typedef typename std::map<std::string, std::map<std::string, T*> >::iterator algorithms_iterator;
+ typedef typename std::map<std::string, T*>::iterator provider_iterator;
+ };
+
+/**
+* Look for an algorithm implementation in the cache
+*/
+template<typename T>
+const T* Algorithm_Cache<T>::get(const SCAN_Name& request)
+ {
+ Mutex_Holder lock(mutex);
+
+ algorithms_iterator algo = algorithms.find(request.as_string());
+
+ if(algo == algorithms.end())
+ return 0;
+
+ const std::string requested_provider = request.providers_string();
+
+ if(requested_provider != "")
+ {
+ provider_iterator provider = algo->second.find(requested_provider);
+
+ if(provider != algo->second.end())
+ return provider->second;
+ }
+ else // no specific provider requested: pick one
+ {
+ provider_iterator provider = algo->second.begin();
+
+ while(provider != algo->second.end())
+ ++provider;
+
+ provider = algo->second.begin();
+ // @fixme: Just picks the lexicographically first one
+ if(provider != algo->second.end())
+ return provider->second;
+ }
+
+ return 0; // cache miss
+ }
+
+/**
+* Add an implementation to the cache
+*/
+template<typename T>
+void Algorithm_Cache<T>::add(T* algo, const std::string& provider)
+ {
+ if(!algo)
+ return;
+
+ Mutex_Holder lock(mutex);
+
+ delete algorithms[algo->name()][provider];
+ algorithms[algo->name()][provider] = algo;
+ }
+
+/**
+* Algorithm_Cache<T> Destructor
+*/
+template<typename T>
+Algorithm_Cache<T>::~Algorithm_Cache()
+ {
+ algorithms_iterator algo = algorithms.begin();
+
+ while(algo != algorithms.end())
+ {
+ provider_iterator provider = algo->second.begin();
+
+ while(provider != algo->second.end())
+ {
+ delete provider->second;
+ ++provider;
+ }
+
+ ++algo;
+ }
+
+ delete mutex;
+ }
+
+}
+
+#endif