winix/core/sessioncontainer.cpp

203 lines
3.9 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "sessioncontainer.h"
#include "log.h"
#include "misc.h"
SessionContainer::SessionContainer()
{
request = 0;
table_size = 0;
}
void SessionContainer::SetRequest(Request * prequest)
{
request = prequest;
}
void SessionContainer::Clear()
{
Table::iterator inext, i = table.begin();
// don't use table.clear();
// because plugins session data would not be erased
while( i != table.end() )
{
inext = i;
++inext;
request->session = &(*i);
table.erase(i);
i = inext;
}
// erasing all indexes
index_id.clear();
index_time.clear();
table_size = 0;
request->session = 0;
}
void SessionContainer::SetLastContainer(LastContainer * plast_container)
{
last_container = plast_container;
}
SessionContainer::TableSize SessionContainer::Size()
{
// don't use table.size() as it has O(n) complexity on FreeBSD
return table_size;
}
SessionContainer::Iterator SessionContainer::Begin()
{
return table.begin();
}
SessionContainer::Iterator SessionContainer::End()
{
return table.end();
}
Session & SessionContainer::Back()
{
return table.back();
}
bool SessionContainer::PushBack(const Session & session)
{
if( index_id.find(session.id) != index_id.end() )
// that element already exists
return false;
Iterator last = table.insert(table.end(), session);
index_id.insert( std::make_pair(session.id, last) );
index_time.insert( std::make_pair(session.last_time, last) );
table_size += 1;
log << log3 << "SC: added session, id: " << session.id << logend;
return true;
}
SessionContainer::Iterator SessionContainer::FindById(long id)
{
IndexId::iterator i;
i = index_id.find(id);
if( i == index_id.end() )
return table.end();
return i->second;
}
void SessionContainer::DelFirstByTimeInterval(time_t interval, bool skip_remember_flag)
{
IndexTime::iterator i = index_time.begin();
IndexTime::iterator iold;
time_t limit = std::time(0) - interval;
Session * old_session = request->session;
while( i != index_time.end() && i->second->last_time < limit )
{
long id = i->second->id;
iold = i;
++i; // incrementing before deleting old one
if( skip_remember_flag && iold->second->puser && iold->second->remember_me )
// don't delete sessions which have 'remember_me' flag (and a user is logged)
continue;
if( iold->second->puser )
last_container->UserLogout(iold->second->puser->id, iold->second->id);
// we're logging session.id (call this before table.erase())
DelFromIdIndex(iold->second);
request->session = &(*iold->second);
table.erase(iold->second);
index_time.erase(iold);
table_size -= 1;
request->session = 0;
log << log3 << "SC: deleted index_time for session id: " << id << logend;
log << log3 << "SC: deleted session, id: " << id << logend;
}
request->session = old_session;
}
void SessionContainer::DelFromIdIndex(SessionContainer::Iterator iter)
{
IndexId::iterator i;
for(i = index_id.begin() ; i!=index_id.end() ; ++i)
{
if( i->second == iter )
{
index_id.erase(i);
log << log3 << "SC: deleted index_id for session id: " << iter->id << logend;
break;
}
}
}
void SessionContainer::UpdateLastTime(SessionContainer::Iterator iter, time_t new_time)
{
IndexTime::iterator i = index_time.lower_bound(iter->last_time);
bool found = false;
for( ; i != index_time.end() ; ++i)
{
if( i->second == iter )
{
index_time.erase(i);
index_time.insert( std::make_pair(new_time, iter) );
iter->last_time = new_time;
iter->tm_last_time = Time(new_time);
log << log3 << "SC: last time and the time index for session id: " << iter->id << " updated" << logend;
found = true;
break;
}
}
if( !found )
log << log1 << "SC: cannot update the time, time index not found for session id: " << iter->id << logend;
}