/* ====================================================================
 * Copyright (c) 2003-2006, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */


// sc
#include "RpListCache.h"
#include "RpListInfo.h"
#include "util/Mutex.h"
#include "util/Guard.h"

// sys
#include <map>

class InfoKey
{
public:
  InfoKey( const sc::String& url, svn::Revnumber rev )
    : _url(url), _rev(rev)
  {
  }

  bool operator<( const InfoKey& key ) const
  {
    if( _url == key._url )
    {
      return _rev < key._rev;
    }
    else 
    {
      return _url < key._url;
    }
  }

  sc::String     _url;
  svn::Revnumber _rev;
};

typedef std::map< InfoKey, RpListInfo > Infos;


struct RpListCache::Member
{
  sc::Mutex lock;
  Infos     infos;
};

static RpListInfo NullInfo( sc::String(""), svn::InvalidRevnumber, 0, svn::DirEntries() );


RpListCache::RpListCache()
{
  _m = new RpListCache::Member();
}

RpListCache::~RpListCache()
{
  delete _m;
}

void RpListCache::set( const RpListInfo& info )
{
  sc::Guard<sc::Mutex> guard(_m->lock);

  InfoKey key(info.getUrl(),info.getRevnumber());

  Infos::iterator it = _m->infos.find(key);  
  if( it != _m->infos.end() )
  {
    (*it).second = info;
  }
  else
  {
    _m->infos.insert( Infos::value_type(key,info) );
  }
}

RpListInfo RpListCache::get( const sc::String& key, svn::Revnumber rev )
{
  sc::Guard<sc::Mutex> guard(_m->lock);

  InfoKey mkey(key,rev);

  Infos::iterator it = _m->infos.find(mkey);  

  if( it == _m->infos.end() )
  {
    return NullInfo;
  }

  return (*it).second;
}
