diff options
Diffstat (limited to 'src/common/simple_string_dictionary.h')
-rw-r--r-- | src/common/simple_string_dictionary.h | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/src/common/simple_string_dictionary.h b/src/common/simple_string_dictionary.h index 28c4bf1c..94849205 100644 --- a/src/common/simple_string_dictionary.h +++ b/src/common/simple_string_dictionary.h @@ -147,39 +147,42 @@ class NonAllocatingMap { if (!key) return NULL; - const Entry* entry = GetConstEntryForKey(key); - if (!entry) + size_t index = GetEntryIndexForKey(key); + if (index == num_entries) return NULL; - return entry->value; + return entries_[index].value; } // Stores |value| into |key|, replacing the existing value if |key| is // already present. |key| must not be NULL. If |value| is NULL, the key is // removed from the map. If there is no more space in the map, then the - // operation silently fails. - void SetKeyValue(const char* key, const char* value) { + // operation silently fails. Returns an index into the map that can be used + // to quickly access the entry, or |num_entries| on failure or when clearing + // a key with a null value. + size_t SetKeyValue(const char* key, const char* value) { if (!value) { RemoveKey(key); - return; + return num_entries; } assert(key); if (!key) - return; + return num_entries; // Key must not be an empty string. assert(key[0] != '\0'); if (key[0] == '\0') - return; + return num_entries; - Entry* entry = GetEntryForKey(key); + size_t entry_index = GetEntryIndexForKey(key); // If it does not yet exist, attempt to insert it. - if (!entry) { + if (entry_index == num_entries) { for (size_t i = 0; i < num_entries; ++i) { if (!entries_[i].is_active()) { - entry = &entries_[i]; + entry_index = i; + Entry* entry = &entries_[i]; strncpy(entry->key, key, key_size); entry->key[key_size - 1] = '\0'; @@ -190,8 +193,8 @@ class NonAllocatingMap { } // If the map is out of space, entry will be NULL. - if (!entry) - return; + if (entry_index == num_entries) + return num_entries; #ifndef NDEBUG // Sanity check that the key only appears once. @@ -203,28 +206,46 @@ class NonAllocatingMap { assert(count == 1); #endif + strncpy(entries_[entry_index].value, value, value_size); + entries_[entry_index].value[value_size - 1] = '\0'; + + return entry_index; + } + + // Sets a value for a key that has already been set with SetKeyValue(), using + // the index returned from that function. + void SetValueAtIndex(size_t index, const char* value) { + assert(index < num_entries); + if (index >= num_entries) + return; + + Entry* entry = &entries_[index]; + assert(entry->key[0] != '\0'); + strncpy(entry->value, value, value_size); entry->value[value_size - 1] = '\0'; } // Given |key|, removes any associated value. |key| must not be NULL. If - // the key is not found, this is a noop. + // the key is not found, this is a noop. This invalidates the index + // returned by SetKeyValue(). bool RemoveKey(const char* key) { assert(key); if (!key) return false; - Entry* entry = GetEntryForKey(key); - if (entry) { - entry->key[0] = '\0'; - entry->value[0] = '\0'; - return true; - } + return RemoveAtIndex(GetEntryIndexForKey(key)); + } -#ifndef NDEBUG - assert(GetEntryForKey(key) == NULL); -#endif - return false; + // Removes a value and key using an index that was returned from + // SetKeyValue(). After a call to this function, the index is invalidated. + bool RemoveAtIndex(size_t index) { + if (index >= num_entries) + return false; + + entries_[index].key[0] = '\0'; + entries_[index].value[0] = '\0'; + return true; } // Places a serialized version of the map into |map| and returns the size. @@ -237,17 +258,13 @@ class NonAllocatingMap { } private: - const Entry* GetConstEntryForKey(const char* key) const { + size_t GetEntryIndexForKey(const char* key) const { for (size_t i = 0; i < num_entries; ++i) { if (strncmp(key, entries_[i].key, key_size) == 0) { - return &entries_[i]; + return i; } } - return NULL; - } - - Entry* GetEntryForKey(const char* key) { - return const_cast<Entry*>(GetConstEntryForKey(key)); + return num_entries; } Entry entries_[NumEntries]; |