/* 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; } }