std::vector<int> hashtable;
std::vector<entry_t> entries;
int free_list, counter, begin_n;
+ int begin_seek_count;
OPS ops;
void init()
free_list = -1;
counter = 0;
begin_n = -1;
+ begin_seek_count = 0;
}
void init_from(const dict<K, T, OPS> &other)
return hash;
}
+ void upd_begin_n()
+ {
+ if (begin_n < -1) {
+ begin_n = -(begin_n+2);
+ if (begin_n > int(entries.size()))
+ begin_n = int(entries.size());
+ do {
+ if (begin_seek_count++ > int(entries.size()))
+ refree();
+ else
+ begin_n--;
+ } while (begin_n >= 0 && entries[begin_n].is_free());
+ }
+ }
+
+ void refree()
+ {
+ free_list = -1;
+ begin_n = -1;
+
+ int last_free = -1;
+ for (int i = 0; i < int(entries.size()); i++)
+ if (entries[i].is_free()) {
+ if (last_free != -1)
+ entries[last_free].set_next_free(i);
+ else
+ free_list = i;
+ last_free = i;
+ } else
+ begin_n = i;
+
+ if (last_free != -1)
+ entries[last_free].set_next_free(-1);
+
+ begin_seek_count = 0;
+ }
+
void rehash()
{
free_list = -1;
for (auto &h : hashtable)
h = -1;
+ int last_free = -1;
for (int i = 0; i < int(entries.size()); i++)
if (entries[i].is_free()) {
- entries[i].set_next_free(free_list);
- free_list = i;
+ if (last_free != -1)
+ entries[last_free].set_next_free(i);
+ else
+ free_list = i;
+ last_free = i;
} else {
int hash = mkhash(entries[i].udata.first);
entries[i].set_next_used(hashtable[hash]);
hashtable[hash] = i;
begin_n = i;
}
+
+ if (last_free != -1)
+ entries[last_free].set_next_free(-1);
+
+ begin_seek_count = 0;
}
int do_erase(const K &key, int hash)
if (--counter == 0)
clear();
else if (index == begin_n)
- do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free());
+ begin_n = -(begin_n+2);
return 1;
}
last_index = index;
entries[i].udata = value;
entries[i].set_next_used(hashtable[hash]);
hashtable[hash] = i;
- if (begin_n < i)
+ if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i))
begin_n = i;
counter++;
return i;
bool empty() const { return counter == 0; }
void clear() { hashtable.clear(); entries.clear(); init(); }
- iterator begin() { return iterator(this, begin_n); }
+ iterator begin() { upd_begin_n(); return iterator(this, begin_n); }
iterator end() { return iterator(this, -1); }
- const_iterator begin() const { return const_iterator(this, begin_n); }
+ const_iterator begin() const { ((dict*)this)->upd_begin_n(); return const_iterator(this, begin_n); }
const_iterator end() const { return const_iterator(this, -1); }
};
std::vector<int> hashtable;
std::vector<entry_t> entries;
int free_list, counter, begin_n;
+ int begin_seek_count;
OPS ops;
void init()
free_list = -1;
counter = 0;
begin_n = -1;
+ begin_seek_count = 0;
}
void init_from(const pool<K, OPS> &other)
return hash;
}
+ void upd_begin_n()
+ {
+ if (begin_n < -1) {
+ begin_n = -(begin_n+2);
+ if (begin_n > int(entries.size()))
+ begin_n = int(entries.size());
+ do {
+ if (begin_seek_count++ > int(entries.size()))
+ refree();
+ else
+ begin_n--;
+ } while (begin_n >= 0 && entries[begin_n].is_free());
+ }
+ }
+
+ void refree()
+ {
+ free_list = -1;
+ begin_n = -1;
+
+ int last_free = -1;
+ for (int i = 0; i < int(entries.size()); i++)
+ if (entries[i].is_free()) {
+ if (last_free != -1)
+ entries[last_free].set_next_free(i);
+ else
+ free_list = i;
+ last_free = i;
+ } else
+ begin_n = i;
+
+ if (last_free != -1)
+ entries[last_free].set_next_free(-1);
+
+ begin_seek_count = 0;
+ }
+
void rehash()
{
free_list = -1;
for (auto &h : hashtable)
h = -1;
+ int last_free = -1;
for (int i = 0; i < int(entries.size()); i++)
if (entries[i].is_free()) {
- entries[i].set_next_free(free_list);
- free_list = i;
+ if (last_free != -1)
+ entries[last_free].set_next_free(i);
+ else
+ free_list = i;
+ last_free = i;
} else {
int hash = mkhash(entries[i].key);
entries[i].set_next_used(hashtable[hash]);
hashtable[hash] = i;
begin_n = i;
}
+
+ if (last_free != -1)
+ entries[last_free].set_next_free(-1);
+
+ begin_seek_count = 0;
}
int do_erase(const K &key, int hash)
if (--counter == 0)
clear();
else if (index == begin_n)
- do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free());
+ begin_n = -(begin_n+2);
return 1;
}
last_index = index;
entries[i].key = key;
entries[i].set_next_used(hashtable[hash]);
hashtable[hash] = i;
- if (begin_n < i)
+ if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i))
begin_n = i;
counter++;
return i;
bool empty() const { return counter == 0; }
void clear() { hashtable.clear(); entries.clear(); init(); }
- iterator begin() { return iterator(this, begin_n); }
+ iterator begin() { upd_begin_n(); return iterator(this, begin_n); }
iterator end() { return iterator(this, -1); }
- const_iterator begin() const { return const_iterator(this, begin_n); }
+ const_iterator begin() const { ((pool*)this)->upd_begin_n(); return const_iterator(this, begin_n); }
const_iterator end() const { return const_iterator(this, -1); }
};