From 15ad172a847fa667c57a4594ef4158405db9a984 Mon Sep 17 00:00:00 2001 From: Angelo Mantellini Date: Tue, 31 Mar 2020 17:50:43 +0200 Subject: [HICN-554] hicn-light refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I36f2d393741d4502ce14d3791158e43e3e9cd4cf Signed-off-by: Jordan Augé --- hicn-light/src/hicn/core/content_store.c | 198 +++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 hicn-light/src/hicn/core/content_store.c (limited to 'hicn-light/src/hicn/core/content_store.c') diff --git a/hicn-light/src/hicn/core/content_store.c b/hicn-light/src/hicn/core/content_store.c new file mode 100644 index 000000000..7ed2bd838 --- /dev/null +++ b/hicn-light/src/hicn/core/content_store.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2020 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file content_store.c + * \brief Implementation of hICN content_store + */ + +#include +#include +#include + +//#include + +#include "content_store.h" + +extern const content_store_ops_t content_store_lru; + +const content_store_ops_t * const content_store_vft[] = { + [CONTENT_STORE_TYPE_LRU] = &content_store_lru, +}; + +// XXX TODO replace by a single packet cache +// XXX TODO per cs type entry data too ! +// XXX TODO getting rid of logger and the need to acquire +// XXX TODO separate cs from vft, same with strategy + +#define content_store_entry_from_msgbuf(entry, msgbuf) \ +do { \ + (entry)->hasExpiryTimeTicks = msgbuf_HasContentExpiryTime(msgbuf); \ + if ((entry)->hasExpiryTimeTicks) \ + (entry)->expiryTimeTicks = msgbuf_GetContentExpiryTimeTicks(msgbuf); \ +} while(0) + + +content_store_t * +content_store_create(content_store_type_t type, size_t max_elts) +{ + content_store_t * cs = malloc(sizeof(content_store_t)); + if (!cs) + goto ERR_MALLOC; + if (!CONTENT_STORE_TYPE_VALID(type)) + goto ERR_TYPE; + cs->type = type; + + // XXX TODO an entry = data + metadata specific to each policy + pool_init(cs->entries, max_elts); + + // data + // options + // stats + + + // index by name + cs->index_by_name = kh_init(cs_name); + + cs->index_by_expiry_time = NULL; + if (!cs->index_by_expiry_time) { + ERROR("Could not create index (expiry time)"); + goto ERR_INDEX_EXPIRY; + } + + + // XXX indices specific to each policy => vft + // index by expiration time + // lru ? + + content_store_vft[type]->initialize(cs); + +ERR_INDEX_EXPIRY: + // XXX TODO +ERR_TYPE: +ERR_MALLOC: + return NULL; +} + +void +content_store_free(content_store_t * cs) +{ + content_store_vft[cs->type]->finalize(cs); + + if (cs->index_by_expiry_time) + ; //listTimeOrdered_Release(&(store->indexByExpirationTime)); +} + +void content_store_clear(content_store_t * cs) +{ + // XXX TODO +} + +msgbuf_t * +content_store_match(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now) +{ + assert(cs); + assert(msgbuf); + assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_INTEREST); + + /* Lookup entry by name */ + khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf)); + if (k == kh_end(cs->index_by_name)) + return NULL; + content_store_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k); + assert(entry); + + /* Remove any expired entry */ + if (content_store_entry_has_expiry_time(entry) && + content_store_entry_expiry_time(entry) < now) { + // the entry is expired, we can remove it + content_store_remove_entry(cs, entry); + goto NOT_FOUND; + } + + cs->stats.lru.countHits++; + +#if 0 // XXX + contentStoreEntry_MoveToHead(entry); +#endif + + DEBUG("CS %p LRU match %p (hits %" PRIu64 ", misses %" PRIu64 ")", + cs, msgbuf, cs->stats.lru.countHits, cs->stats.lru.countMisses); + return content_store_entry_message(entry); + +NOT_FOUND: + cs->stats.lru.countMisses++; + + DEBUG("ContentStoreLRU %p missed msgbuf %p (hits %" PRIu64 ", misses %" PRIu64 ")", + cs, msgbuf, cs->stats.lru.countHits, cs->stats.lru.countMisses); + return NULL; +} + +void +content_store_add(content_store_t * cs, msgbuf_t * msgbuf, uint64_t now) +{ + assert(cs); + assert(msgbuf); + assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA); + + content_store_entry_t * entry = NULL; + + /* borrow from content_store_lru_add_entry */ + + content_store_vft[cs->type]->add_entry(cs, entry); +} + +void +content_store_remove_entry(content_store_t * cs, content_store_entry_t * entry) +{ + assert(cs); + assert(entry); + + if (content_store_entry_has_expiry_time(entry)) + ; // XXX TODO listTimeOrdered_Remove(store->indexByExpirationTime, entryToPurge); + + msgbuf_t * msgbuf = content_store_entry_message(entry); + khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf)); + if (k != kh_end(cs->index_by_name)) + kh_del(cs_name, cs->index_by_name, k); + + // This will take care of LRU entry for instance + content_store_vft[cs->type]->remove_entry(cs, entry); + + //store->objectCount--; + pool_put(cs->entries, entry); + +} +// +// XXX TODO what is the difference between purge and remove ? +bool +content_store_remove(content_store_t * cs, msgbuf_t * msgbuf) +{ + assert(cs); + assert(msgbuf); + assert(msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA); + + /* Lookup entry by name */ + khiter_t k = kh_get_cs_name(cs->index_by_name, msgbuf_get_name(msgbuf)); + if (k == kh_end(cs->index_by_name)) + return false; + + content_store_entry_t * entry = cs->entries + kh_val(cs->index_by_name, k); + assert(entry); + + content_store_remove_entry(cs, entry); + return true; +} + -- cgit 1.2.3-korg