diff options
author | Matthew Cline <zelgadis@sourceforge.net> | 2009-11-10 02:08:57 -0800 |
---|---|---|
committer | Matthew Cline <zelgadis@sourceforge.net> | 2009-11-10 02:13:09 -0800 |
commit | 75921593c0f8f33133034bc56dc94d956d2afd67 (patch) | |
tree | f674de5fd73a8ab1dd507c3813e2dcde90327d91 /crawl-ref/source | |
parent | 5e9e9773f748ab17c8298cd212c77bf5ea1b2051 (diff) | |
download | crawl-ref-75921593c0f8f33133034bc56dc94d956d2afd67.tar.gz crawl-ref-75921593c0f8f33133034bc56dc94d956d2afd67.zip |
CrawlHashTable: reduce RAM overhead
The RAM overhead for an unused CrawlHash table has been reduced from 32
to 4 (on 32 bit systems), with an increased overhead of 4 bytes for ones
which are used. This leads to a 35% RAM reduction for item_def
instances with an unused props field.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/decks.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 12 | ||||
-rw-r--r-- | crawl-ref/source/store.cc | 224 | ||||
-rw-r--r-- | crawl-ref/source/store.h | 24 | ||||
-rw-r--r-- | crawl-ref/source/tags.h | 25 |
9 files changed, 140 insertions, 164 deletions
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index 3391aea762..07016dea68 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -3056,11 +3056,11 @@ void init_deck(item_def &item) ASSERT(item.special >= DECK_RARITY_COMMON && item.special <= DECK_RARITY_LEGENDARY); - props.set_default_flags(SFLAG_CONST_TYPE); + const store_flags fl = SFLAG_CONST_TYPE; - props["cards"].new_vector(SV_BYTE).resize((vec_size)item.plus); - props["card_flags"].new_vector(SV_BYTE).resize((vec_size)item.plus); - props["drawn_cards"].new_vector(SV_BYTE); + props["cards"].new_vector(SV_BYTE, fl).resize((vec_size)item.plus); + props["card_flags"].new_vector(SV_BYTE, fl).resize((vec_size)item.plus); + props["drawn_cards"].new_vector(SV_BYTE, fl); for (int i = 0; i < item.plus; ++i) { diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index f1e22443d4..f4a57bef67 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -2100,7 +2100,7 @@ void set_feature_desc_long(const std::string &raw_name, CrawlHashTable &props = env.properties; if (!props.exists(LONG_DESC_KEY)) - props[LONG_DESC_KEY].new_table(SV_STR); + props[LONG_DESC_KEY].new_table(); CrawlHashTable &desc_table = props[LONG_DESC_KEY].get_table(); diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 7d8d3a8392..23f0cba945 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -2839,7 +2839,7 @@ void set_feature_desc_short(const std::string &base_name, CrawlHashTable &props = env.properties; if (!props.exists(SHORT_DESC_KEY)) - props[SHORT_DESC_KEY].new_table(SV_STR); + props[SHORT_DESC_KEY].new_table(); CrawlHashTable &desc_table = props[SHORT_DESC_KEY].get_table(); diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 6870e90476..f2f46d92ad 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -955,8 +955,8 @@ void dgn_reset_level() env.properties.clear(); // Set up containers for storing some level generation info. - env.properties[LEVEL_VAULTS_KEY].new_table(SV_STR); - env.properties[TEMP_VAULTS_KEY].new_table(SV_STR); + env.properties[LEVEL_VAULTS_KEY].new_table(); + env.properties[TEMP_VAULTS_KEY].new_table(); env.properties[LEVEL_EXTRAS_KEY].new_vector(SV_STR); // Blank level with DNGN_ROCK_WALL. diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index fa9034eb99..dd4924995c 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -466,6 +466,9 @@ void unlink_item( int dest ) void destroy_item( item_def &item, bool never_created ) { + // Free up CrawlHashTable memory. + item.props.clear(); + if (!item.is_valid()) return; diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 505a4328b0..4be5a39c2d 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -203,8 +203,7 @@ void init_stack_blood_potions(item_def &stack, int age) CrawlHashTable &props = stack.props; props.clear(); // sanity measure - props.set_default_flags(SFLAG_CONST_TYPE); - props["timer"].new_vector(SV_LONG); + props["timer"].new_vector(SV_LONG, SFLAG_CONST_TYPE); CrawlVector &timer = props["timer"].get_vector(); if (age == -1) @@ -406,8 +405,7 @@ void maybe_coagulate_blood_potions_floor(int obj) item_colour(item); CrawlHashTable &props_new = item.props; - props_new.set_default_flags(SFLAG_CONST_TYPE); - props_new["timer"].new_vector(SV_LONG); + props_new["timer"].new_vector(SV_LONG, SFLAG_CONST_TYPE); CrawlVector &timer_new = props_new["timer"].get_vector(); long val; @@ -663,8 +661,7 @@ bool maybe_coagulate_blood_potions_inv(item_def &blood) item_colour(item); CrawlHashTable &props_new = item.props; - props_new.set_default_flags(SFLAG_CONST_TYPE); - props_new["timer"].new_vector(SV_LONG); + props_new["timer"].new_vector(SV_LONG, SFLAG_CONST_TYPE); CrawlVector &timer_new = props_new["timer"].get_vector(); long val; @@ -744,8 +741,7 @@ bool maybe_coagulate_blood_potions_inv(item_def &blood) item_colour(mitm[o]); CrawlHashTable &props_new = mitm[o].props; - props_new.set_default_flags(SFLAG_CONST_TYPE); - props_new["timer"].new_vector(SV_LONG); + props_new["timer"].new_vector(SV_LONG, SFLAG_CONST_TYPE); CrawlVector &timer_new = props_new["timer"].get_vector(); long val; diff --git a/crawl-ref/source/store.cc b/crawl-ref/source/store.cc index cf771633fe..97d1e0a8c1 100644 --- a/crawl-ref/source/store.cc +++ b/crawl-ref/source/store.cc @@ -302,10 +302,12 @@ void CrawlStoreValue::unset(bool force) } case SV_NONE: - ASSERT(false); + DEBUGSTR("CrawlStoreValue::unset: unsetting nothing"); + break; - case NUM_STORE_VAL_TYPES: - ASSERT(false); + default: + DEBUGSTR("CrawlStoreValue::unset: unsetting invalid type"); + break; } flags |= SFLAG_UNSET; @@ -339,8 +341,6 @@ CrawlStoreValue &CrawlStoreValue::operator = (const CrawlStoreValue &other) switch (type) { case SV_NONE: - break; - case SV_BOOL: case SV_BYTE: case SV_SHORT: @@ -377,8 +377,8 @@ CrawlStoreValue &CrawlStoreValue::operator = (const CrawlStoreValue &other) COPY_PTR(level_pos); break; - case NUM_STORE_VAL_TYPES: - DEBUGSTR("CrawlStoreValue has type NUM_STORE_VAL_TYPES"); + default: + DEBUGSTR("CrawlStoreValue has invalid type"); break; } @@ -595,37 +595,9 @@ void CrawlStoreValue::read(reader &th) } } -//////////////////////////////////////////////////////////////// -// Setup a new table with the given flags and/or type; assert if -// a table already exists. -CrawlHashTable &CrawlStoreValue::new_table(store_flags _flags) -{ - return new_table(SV_NONE, flags); -} - -CrawlHashTable &CrawlStoreValue::new_table(store_val_type _type, - store_flags _flags) +CrawlHashTable &CrawlStoreValue::new_table() { -#ifdef DEBUG - CrawlHashTable* old_table = static_cast<CrawlHashTable*>(val.ptr); - - ASSERT(flags & SFLAG_UNSET); - ASSERT(type == SV_NONE - || (type == SV_HASH - && old_table->size() == 0 - && old_table->get_type() == SV_NONE - && old_table->get_default_flags() == 0)); -#endif - - CrawlHashTable &table = get_table(); - - table.default_flags = _flags; - table.type = _type; - - type = SV_HASH; - flags &= ~SFLAG_UNSET; - - return table; + return get_table(); } //////////////////////////////////////////////////////////////// @@ -1165,26 +1137,43 @@ std::string &CrawlStoreValue::operator += (const std::string &_val) //////////////////////////////////////////////////////////////////////////// CrawlHashTable::CrawlHashTable() - : type(SV_NONE), default_flags(0) { + hash_map = NULL; } -CrawlHashTable::CrawlHashTable(store_flags flags) - : type(SV_NONE), default_flags(flags) +CrawlHashTable::CrawlHashTable(const CrawlHashTable& other) { - ASSERT(!(default_flags & SFLAG_UNSET)); + if (other.hash_map == NULL) + { + hash_map = NULL; + return; + } + + hash_map = new hash_map_type(*(other.hash_map)); } -CrawlHashTable::CrawlHashTable(store_val_type _type, store_flags flags) - : type(_type), default_flags(flags) +CrawlHashTable::~CrawlHashTable() { - ASSERT(type >= SV_NONE && type < NUM_STORE_VAL_TYPES); - ASSERT(!(default_flags & SFLAG_UNSET)); + // NOTE: Not using std::auto_ptr because making hash_map and auto_ptr + // causes compile weirdness in externs.h + if (hash_map == NULL) + return; + + delete hash_map; + hash_map = NULL; } -CrawlHashTable::~CrawlHashTable() +CrawlHashTable &CrawlHashTable::operator = (const CrawlHashTable &other) { - assert_validity(); + if (other.hash_map == NULL) + { + hash_map = NULL; + return (*this); + } + + hash_map = new hash_map_type(*(other.hash_map)); + + return (*this); } ////////////////////////////// @@ -1199,12 +1188,10 @@ void CrawlHashTable::write(writer &th) const } marshallByte(th, size()); - marshallByte(th, static_cast<char>(type)); - marshallByte(th, (char) default_flags); - CrawlHashTable::hash_map_type::const_iterator i = hash_map.begin(); + CrawlHashTable::hash_map_type::const_iterator i = hash_map->begin(); - for (; i != hash_map.end(); i++) + for (; i != hash_map->end(); i++) { marshallString(th, i->first); i->second.write(th); @@ -1218,16 +1205,19 @@ void CrawlHashTable::read(reader &th) assert_validity(); ASSERT(empty()); - ASSERT(type == SV_NONE); - ASSERT(default_flags == 0); hash_size _size = (hash_size) unmarshallByte(th); if (_size == 0) return; - type = static_cast<store_val_type>(unmarshallByte(th)); - default_flags = (store_flags) unmarshallByte(th); + if (th.getMinorVersion() < TAG_MINOR_SMALL_HASH) + { + unmarshallByte(th); + unmarshallByte(th); + } + + init_hash_map(); for (hash_size i = 0; i < _size; i++) { @@ -1244,54 +1234,28 @@ void CrawlHashTable::read(reader &th) ////////////////// // Misc functions -store_flags CrawlHashTable::get_default_flags() const -{ - assert_validity(); - return default_flags; -} - -store_flags CrawlHashTable::set_default_flags(store_flags flags) -{ - assert_validity(); - ASSERT(!(flags & SFLAG_UNSET)); - default_flags |= flags; - - return default_flags; -} - -store_flags CrawlHashTable::unset_default_flags(store_flags flags) -{ - assert_validity(); - ASSERT(!(flags & SFLAG_UNSET)); - default_flags &= ~flags; - - return default_flags; -} - -store_val_type CrawlHashTable::get_type() const -{ - assert_validity(); - return type; -} - bool CrawlHashTable::exists(const std::string &key) const { + if (hash_map == NULL) + return (false); + assert_validity(); - hash_map_type::const_iterator i = hash_map.find(key); + hash_map_type::const_iterator i = hash_map->find(key); - return (i != hash_map.end()); + return (i != hash_map->end()); } void CrawlHashTable::assert_validity() const { #ifdef DEBUG - ASSERT(!(default_flags & SFLAG_UNSET)); + if (hash_map == NULL) + return; - hash_map_type::const_iterator i = hash_map.begin(); + hash_map_type::const_iterator i = hash_map->begin(); unsigned long actual_size = 0; - for (; i != hash_map.end(); i++) + for (; i != hash_map->end(); i++) { actual_size++; @@ -1305,9 +1269,6 @@ void CrawlHashTable::assert_validity() const ASSERT(val.type != SV_NONE); ASSERT(!(val.flags & SFLAG_UNSET)); - if (type != SV_NONE) - ASSERT(type == val.type); - switch (val.type) { case SV_STR: @@ -1355,18 +1316,14 @@ void CrawlHashTable::assert_validity() const CrawlStoreValue& CrawlHashTable::get_value(const std::string &key) { assert_validity(); - iterator i = hash_map.find(key); + init_hash_map(); - if (i == hash_map.end()) - { - hash_map[key] = CrawlStoreValue(default_flags); - CrawlStoreValue &val = hash_map[key]; + iterator i = hash_map->find(key); - if (type != SV_NONE) - { - val.type = type; - val.flags |= SFLAG_CONST_TYPE; - } + if (i == hash_map->end()) + { + (*hash_map)[key] = CrawlStoreValue(); + CrawlStoreValue &val = (*hash_map)[key]; return (val); } @@ -1376,10 +1333,12 @@ CrawlStoreValue& CrawlHashTable::get_value(const std::string &key) const CrawlStoreValue& CrawlHashTable::get_value(const std::string &key) const { + ASSERT(hash_map != NULL); assert_validity(); - hash_map_type::const_iterator i = hash_map.find(key); - ASSERT(i != hash_map.end()); + hash_map_type::const_iterator i = hash_map->find(key); + + ASSERT(i != hash_map->end()); ASSERT(i->second.type != SV_NONE); ASSERT(!(i->second.flags & SFLAG_UNSET)); @@ -1401,66 +1360,86 @@ const CrawlStoreValue& CrawlHashTable::operator[] (const std::string &key) // std::map style interface hash_size CrawlHashTable::size() const { - return hash_map.size(); + if (hash_map == NULL) + return (0); + + return hash_map->size(); } bool CrawlHashTable::empty() const { - return hash_map.empty(); + if (hash_map == NULL) + return (true); + + return hash_map->empty(); } void CrawlHashTable::erase(const std::string key) { assert_validity(); - iterator i = hash_map.find(key); + init_hash_map(); - if (i != hash_map.end()) + iterator i = hash_map->find(key); + + if (i != hash_map->end()) { #ifdef DEBUG CrawlStoreValue &val = i->second; ASSERT(!(val.flags & SFLAG_NO_ERASE)); #endif - hash_map.erase(i); + hash_map->erase(i); } } void CrawlHashTable::clear() { assert_validity(); - ASSERT(!(default_flags & SFLAG_NO_ERASE)); - - iterator i = hash_map.begin(); - for (; i != hash_map.end(); i++) - ASSERT(!(i->second.flags & SFLAG_NO_ERASE)); + if (hash_map == NULL) + return; - hash_map.clear(); - default_flags = 0; - type = SV_NONE; + delete hash_map; + hash_map = NULL; } CrawlHashTable::iterator CrawlHashTable::begin() { assert_validity(); - return hash_map.begin(); + init_hash_map(); + + return hash_map->begin(); } CrawlHashTable::iterator CrawlHashTable::end() { assert_validity(); - return hash_map.end(); + init_hash_map(); + + return hash_map->end(); } CrawlHashTable::const_iterator CrawlHashTable::begin() const { + ASSERT(hash_map != NULL); assert_validity(); - return hash_map.begin(); + + return hash_map->begin(); } CrawlHashTable::const_iterator CrawlHashTable::end() const { + ASSERT(hash_map != NULL); assert_validity(); - return hash_map.end(); + + return hash_map->end(); +} + +void CrawlHashTable::init_hash_map() +{ + if (hash_map != NULL) + return; + + hash_map = new hash_map_type(); } ///////////////////////////////////////////////////////////////////////////// @@ -1876,7 +1855,6 @@ template <typename T, store_val_type TYPE> void CrawlTableWrapper<T, TYPE>::wrap(CrawlHashTable* _table) { ASSERT(_table != NULL); - ASSERT(_table->get_type() == TYPE); table = _table; } diff --git a/crawl-ref/source/store.h b/crawl-ref/source/store.h index 1eae58f2b2..e23e6056be 100644 --- a/crawl-ref/source/store.h +++ b/crawl-ref/source/store.h @@ -109,8 +109,7 @@ public: store_flags unset_flags(store_flags flags); store_val_type get_type() const; - CrawlHashTable &new_table(store_flags flags); - CrawlHashTable &new_table(store_val_type type, store_flags flags = 0); + CrawlHashTable &new_table(); CrawlVector &new_vector(store_flags flags, vec_size max_size = VEC_MAX_SIZE); @@ -270,8 +269,7 @@ class CrawlHashTable { public: CrawlHashTable(); - CrawlHashTable(store_flags flags); - CrawlHashTable(store_val_type type, store_flags flags = 0); + CrawlHashTable(const CrawlHashTable& other); ~CrawlHashTable(); @@ -280,22 +278,22 @@ public: typedef hash_map_type::const_iterator const_iterator; protected: - store_val_type type; - store_flags default_flags; - hash_map_type hash_map; + // NOTE: Not using std::auto_ptr because making hash_map an auto_ptr + // causes compile weirdness in externs.h + hash_map_type *hash_map; + + void init_hash_map(); friend class CrawlStoreValue; public: + CrawlHashTable &operator = (const CrawlHashTable &other); + void write(writer &) const; void read(reader &); - store_flags get_default_flags() const; - store_flags set_default_flags(store_flags flags); - store_flags unset_default_flags(store_flags flags); - store_val_type get_type() const; - bool exists(const std::string &key) const; - void assert_validity() const; + bool exists(const std::string &key) const; + void assert_validity() const; // NOTE: If the const versions of get_value() or [] are given a // key which doesn't exist, they will assert. diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index c85796bef9..b843a55329 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -49,18 +49,19 @@ enum tag_major_version // the dungeon Lua changes. enum tag_minor_version { - TAG_MINOR_ARTEFACT = 0, // Turned fixed arts into unrandarts. - TAG_MINOR_JIYVA = 1, // Added some player bits for Jiyva. - TAG_MINOR_ZOT_OPEN = 2, // Remember whether Zot was opened. - TAG_MINOR_JELLY = 3, // Remember whether the royal jelly is dead. - TAG_ANNOTATE_EXCL = 4, // Store exclusion information for annotations. - TAG_MINOR_UGLY = 5, // More ghost bits for (very) ugly things. - TAG_MINOR_ROTTING = 6, // Added monster-specific rotting resistance. - TAG_MINOR_TRANS = 7, // Keep track of cancellable transformations. - TAG_MINOR_GITREV = 8, // Removed SVN revision and added Git revision. - TAG_MINOR_DSTRAITS = 9, // Pre-calculate demonspawn mutations - TAG_MINOR_YOU_PROP = 10, // Player class has CrawlHashTable - TAG_MINOR_VERSION = 10 // Current version. (Keep equal to max.) + TAG_MINOR_ARTEFACT = 0, // Turned fixed arts into unrandarts. + TAG_MINOR_JIYVA = 1, // Added some player bits for Jiyva. + TAG_MINOR_ZOT_OPEN = 2, // Remember whether Zot was opened. + TAG_MINOR_JELLY = 3, // Remember whether the royal jelly is dead. + TAG_ANNOTATE_EXCL = 4, // Store exclusion information for annotations. + TAG_MINOR_UGLY = 5, // More ghost bits for (very) ugly things. + TAG_MINOR_ROTTING = 6, // Added monster-specific rotting resistance. + TAG_MINOR_TRANS = 7, // Keep track of cancellable transformations. + TAG_MINOR_GITREV = 8, // Removed SVN revision and added Git revision. + TAG_MINOR_DSTRAITS = 9, // Pre-calculate demonspawn mutations + TAG_MINOR_YOU_PROP = 10, // Player class has CrawlHashTable + TAG_MINOR_SMALL_HASH = 11, // Reduced RAM size of CrawlHashTable + TAG_MINOR_VERSION = 11 // Current version. (Keep equal to max.) }; |