00001
00002 #pragma once
00003 #include "moses/Util.h"
00004 #include "moses/ContextScope.h"
00005 #include "moses/parameters/AllOptions.h"
00006 #include <sys/time.h>
00007 #include <boost/unordered_map.hpp>
00008
00009 #ifdef WITH_THREADS
00010 #include <boost/thread/shared_mutex.hpp>
00011 #include <boost/thread/locks.hpp>
00012 #endif
00013 namespace MosesServer{
00014
00015 struct Session
00016 {
00017 uint64_t const id;
00018 time_t start_time;
00019 time_t last_access;
00020 boost::shared_ptr<Moses::ContextScope> const scope;
00021 SPTR<std::map<std::string,float> > m_context_weights;
00022
00023
00024 Session(uint64_t const session_id)
00025 : id(session_id)
00026 , scope(new Moses::ContextScope)
00027 {
00028 last_access = start_time = time(NULL);
00029 }
00030
00031 bool is_new() const { return last_access == start_time; }
00032
00033 void setup(std::map<std::string, xmlrpc_c::value> const& params);
00034 };
00035
00036 class SessionCache
00037 {
00038 mutable boost::shared_mutex m_lock;
00039 uint64_t m_session_counter;
00040 boost::unordered_map<uint64_t,Session> m_cache;
00041 public:
00042
00043 SessionCache() : m_session_counter(1) {}
00044
00045 Session const&
00046 operator[](uint32_t id)
00047 {
00048 boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
00049 if (id > 1)
00050 {
00051 boost::unordered_map<uint64_t, Session>::iterator m = m_cache.find(id);
00052 if (m != m_cache.end())
00053 {
00054 m->second.last_access = time(NULL);
00055 return m->second;
00056 }
00057 }
00058 boost::upgrade_to_unique_lock<boost::shared_mutex> xlock(lock);
00059 id = ++m_session_counter;
00060 std::pair<uint64_t, Session> foo(id, Session(id));
00061 return m_cache.insert(foo).first->second;
00062 }
00063
00064 void
00065 erase(uint32_t const id)
00066 {
00067 boost::unique_lock<boost::shared_mutex> lock(m_lock);
00068 m_cache.erase(id);
00069 }
00070
00071
00072 };
00073
00074
00075 }