|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _ISS_H |
|
#define _ISS_H |
|
|
|
#include <limits> |
|
#include <vector> |
|
#include <string.h> |
|
|
|
|
|
#ifdef USE_HASHSET |
|
#include <ext/hash_set> |
|
#else |
|
#include <set> |
|
#endif |
|
|
|
#include <boost/pool/pool.hpp> |
|
|
|
#ifdef USE_HASHSET |
|
|
|
template<class IndType> |
|
class StringsEqualComparator; |
|
|
|
template<class IndType> |
|
class Hasher; |
|
#else |
|
|
|
template<class IndType> |
|
class StringsLessComparator; |
|
#endif |
|
|
|
|
|
|
|
template<class IndType> |
|
class IndexedStringsStorage { |
|
|
|
public: |
|
|
|
typedef IndType index_type; |
|
|
|
#ifdef USE_HASHSET |
|
typedef StringsEqualComparator<IndType> equality_comparator_t; |
|
|
|
typedef Hasher<IndType> hasher_t; |
|
|
|
|
|
typedef __gnu_cxx::hash_set<IndType, hasher_t, equality_comparator_t> index_t; |
|
#else |
|
typedef StringsLessComparator<IndType> less_comparator_t; |
|
|
|
|
|
typedef std::set<IndType, less_comparator_t> index_t; |
|
#endif |
|
|
|
|
|
|
|
typedef std::vector<const char*> table_t; |
|
|
|
private: |
|
|
|
|
|
boost::pool<> _storage; |
|
|
|
|
|
table_t _table; |
|
|
|
|
|
index_t _index; |
|
|
|
public: |
|
|
|
|
|
IndexedStringsStorage(void); |
|
|
|
|
|
|
|
inline bool is_full(void) const { return _table.size() == std::numeric_limits<IndType>::max(); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
inline const char* get(IndType index) const { return _table[index]; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IndType put(const char* str); |
|
|
|
|
|
|
|
inline table_t::size_type size(void) const { return _table.size(); } |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#ifdef USE_HASHSET |
|
template<class IndType> |
|
class StringsEqualComparator: public std::binary_function<IndType, IndType, bool> { |
|
#else |
|
template<class IndType> |
|
class StringsLessComparator: public std::binary_function<IndType, IndType, bool> { |
|
#endif |
|
|
|
const typename IndexedStringsStorage<IndType>::table_t& _table; |
|
public: |
|
#ifdef USE_HASHSET |
|
StringsEqualComparator<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _table(table) {} |
|
#else |
|
StringsLessComparator<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _table(table) {} |
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool operator()(IndType lhs, IndType rhs) const { |
|
#ifdef USE_HASHSET |
|
return strcmp(_table[lhs], _table[rhs]) == 0; |
|
#else |
|
return strcmp(_table[lhs], _table[rhs]) < 0; |
|
#endif |
|
} |
|
}; |
|
|
|
#ifdef USE_HASHSET |
|
|
|
|
|
template<class IndType> |
|
class Hasher: public std::unary_function<IndType, size_t> { |
|
|
|
__gnu_cxx::hash<const char*> _hash; |
|
|
|
|
|
const typename IndexedStringsStorage<IndType>::table_t& _table; |
|
|
|
public: |
|
|
|
Hasher<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _hash(), _table(table) {} |
|
|
|
|
|
|
|
|
|
|
|
inline size_t operator()(const IndType index) const { |
|
return _hash(_table[index]); |
|
} |
|
}; |
|
#endif |
|
|
|
template <class IndType> |
|
#ifdef USE_HASHSET |
|
IndexedStringsStorage<IndType>::IndexedStringsStorage(void): _storage(sizeof(char)), _table(), _index(100, hasher_t(_table), equality_comparator_t(_table)) {} |
|
#else |
|
IndexedStringsStorage<IndType>::IndexedStringsStorage(void): _storage(sizeof(char)), _table(), _index(less_comparator_t(_table)) {} |
|
#endif |
|
|
|
template <class IndType> |
|
IndType IndexedStringsStorage<IndType>::put(const char* str) { |
|
|
|
if ( this->is_full() ) { |
|
|
|
throw std::bad_alloc(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
IndType index = static_cast<IndType>(_table.size()); |
|
_table.push_back(str); |
|
|
|
#ifdef USE_HASHSET |
|
|
|
typename index_t::iterator iIndex = _index.find(index); |
|
#else |
|
|
|
|
|
typename index_t::iterator iIndex = _index.lower_bound(index); |
|
#endif |
|
|
|
if ( (iIndex != _index.end()) |
|
#ifndef USE_HASHSET |
|
|
|
|
|
&& (strcmp(_table[*iIndex], str) == 0) |
|
#endif |
|
) { |
|
|
|
|
|
_table.pop_back(); |
|
|
|
return static_cast<IndType>(*iIndex); |
|
} |
|
|
|
|
|
|
|
|
|
char* mem = static_cast<char*>(_storage.ordered_malloc(strlen(str) + 1)); |
|
|
|
strcpy(mem, str); |
|
|
|
|
|
|
|
_table[index] = mem; |
|
|
|
#ifdef USE_HASHSET |
|
|
|
_index.insert(index); |
|
#else |
|
|
|
|
|
_index.insert(iIndex, index); |
|
#endif |
|
|
|
|
|
return index; |
|
} |
|
|
|
#endif |
|
|