00001 #pragma once
00002
00003 #include <string>
00004 #include <cstdlib>
00005 #include <vector>
00006 #include <map>
00007
00008 #include <boost/thread/tss.hpp>
00009 #include <boost/shared_ptr.hpp>
00010
00011 #include "moses/FF/FeatureFunction.h"
00012
00013 namespace Moses
00014 {
00015
00016 template <class Value>
00017 struct DefaultFactory {
00018 typedef boost::shared_ptr<Value> ValuePtr;
00019
00020 ValuePtr operator()() {
00021 return ValuePtr(new Value());
00022 }
00023 };
00024
00025 template<class Value, class Factory = DefaultFactory<Value> >
00026 class ThreadLocalByFeatureStorage
00027 {
00028 public:
00029 typedef boost::shared_ptr<Value> ValuePtr;
00030 typedef std::map<std::string, ValuePtr> NameValueMap;
00031 typedef boost::thread_specific_ptr<NameValueMap> TSNameValueMap;
00032
00033 ThreadLocalByFeatureStorage(FeatureFunction* ff,
00034 Factory factory = Factory())
00035 : m_ff(ff), m_factory(factory) {}
00036
00037 virtual ~ThreadLocalByFeatureStorage() {}
00038
00039 virtual ValuePtr GetStored() {
00040 if(!m_nameMap.get())
00041 m_nameMap.reset(new NameValueMap());
00042
00043 typename NameValueMap::iterator it
00044 = m_nameMap->find(m_ff->GetScoreProducerDescription());
00045
00046 if(it == m_nameMap->end()) {
00047 std::pair<typename NameValueMap::iterator, bool> ret;
00048 ret = m_nameMap->insert(
00049 std::make_pair(m_ff->GetScoreProducerDescription(), m_factory()));
00050
00051 return ret.first->second;
00052 } else {
00053 return it->second;
00054 }
00055 }
00056
00057 virtual const ValuePtr GetStored() const {
00058 UTIL_THROW_IF2(!m_nameMap.get(),
00059 "No thread local storage has been created for: "
00060 << m_ff->GetScoreProducerDescription());
00061
00062 typename NameValueMap::const_iterator it
00063 = m_nameMap->find(m_ff->GetScoreProducerDescription());
00064
00065 UTIL_THROW_IF2(it == m_nameMap->end(),
00066 "No features stored for: "
00067 << m_ff->GetScoreProducerDescription());
00068
00069 return it->second;
00070 }
00071
00072 private:
00073 FeatureFunction* m_ff;
00074 Factory m_factory;
00075 static TSNameValueMap m_nameMap;
00076 };
00077
00078 template <class Value, class Factory>
00079 typename ThreadLocalByFeatureStorage<Value, Factory>::TSNameValueMap
00080 ThreadLocalByFeatureStorage<Value, Factory>::m_nameMap;
00081
00082 }