int ht_add_entry(t_hash *hash, void *data, void const *key, size_t key_size) { size_t hashed_key; size_t offset; t_entry *entry; hashed_key = (hash->hash)(key, key_size); offset = hashed_key % hash->size; entry = malloc(sizeof(t_entry)); if (entry == NULL) return (false); entry->data = data; entry->key = duplicate_key(key, key_size); if (!entry->key) { free(entry); return (false); } entry->key_size = key_size; entry->hash = hashed_key; return ((*(hash->buckets[offset])).prepend(&hash->buckets[offset], entry)); }
// validate the _var_info[] table bool AP_Param::check_var_info(void) { uint16_t total_size = sizeof(struct EEPROM_header); for (uint8_t i=0; i<_num_vars; i++) { uint8_t type = PGM_UINT8(&_var_info[i].type); uint8_t key = PGM_UINT8(&_var_info[i].key); if (type == AP_PARAM_GROUP) { if (i == 0) { // first element can't be a group, for first() call return false; } const struct GroupInfo *group_info = (const struct GroupInfo *)PGM_POINTER(&_var_info[i].group_info); if (group_info == NULL || !check_group_info(group_info, &total_size, 0)) { return false; } } else { uint8_t size = type_size((enum ap_var_type)type); if (size == 0) { // not a valid type - the top level list can't contain // AP_PARAM_NONE return false; } total_size += size + sizeof(struct Param_header); } if (duplicate_key(i, key)) { return false; } } // we no longer check if total_size is larger than _eeprom_size, // as we allow for more variables than could fit, relying on not // saving default values return true; }
// validate the _var_info[] table bool AP_Param::check_var_info(void) { uint16_t total_size = sizeof(struct EEPROM_header); for (uint8_t i=0; i<_num_vars; i++) { uint8_t type = PGM_UINT8(&_var_info[i].type); uint8_t key = PGM_UINT8(&_var_info[i].key); if (type == AP_PARAM_GROUP) { if (i == 0) { // first element can't be a group, for first() call return false; } const struct GroupInfo *group_info = (const struct GroupInfo *)PGM_POINTER(&_var_info[i].group_info); if (group_info == NULL || !check_group_info(group_info, &total_size, 0)) { return false; } } else { uint8_t size = type_size((enum ap_var_type)type); if (size == 0) { // not a valid type - the top level list can't contain // AP_PARAM_NONE return false; } total_size += size + sizeof(struct Param_header); } if (duplicate_key(i, key)) { return false; } } if (total_size > _eeprom_size) { serialDebug("total_size %u exceeds _eeprom_size %u", total_size, _eeprom_size); return false; } return true; }
static svn_error_t * inprocess_cache_set_internal(inprocess_cache_t *cache, const void *key, void *value, apr_pool_t *scratch_pool) { struct cache_entry *existing_entry; existing_entry = apr_hash_get(cache->hash, key, cache->klen); /* Is it already here, but we can do the one-item-per-page * optimization? */ if (existing_entry && cache->items_per_page == 1) { /* Special case! ENTRY is the *only* entry on this page, so * why not wipe it (so as not to leak the previous value). */ struct cache_page *page = existing_entry->page; /* This can't be the partial page: items_per_page == 1 * *never* has a partial page (except for in the temporary state * that we're about to fake). */ SVN_ERR_ASSERT(page->next != NULL); SVN_ERR_ASSERT(cache->partial_page == NULL); erase_page(cache, page); existing_entry = NULL; } /* Is it already here, and we just have to leak the old value? */ if (existing_entry) { struct cache_page *page = existing_entry->page; SVN_ERR(move_page_to_front(cache, page)); cache->data_size -= existing_entry->size; if (value) { SVN_ERR(cache->serialize_func(&existing_entry->value, &existing_entry->size, value, page->page_pool)); cache->data_size += existing_entry->size; if (existing_entry->size == 0) existing_entry->value = NULL; } else { existing_entry->value = NULL; existing_entry->size = 0; } return SVN_NO_ERROR; } /* Do we not have a partial page to put it on, but we are allowed to * allocate more? */ if (cache->partial_page == NULL && cache->unallocated_pages > 0) { cache->partial_page = apr_pcalloc(cache->cache_pool, sizeof(*(cache->partial_page))); cache->partial_page->page_pool = svn_pool_create(cache->cache_pool); cache->partial_page_number_filled = 0; (cache->unallocated_pages)--; } /* Do we really not have a partial page to put it on, even after the * one-item-per-page optimization and checking the unallocated page * count? */ if (cache->partial_page == NULL) { struct cache_page *oldest_page = cache->sentinel->prev; SVN_ERR_ASSERT(oldest_page != cache->sentinel); /* Erase the page and put it in cache->partial_page. */ erase_page(cache, oldest_page); } SVN_ERR_ASSERT(cache->partial_page != NULL); { struct cache_page *page = cache->partial_page; struct cache_entry *new_entry = apr_pcalloc(page->page_pool, sizeof(*new_entry)); /* Copy the key and value into the page's pool. */ new_entry->key = duplicate_key(cache, key, page->page_pool); if (value) { SVN_ERR(cache->serialize_func(&new_entry->value, &new_entry->size, value, page->page_pool)); cache->data_size += new_entry->size; if (new_entry->size == 0) new_entry->value = NULL; } else { new_entry->value = NULL; new_entry->size = 0; } /* Add the entry to the page's list. */ new_entry->page = page; new_entry->next_entry = page->first_entry; page->first_entry = new_entry; /* Add the entry to the hash, using the *entry's* copy of the * key. */ apr_hash_set(cache->hash, new_entry->key, cache->klen, new_entry); /* We've added something else to the partial page. */ (cache->partial_page_number_filled)++; /* Is it full? */ if (cache->partial_page_number_filled >= cache->items_per_page) { insert_page(cache, page); cache->partial_page = NULL; } } return SVN_NO_ERROR; }