Esempio n. 1
0
int
read_cache(void)
{
    FILE *fr;
    LIST_MEMBER *pentry;
    char Line[LINESIZE + 1];
    int result = 0;

    Line[LINESIZE] = '\0';

    fr = fopen(cache_name, "r");
    if (!fr)
    {
        l2l_dbg(1, "Open %s failed\n", cache_name);
        return 2;
    }
    cache.phead = cache.ptail = NULL;

    while (fgets(Line, LINESIZE, fr) != NULL)
    {
        pentry = cache_entry_create(Line);
        if (!pentry)
        {
            l2l_dbg(2, "** Create entry failed of: %s\n", Line);
        }
        else
            entry_insert(&cache, pentry);
    }

    fclose(fr);
    return result;
}
Esempio n. 2
0
struct stasis_message *stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
{
	RAII_VAR(struct cache_entry *, search_entry, NULL, ao2_cleanup);
	RAII_VAR(struct cache_entry *, cached_entry, NULL, ao2_cleanup);

	ast_assert(cache->entries != NULL);

	search_entry = cache_entry_create(type, id, NULL);
	if (search_entry == NULL) {
		return NULL;
	}

	cached_entry = ao2_find(cache->entries, search_entry, OBJ_POINTER);
	if (cached_entry == NULL) {
		return NULL;
	}

	ast_assert(cached_entry->snapshot != NULL);
	ao2_ref(cached_entry->snapshot, +1);
	return cached_entry->snapshot;
}
Esempio n. 3
0
static struct stasis_message *cache_put(struct stasis_cache *cache,
	struct stasis_message_type *type, const char *id,
	struct stasis_message *new_snapshot)
{
	RAII_VAR(struct cache_entry *, new_entry, NULL, ao2_cleanup);
	RAII_VAR(struct cache_entry *, cached_entry, NULL, ao2_cleanup);
	struct stasis_message *old_snapshot = NULL;

	ast_assert(cache->entries != NULL);
	ast_assert(new_snapshot == NULL ||
		type == stasis_message_type(new_snapshot));

	new_entry = cache_entry_create(type, id, new_snapshot);

	if (new_snapshot == NULL) {
		/* Remove entry from cache */
		cached_entry = ao2_find(cache->entries, new_entry, OBJ_POINTER | OBJ_UNLINK);
		if (cached_entry) {
			old_snapshot = cached_entry->snapshot;
			cached_entry->snapshot = NULL;
		}
	} else {
		/* Insert/update cache */
		SCOPED_AO2LOCK(lock, cache->entries);

		cached_entry = ao2_find(cache->entries, new_entry, OBJ_POINTER | OBJ_NOLOCK);
		if (cached_entry) {
			/* Update cache. Because objects are moving, no need to update refcounts. */
			old_snapshot = cached_entry->snapshot;
			cached_entry->snapshot = new_entry->snapshot;
			new_entry->snapshot = NULL;
		} else {
			/* Insert into the cache */
			ao2_link_flags(cache->entries, new_entry, OBJ_NOLOCK);
		}

	}

