00001
00002
00003
00004
00005
00006
00007 #pragma once
00008
00009 #ifdef WITH_THREADS
00010 #include <boost/thread/shared_mutex.hpp>
00011 #include <boost/thread/locks.hpp>
00012 #include <boost/foreach.hpp>
00013 #endif
00014
00015
00016
00017 #include "xmlrpc-c.h"
00018
00019 #include <map>
00020 #include <boost/shared_ptr.hpp>
00021 #include "TypeDef.h"
00022 #include "Util.h"
00023
00024 namespace Moses
00025 {
00026 class ContextScope
00027 {
00028 protected:
00029 typedef std::map<void const*, boost::shared_ptr<void> > scratchpad_t;
00030 typedef scratchpad_t::iterator iter_t;
00031 typedef scratchpad_t::value_type entry_t;
00032 typedef scratchpad_t::const_iterator const_iter_t;
00033 scratchpad_t m_scratchpad;
00034 #ifdef WITH_THREADS
00035 mutable boost::shared_mutex m_lock;
00036 #endif
00037 SPTR<std::map<std::string,float> const> m_context_weights;
00038 public:
00039 typedef boost::shared_ptr<ContextScope> ptr;
00040 template<typename T>
00041 boost::shared_ptr<void> const&
00042 set(void const* const key, boost::shared_ptr<T> const& val) {
00043 #ifdef WITH_THREADS
00044 boost::unique_lock<boost::shared_mutex> lock(m_lock);
00045 #endif
00046 return (m_scratchpad[key] = val);
00047 }
00048
00049 template<typename T>
00050 boost::shared_ptr<T> const
00051 get(void const* key, bool CreateNewIfNecessary=false) {
00052 #ifdef WITH_THREADS
00053 using boost::shared_mutex;
00054 using boost::upgrade_lock;
00055
00056 upgrade_lock<shared_mutex> lock(m_lock);
00057 #endif
00058 iter_t m = m_scratchpad.find(key);
00059 boost::shared_ptr< T > ret;
00060 if (m != m_scratchpad.end()) {
00061 if (m->second == NULL && CreateNewIfNecessary) {
00062 #ifdef WITH_THREADS
00063 boost::upgrade_to_unique_lock<shared_mutex> xlock(lock);
00064 #endif
00065 m->second.reset(new T);
00066 }
00067 ret = boost::static_pointer_cast< T >(m->second);
00068 return ret;
00069 }
00070 if (!CreateNewIfNecessary) return ret;
00071 #ifdef WITH_THREADS
00072 boost::upgrade_to_unique_lock<shared_mutex> xlock(lock);
00073 #endif
00074 ret.reset(new T);
00075 m_scratchpad[key] = ret;
00076 return ret;
00077 }
00078
00079 ContextScope() { }
00080
00081 ContextScope(ContextScope const& other) {
00082 #ifdef WITH_THREADS
00083 boost::unique_lock<boost::shared_mutex> lock1(this->m_lock);
00084 boost::unique_lock<boost::shared_mutex> lock2(other.m_lock);
00085 #endif
00086 m_scratchpad = other.m_scratchpad;
00087 }
00088
00089 SPTR<std::map<std::string,float> const>
00090 GetContextWeights() {
00091 return m_context_weights;
00092 }
00093
00094 bool
00095 SetContextWeights(std::string const& spec) {
00096 if (m_context_weights) return false;
00097 boost::unique_lock<boost::shared_mutex> lock(m_lock);
00098 SPTR<std::map<std::string,float> > M(new std::map<std::string, float>);
00099
00100
00101
00102 std::vector<std::string> tokens = Tokenize(spec,":");
00103 for (std::vector<std::string>::iterator it = tokens.begin();
00104 it != tokens.end(); it++) {
00105 std::vector<std::string> key_and_value = Tokenize(*it, ",");
00106 (*M)[key_and_value[0]] = atof(key_and_value[1].c_str());
00107 }
00108 m_context_weights = M;
00109 return true;
00110 }
00111
00112 bool
00113 SetContextWeights(SPTR<std::map<std::string,float> const> const& w) {
00114 if (m_context_weights) return false;
00115 #ifdef WITH_THREADS
00116 boost::unique_lock<boost::shared_mutex> lock(m_lock);
00117 #endif
00118 m_context_weights = w;
00119 return true;
00120 }
00121
00122 };
00123
00124 };