/*
Copyright (C) 2012 Olaf Till
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; If not, see .
*/
#include "ptrmap.h"
#include
int ptrmap_class::insert (void *ptr)
{
if (! instance) init ();
return instance->do_insert (ptr);
}
int ptrmap_class::do_insert (void *ptr)
{
int key;
if (! holes_set.empty ())
{
ptrset_t::iterator iter;
key = *(iter = holes_set.begin ());
active_map[key] = ptr;
holes_set.erase (iter);
}
else
{
if (active_map.size () == active_map.max_size ())
{
error (0, 0, "could not insert pointer");
return -1;
}
else
{
if (active_map.empty ())
key = 0;
else
key = active_map.rbegin ()->first + 1;
active_map[key] = ptr;
}
}
return key;
}
void *ptrmap_class::lookup (int key, int& err)
{
if (! instance) init ();
return instance->do_lookup (key, err);
}
void *ptrmap_class::do_lookup (int key, int& err)
{
void *ptr;
err = 0;
if (lookup_cache != active_map.end () &&
lookup_cache->first == key)
ptr = lookup_cache->second;
else
{
ptrmap_t::const_iterator iter;
if ((iter = active_map.find (key)) == active_map.end ())
{
error (0, 0, "invalid key");
err = 1;
}
else
{
ptr = iter->second;
lookup_cache = iter;
}
}
return ptr;
}
int ptrmap_class::remove (int key)
{
if (! instance) init ();
return instance->do_remove (key);
}
int ptrmap_class::do_remove (int key)
{
ptrmap_t::iterator iter;
if ((iter = active_map.find (key)) == active_map.end ())
{
error (0, 0, "invalid key");
return -1;
}
else
{
if (iter == --active_map.end ())
{
active_map.erase (iter);
int last = active_map.rbegin ()->first;
ptrset_t::iterator siter = holes_set.upper_bound (last);
holes_set.erase (siter, holes_set.end ());
}
else
{
active_map.erase (iter);
holes_set.insert (key);
}
if (key == lookup_cache->first)
lookup_cache = active_map.end ();
return 0;
}
}