	return old_snapshot;
}
Esempio n. 4
0
int main (int argc, char *argv[])
{
    struct cache *cache;
    struct cache_entry *e1, *e2;
    json_object *o1;
    json_object *o2;
    wait_t *w;
    int count, i;

    plan (NO_PLAN);

    cache_destroy (NULL);
    cache_entry_destroy (NULL);
    diag ("cache_destroy and cache_entry_destroy accept NULL arg");

    ok ((cache = cache_create ()) != NULL,
        "cache_create works");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    cache_destroy (cache);

    /* Play with one entry.
     * N.B.: json ref is NOT incremented by create or get_json.
     */
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    ok ((e1 = cache_entry_create (o1)) != NULL,
        "cache_entry_create works");
    ok (cache_entry_get_valid (e1) == true,
        "cache entry initially valid");
    ok (cache_entry_get_dirty (e1) == false,
        "cache entry initially not dirty");
    cache_entry_set_dirty (e1, true);
    ok (cache_entry_get_dirty (e1) == true,
        "cache entry succcessfully set dirty");
    ok ((o2 = cache_entry_get_json (e1)) != NULL,
        "json retrieved from cache entry");
    ok (Jget_int (o2, "foo", &i) == true && i == 42,
        "expected json object found");
    cache_entry_destroy (e1); /* destroys o1 */

    /* Test cache entry waiters.
     * N.B. waiter is destroyed when run.
     */
    count = 0;
    ok ((w = wait_create (wait_cb, &count)) != NULL,
        "wait_create works");
    ok ((e1 = cache_entry_create (NULL)) != NULL,
        "cache_entry_create created empty object");
    ok (cache_entry_get_valid (e1) == false,
        "cache entry invalid, adding waiter");
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    cache_entry_wait_valid (e1, w);
    cache_entry_set_json (e1, o1);
    ok (cache_entry_get_valid (e1) == true,
        "cache entry set valid with one waiter");
    ok (count == 1,
        "waiter callback ran");

    count = 0;
    ok ((w = wait_create (wait_cb, &count)) != NULL,
        "wait_create works");
    cache_entry_set_dirty (e1, true);
    ok (cache_entry_get_dirty (e1) == true,
        "cache entry set dirty, adding waiter");
    cache_entry_wait_notdirty (e1, w);
    cache_entry_set_dirty (e1, false);
    ok (cache_entry_get_dirty (e1) == false,
        "cache entry set not dirty with one waiter");
    ok (count == 1,
        "waiter callback ran");
    cache_entry_destroy (e1); /* destroys o1 */

    /* Put entry in cache and test lookup, expire
     */
    ok ((cache = cache_create ()) != NULL,
        "cache_create works");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    ok ((e1 = cache_entry_create (o1)) != NULL,
        "cache_entry_create works");
    cache_insert (cache, "xxx1", e1);
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry after insert");
    ok (cache_lookup (cache, "yyy1", 0) == NULL,
        "cache_lookup of wrong hash fails");
    ok ((e2 = cache_lookup (cache, "xxx1", 42)) != NULL,
        "cache_lookup of correct hash works (last use=42)");
    i = 0;
    ok ((o2 = cache_entry_get_json (e2)) != NULL
        && Jget_int (o2, "foo", &i) == true && i == 42,
        "expected json object found");
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry");
    ok (cache_expire_entries (cache, 43, 1) == 0,
        "cache_expire_entries now=43 thresh=1 expired 0");
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry");
    ok (cache_expire_entries (cache, 44, 1) == 1,
        "cache_expire_entries now=44 thresh=1 expired 1");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    cache_destroy (cache);

    done_testing ();
    return (0);
}
Esempio n. 5
0
// store file buffer into local storage
// if success == TRUE then "buf" successfuly stored on disc
void cache_mng_store_file_buf (CacheMng *cmng, fuse_ino_t ino, size_t size, off_t off, unsigned char *buf,
    cache_mng_on_store_file_buf_cb on_store_file_buf_cb, void *ctx)
{
    struct _CacheContext *context;
    struct _CacheEntry *entry;
    ssize_t res;
    int fd;
    char path[PATH_MAX];
    guint64 old_length, new_length;
    guint64 range_size;
    time_t now;

    range_size = (guint64)(off + size);

    // limit the number of cache checks
    now = time (NULL);
    if (cmng->check_time < now && now - cmng->check_time >= 10) {
        // remove data until we have at least size bytes of max_size left
        while (cmng->max_size < cmng->size + size && g_queue_peek_tail (cmng->q_lru)) {
            entry = (struct _CacheEntry *) g_queue_peek_tail (cmng->q_lru);

            cache_mng_remove_file (cmng, entry->ino);
        }
        cmng->check_time = now;
    }

    context = cache_context_create (size, ctx);
    context->cb.store_cb = on_store_file_buf_cb;

    cache_mng_file_name (cmng, path, sizeof (path), ino);
    fd = open (path, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if (fd < 0) {
        LOG_err (CMNG_LOG, INO_H"Failed to create / open file for writing! Path: %s", INO_T (ino), path);
        if (context->cb.store_cb)
            context->cb.store_cb (FALSE, context->user_ctx);
        cache_context_destroy (context);
        return;
    }
    res = pwrite(fd, buf, size, off);
    close (fd);

    entry = g_hash_table_lookup (cmng->h_entries, GUINT_TO_POINTER (ino));

    if (!entry) {
        entry = cache_entry_create (ino);
        g_queue_push_head (cmng->q_lru, entry);
        entry->ll_lru = g_queue_peek_head_link (cmng->q_lru);
        g_hash_table_insert (cmng->h_entries, GUINT_TO_POINTER (ino), entry);
    }

    old_length = range_length (entry->avail_range);
    range_add (entry->avail_range, off, range_size);
    new_length = range_length (entry->avail_range);
    if (new_length >= old_length)
        cmng->size += new_length - old_length;
    else {
        LOG_err (CMNG_LOG, INO_H"New length is less than the old length !: %"G_GUINT64_FORMAT" <= %"G_GUINT64_FORMAT, 
            INO_T (ino), new_length, old_length);
    }
    
    // update modification time
    entry->modification_time = time (NULL);
   
    context->success = (res == (ssize_t) size);

    LOG_debug (CMNG_LOG, INO_H"Written [%"OFF_FMT":%zu] bytes, result: %s", 
        INO_T (ino), off, size, context->success ? "OK" : "Failed");

    context->ev = event_new (application_get_evbase (cmng->app), -1,  0,
                    cache_write_cb, context);
    // fire this event at once
    event_active (context->ev, 0, 0);
    event_add (context->ev, NULL);
}