src/util/hash32.h \
src/util/local_increment.h \
src/util/lookup.h \
- src/util/ord_hash_set.h \
src/util/range.h \
src/util/s_to_n32_unsafe.h \
src/util/smart_ptr.h \
src/parse/input.cc \
src/parse/scanner.cc \
src/parse/unescape.cc \
- src/util/ord_hash_set.cc \
src/util/s_to_n32_unsafe.cc \
src/util/range.cc
re2c_SOURCES = \
#include "src/ir/rule.h"
#include "src/ir/tagpool.h"
#include "src/util/forbid_copy.h"
-#include "src/util/ord_hash_set.h"
namespace re2c
{
#include "src/ir/tagpool.h"
-#include "src/util/forbid_copy.h"
+#include "src/util/hash32.h"
namespace re2c
{
Tagpool::Tagpool(size_t n)
: ntags(n)
- , pool()
+ , lookup()
, buff(new bool[ntags]())
{
// all-no tag set must have number 0
Tagpool::~Tagpool()
{
delete[] buff;
+ const size_t n = lookup.size();
+ for (size_t i = 0; i < n; ++i) {
+ free(const_cast<bool*>(lookup[i]));
+ }
}
size_t Tagpool::insert(const bool *tags)
{
- return pool.insert(tags, ntags * sizeof(bool));
+ const size_t size = ntags * sizeof(bool);
+ const uint32_t hash = hash32(0, tags, size);
+
+ eqtag_t eq(ntags);
+ const size_t idx = lookup.find_with(hash, tags, eq);
+ if (idx != taglookup_t::NIL) {
+ return idx;
+ }
+
+ bool *copy = static_cast<bool*>(malloc(size));
+ memcpy(copy, tags, size);
+ return lookup.push(hash, copy);
+}
+
+const bool *Tagpool::operator[](size_t idx)
+{
+ return lookup[idx];
}
size_t Tagpool::orl(size_t t, size_t o)
return insert(buff);
}
-const bool *Tagpool::operator[](size_t idx)
-{
- const bool *tags;
- pool.deref<const bool>(idx, tags);
- return tags;
-}
-
} // namespace re2c
#ifndef _RE2C_IR_TAGPOOL_
#define _RE2C_IR_TAGPOOL_
-#include "src/util/ord_hash_set.h"
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy, memcmp
+
+#include "src/util/lookup.h"
#include "src/util/forbid_copy.h"
namespace re2c
{
+struct eqtag_t
+{
+ size_t ntags;
+
+ explicit eqtag_t(size_t n): ntags(n) {}
+ inline bool operator()(const bool *x, const bool *y)
+ {
+ return memcmp(x, y, ntags * sizeof(bool)) == 0;
+ }
+};
+
struct Tagpool
{
const size_t ntags;
private:
- ord_hash_set_t pool;
+ typedef lookup_t<const bool*> taglookup_t;
+ taglookup_t lookup;
bool *buff;
public:
+++ /dev/null
-#include <stddef.h>
-
-#include "src/util/ord_hash_set.h"
-
-namespace re2c
-{
-
-ord_hash_set_t::hash_t ord_hash_set_t::hash(const void *data, size_t size)
-{
- const uint8_t *bytes = static_cast<const uint8_t*>(data);
- hash_t h = size; // seed
- for (size_t i = 0; i < size; ++i)
- {
- h = h ^ ((h << 5) + (h >> 2) + bytes[i]);
- }
- return h;
-}
-
-ord_hash_set_t::elem_t* ord_hash_set_t::make_elem(
- elem_t *next,
- size_t index,
- size_t size,
- const void *data)
-{
- elem_t *e = static_cast<elem_t*>(malloc(offsetof(elem_t, data) + size));
- e->next = next;
- e->index = index;
- e->size = size;
- memcpy(e->data, data, size);
- return e;
-}
-
-ord_hash_set_t::ord_hash_set_t()
- : elems()
- , lookup()
-{}
-
-ord_hash_set_t::~ord_hash_set_t()
-{
- std::for_each(elems.begin(), elems.end(), free);
-}
-
-size_t ord_hash_set_t::size() const
-{
- return elems.size();
-}
-
-size_t ord_hash_set_t::insert(const void *data, size_t size)
-{
- const hash_t h = hash(data, size);
-
- std::map<hash_t, elem_t*>::const_iterator i = lookup.find(h);
- if (i != lookup.end())
- {
- for (elem_t *e = i->second; e; e = e->next)
- {
- if (e->size == size
- && memcmp(e->data, data, size) == 0)
- {
- return e->index;
- }
- }
- }
-
- const size_t index = elems.size();
- elems.push_back(lookup[h] = make_elem(lookup[h], index, size, data));
- return index;
-}
-
-} // namespace re2c
+++ /dev/null
-#ifndef _RE2C_UTIL_ORD_HASH_SET_
-#define _RE2C_UTIL_ORD_HASH_SET_
-
-#include "src/util/c99_stdint.h"
-#include <stdlib.h> // malloc, free
-#include <string.h> // memcpy
-#include <algorithm> // for_each
-#include <map>
-#include <vector>
-
-namespace re2c
-{
-
-/*
- * ordered hash set:
- * - access element by index: O(1)
- * - insert element (find existing or add new): O(log(n))
- *
- */
-class ord_hash_set_t
-{
- struct elem_t
- {
- elem_t *next;
- size_t index;
- size_t size;
- char data[1]; // inlined array of variable length
- };
- typedef size_t hash_t;
-
- std::vector<elem_t*> elems;
- std::map<hash_t, elem_t*> lookup;
-
- static hash_t hash(const void *data, size_t size);
- elem_t *make_elem(elem_t *next, size_t index, size_t size, const void *data);
-
-public:
- ord_hash_set_t();
- ~ord_hash_set_t();
- size_t size() const;
- size_t insert(const void *data, size_t size);
- template<typename data_t> size_t deref(size_t i, data_t *&data);
-};
-
-template<typename data_t> size_t ord_hash_set_t::deref(size_t i, data_t *&data)
-{
- elem_t *e = elems[i];
- data = reinterpret_cast<data_t*>(e->data);
- return e->size / sizeof(data_t);
-}
-
-} // namespace re2c
-
-#endif // _RE2C_UTIL_ORD_HASH_SET_