mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Defer initialization of lists and dicts until an item is added.
Instead of pre-allocating every list with space for 10 items, don't initialize it at all until the first Insert. Instead of pre-allocating every dictionary with 17 buckets, don't initialize it at all until the first Insert.
This commit is contained in:
parent
aff3f4b3fd
commit
52dbaef6da
3 changed files with 37 additions and 31 deletions
27
src/Dict.cc
27
src/Dict.cc
|
@ -53,7 +53,7 @@ public:
|
||||||
|
|
||||||
Dictionary::Dictionary(dict_order ordering, int initial_size)
|
Dictionary::Dictionary(dict_order ordering, int initial_size)
|
||||||
{
|
{
|
||||||
Init(initial_size);
|
tbl = 0;
|
||||||
tbl2 = 0;
|
tbl2 = 0;
|
||||||
|
|
||||||
if ( ordering == ORDERED )
|
if ( ordering == ORDERED )
|
||||||
|
@ -61,14 +61,13 @@ Dictionary::Dictionary(dict_order ordering, int initial_size)
|
||||||
else
|
else
|
||||||
order = 0;
|
order = 0;
|
||||||
|
|
||||||
SetDensityThresh(DEFAULT_DENSITY_THRESH);
|
|
||||||
|
|
||||||
delete_func = 0;
|
delete_func = 0;
|
||||||
tbl_next_ind = 0;
|
tbl_next_ind = 0;
|
||||||
|
|
||||||
cumulative_entries = 0;
|
cumulative_entries = 0;
|
||||||
num_buckets2 = num_entries2 = max_num_entries2 = thresh_entries2 = 0;
|
num_buckets2 = num_entries2 = max_num_entries2 = thresh_entries2 = 0;
|
||||||
den_thresh2 = 0;
|
den_thresh2 = 0;
|
||||||
|
max_num_entries = num_entries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::~Dictionary()
|
Dictionary::~Dictionary()
|
||||||
|
@ -80,12 +79,14 @@ Dictionary::~Dictionary()
|
||||||
void Dictionary::Clear()
|
void Dictionary::Clear()
|
||||||
{
|
{
|
||||||
DeInit();
|
DeInit();
|
||||||
Init(2);
|
tbl = 0;
|
||||||
tbl2 = 0;
|
tbl2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::DeInit()
|
void Dictionary::DeInit()
|
||||||
{
|
{
|
||||||
|
if ( tbl == 0 )
|
||||||
|
return;
|
||||||
for ( int i = 0; i < num_buckets; ++i )
|
for ( int i = 0; i < num_buckets; ++i )
|
||||||
if ( tbl[i] )
|
if ( tbl[i] )
|
||||||
{
|
{
|
||||||
|
@ -127,6 +128,8 @@ void Dictionary::DeInit()
|
||||||
|
|
||||||
void* Dictionary::Lookup(const void* key, int key_size, hash_t hash) const
|
void* Dictionary::Lookup(const void* key, int key_size, hash_t hash) const
|
||||||
{
|
{
|
||||||
|
if (tbl == 0 && tbl2 == 0 )
|
||||||
|
return 0;
|
||||||
hash_t h;
|
hash_t h;
|
||||||
PList(DictEntry)* chain;
|
PList(DictEntry)* chain;
|
||||||
|
|
||||||
|
@ -155,6 +158,8 @@ void* Dictionary::Lookup(const void* key, int key_size, hash_t hash) const
|
||||||
void* Dictionary::Insert(void* key, int key_size, hash_t hash, void* val,
|
void* Dictionary::Insert(void* key, int key_size, hash_t hash, void* val,
|
||||||
int copy_key)
|
int copy_key)
|
||||||
{
|
{
|
||||||
|
if ( tbl == 0 )
|
||||||
|
Init(DEFAULT_DICT_SIZE);
|
||||||
DictEntry* new_entry = new DictEntry(key, key_size, hash, val);
|
DictEntry* new_entry = new DictEntry(key, key_size, hash, val);
|
||||||
void* old_val = Insert(new_entry, copy_key);
|
void* old_val = Insert(new_entry, copy_key);
|
||||||
|
|
||||||
|
@ -179,6 +184,8 @@ void* Dictionary::Insert(void* key, int key_size, hash_t hash, void* val,
|
||||||
void* Dictionary::Remove(const void* key, int key_size, hash_t hash,
|
void* Dictionary::Remove(const void* key, int key_size, hash_t hash,
|
||||||
bool dont_delete)
|
bool dont_delete)
|
||||||
{
|
{
|
||||||
|
if ( tbl == 0 && tbl2 == 0 )
|
||||||
|
return 0;
|
||||||
hash_t h;
|
hash_t h;
|
||||||
PList(DictEntry)* chain;
|
PList(DictEntry)* chain;
|
||||||
int* num_entries_ptr;
|
int* num_entries_ptr;
|
||||||
|
@ -280,6 +287,13 @@ void Dictionary::StopIteration(IterCookie* cookie) const
|
||||||
|
|
||||||
void* Dictionary::NextEntry(HashKey*& h, IterCookie*& cookie, int return_hash) const
|
void* Dictionary::NextEntry(HashKey*& h, IterCookie*& cookie, int return_hash) const
|
||||||
{
|
{
|
||||||
|
if ( tbl == 0 && tbl2 == 0 )
|
||||||
|
{
|
||||||
|
const_cast<PList(IterCookie)*>(&cookies)->remove(cookie);
|
||||||
|
delete cookie;
|
||||||
|
cookie = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// If there are any inserted entries, return them first.
|
// If there are any inserted entries, return them first.
|
||||||
// That keeps the list small and helps avoiding searching
|
// That keeps the list small and helps avoiding searching
|
||||||
// a large list when deleting an entry.
|
// a large list when deleting an entry.
|
||||||
|
@ -366,6 +380,7 @@ void Dictionary::Init(int size)
|
||||||
tbl[i] = 0;
|
tbl[i] = 0;
|
||||||
|
|
||||||
max_num_entries = num_entries = 0;
|
max_num_entries = num_entries = 0;
|
||||||
|
SetDensityThresh(DEFAULT_DENSITY_THRESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::Init2(int size)
|
void Dictionary::Init2(int size)
|
||||||
|
@ -382,6 +397,8 @@ void Dictionary::Init2(int size)
|
||||||
// private
|
// private
|
||||||
void* Dictionary::Insert(DictEntry* new_entry, int copy_key)
|
void* Dictionary::Insert(DictEntry* new_entry, int copy_key)
|
||||||
{
|
{
|
||||||
|
if ( tbl == 0 )
|
||||||
|
Init(DEFAULT_DICT_SIZE);
|
||||||
PList(DictEntry)** ttbl;
|
PList(DictEntry)** ttbl;
|
||||||
int* num_entries_ptr;
|
int* num_entries_ptr;
|
||||||
int* max_num_entries_ptr;
|
int* max_num_entries_ptr;
|
||||||
|
@ -568,6 +585,8 @@ unsigned int Dictionary::MemoryAllocation() const
|
||||||
{
|
{
|
||||||
int size = padded_sizeof(*this);
|
int size = padded_sizeof(*this);
|
||||||
|
|
||||||
|
if ( tbl == 0 )
|
||||||
|
return size;
|
||||||
for ( int i = 0; i < num_buckets; ++i )
|
for ( int i = 0; i < num_buckets; ++i )
|
||||||
if ( tbl[i] )
|
if ( tbl[i] )
|
||||||
{
|
{
|
||||||
|
|
39
src/List.cc
39
src/List.cc
|
@ -6,33 +6,27 @@
|
||||||
#include "List.h"
|
#include "List.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static const int DEFAULT_CHUNK_SIZE = 10;
|
#define DEFAULT_LIST_SIZE 10
|
||||||
|
#define GROWTH_FACTOR 2
|
||||||
|
|
||||||
BaseList::BaseList(int size)
|
BaseList::BaseList(int size)
|
||||||
{
|
{
|
||||||
chunk_size = DEFAULT_CHUNK_SIZE;
|
|
||||||
|
|
||||||
if ( size < 0 )
|
|
||||||
{
|
|
||||||
num_entries = max_entries = 0;
|
|
||||||
entry = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( size > 0 )
|
|
||||||
chunk_size = size;
|
|
||||||
|
|
||||||
num_entries = 0;
|
num_entries = 0;
|
||||||
entry = (ent *) safe_malloc(chunk_size * sizeof(ent));
|
max_entries = 0;
|
||||||
max_entries = chunk_size;
|
entry = 0;
|
||||||
}
|
|
||||||
|
if ( size <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
max_entries = size;
|
||||||
|
|
||||||
|
entry = (ent *) safe_malloc(max_entries * sizeof(ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BaseList::BaseList(BaseList& b)
|
BaseList::BaseList(BaseList& b)
|
||||||
{
|
{
|
||||||
max_entries = b.max_entries;
|
max_entries = b.max_entries;
|
||||||
chunk_size = b.chunk_size;
|
|
||||||
num_entries = b.num_entries;
|
num_entries = b.num_entries;
|
||||||
|
|
||||||
if ( max_entries )
|
if ( max_entries )
|
||||||
|
@ -58,7 +52,6 @@ void BaseList::operator=(BaseList& b)
|
||||||
free(entry);
|
free(entry);
|
||||||
|
|
||||||
max_entries = b.max_entries;
|
max_entries = b.max_entries;
|
||||||
chunk_size = b.chunk_size;
|
|
||||||
num_entries = b.num_entries;
|
num_entries = b.num_entries;
|
||||||
|
|
||||||
if ( max_entries )
|
if ( max_entries )
|
||||||
|
@ -74,8 +67,7 @@ void BaseList::insert(ent a)
|
||||||
{
|
{
|
||||||
if ( num_entries == max_entries )
|
if ( num_entries == max_entries )
|
||||||
{
|
{
|
||||||
resize(max_entries + chunk_size); // make more room
|
resize(max_entries==0 ? DEFAULT_LIST_SIZE : max_entries*GROWTH_FACTOR); // make more room
|
||||||
chunk_size *= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = num_entries; i > 0; --i )
|
for ( int i = num_entries; i > 0; --i )
|
||||||
|
@ -95,8 +87,7 @@ void BaseList::sortedinsert(ent a, list_cmp_func cmp_func)
|
||||||
// First append element.
|
// First append element.
|
||||||
if ( num_entries == max_entries )
|
if ( num_entries == max_entries )
|
||||||
{
|
{
|
||||||
resize(max_entries + chunk_size);
|
resize(max_entries==0 ? DEFAULT_LIST_SIZE : max_entries*GROWTH_FACTOR);
|
||||||
chunk_size *= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry[num_entries++] = a;
|
entry[num_entries++] = a;
|
||||||
|
@ -142,8 +133,7 @@ void BaseList::append(ent a)
|
||||||
{
|
{
|
||||||
if ( num_entries == max_entries )
|
if ( num_entries == max_entries )
|
||||||
{
|
{
|
||||||
resize(max_entries + chunk_size); // make more room
|
resize(max_entries==0 ? DEFAULT_LIST_SIZE : max_entries*GROWTH_FACTOR); // make more room
|
||||||
chunk_size *= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry[num_entries++] = a;
|
entry[num_entries++] = a;
|
||||||
|
@ -168,7 +158,6 @@ void BaseList::clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
num_entries = max_entries = 0;
|
num_entries = max_entries = 0;
|
||||||
chunk_size = DEFAULT_CHUNK_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ent BaseList::replace(int ent_index, ent new_ent)
|
ent BaseList::replace(int ent_index, ent new_ent)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// element up, and resizing the list, which involves getting new space
|
// element up, and resizing the list, which involves getting new space
|
||||||
// and moving the data. Resizing occurs automatically when inserting
|
// and moving the data. Resizing occurs automatically when inserting
|
||||||
// more elements than the list can currently hold. Automatic
|
// more elements than the list can currently hold. Automatic
|
||||||
// resizing is done one "chunk_size" of elements at a time and
|
// resizing is done by growing by GROWTH_FACTOR at a time and
|
||||||
// always increases the size of the list. Resizing to zero
|
// always increases the size of the list. Resizing to zero
|
||||||
// (or to less than the current value of num_entries)
|
// (or to less than the current value of num_entries)
|
||||||
// will decrease the size of the list to the current number of
|
// will decrease the size of the list to the current number of
|
||||||
|
@ -32,7 +32,6 @@ public:
|
||||||
|
|
||||||
void clear(); // remove all entries
|
void clear(); // remove all entries
|
||||||
int length() const { return num_entries; }
|
int length() const { return num_entries; }
|
||||||
int chunk() const { return chunk_size; }
|
|
||||||
int max() const { return max_entries; }
|
int max() const { return max_entries; }
|
||||||
int resize(int = 0); // 0 => size to fit current number of entries
|
int resize(int = 0); // 0 => size to fit current number of entries
|
||||||
|
|
||||||
|
@ -79,7 +78,6 @@ protected:
|
||||||
void operator=(BaseList&);
|
void operator=(BaseList&);
|
||||||
|
|
||||||
ent* entry;
|
ent* entry;
|
||||||
int chunk_size; // increase size by this amount when necessary
|
|
||||||
int max_entries;
|
int max_entries;
|
||||||
int num_entries;
|
int num_entries;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue