Back to index

avfs  1.0.1
Classes | Defines | Functions | Variables
cache.c File Reference
#include "cache.h"
#include "internal.h"
#include "exit.h"
#include <stdio.h>
#include <stdlib.h>

Go to the source code of this file.

Classes

struct  cacheobj

Defines

#define MBYTE   (1024 * 1024)

Functions

static AV_LOCK_DECL (cachelock)
static int cache_clear ()
static int cache_getfunc (struct entry *ent, const char *param, char **retp)
static int cache_setfunc (struct entry *ent, const char *param, const char *val)
static int cache_getoff (struct entry *ent, const char *param, char **retp)
static int cache_setoff (struct entry *ent, const char *param, const char *val)
static void destroy_cache ()
 This is the exit handler to remove all temporary file stored using the V2 interface.
void av_init_cache ()
static void cacheobj_remove (struct cacheobj *cobj)
static void cacheobj_insert (struct cacheobj *cobj)
static void cacheobj_free (struct cacheobj *cobj)
static void cacheobj_delete (struct cacheobj *cobj)
 This is the destructor for external cacheobj's created using the V1 interface.
static void cacheobj_internal_delete (struct cacheobj *cobj)
 This is the destructor for internal cacheobj's created using the V2 interface Because of possible race conditions the object can only by destroyed when holding the lock.
struct cacheobjav_cacheobj_new (void *obj, const char *name)
 cache V1 interface using external cache objects The object created by _new is not referenced by the cache itself so the user has to take care of this.
static int cache_free_one (struct cacheobj *skip_entry)
static void cache_checkspace (int full, struct cacheobj *skip_entry)
void av_cache_checkspace ()
void av_cache_diskfull ()
void av_cacheobj_setsize (struct cacheobj *cobj, avoff_t diskusage)
void * av_cacheobj_get (struct cacheobj *cobj)
static struct cacheobjcacheobj2_find (const char *name)
int av_cache2_set (void *obj, const char *name)
 cache V2 interface using internal cache objects The interface doesn't returns the cache object storing the obj.
void * av_cache2_get (const char *name)
void av_cache2_setsize (const char *name, avoff_t diskusage)

Variables

static struct cacheobj
static avoff_t disk_cache_limit = 100 * MBYTE
static avoff_t disk_keep_free = 10 * MBYTE
static avoff_t disk_usage = 0

Class Documentation

struct cacheobj

Definition at line 35 of file cache.c.

Collaboration diagram for cacheobj:
Class Members
avoff_t diskusage
int internal_obj
char * name
struct cacheobj * next
void * obj
struct cacheobj * prev

Define Documentation

#define MBYTE   (1024 * 1024)

Definition at line 46 of file cache.c.


Function Documentation

void* av_cache2_get ( const char *  name)

Definition at line 411 of file cache.c.

{
    struct cacheobj *cobj;
    void *obj = NULL;
    
    AV_LOCK(cachelock);
    cobj = cacheobj2_find(name);
    if(cobj != NULL) {
        cacheobj_remove(cobj);
        cacheobj_insert(cobj);
        obj = cobj->obj;
        av_ref_obj(obj);
    }
    AV_UNLOCK(cachelock);

    return obj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int av_cache2_set ( void *  obj,
const char *  name 
)

cache V2 interface using internal cache objects The interface doesn't returns the cache object storing the obj.

The name is used to access the object.

Definition at line 382 of file cache.c.

{
    struct cacheobj *cobj, *oldcobj;

    if(obj != NULL) {
        AV_NEW_OBJ(cobj, cacheobj_internal_delete);
        cobj->obj = obj;
        cobj->diskusage = 0;
        cobj->name = av_strdup(name);
        cobj->internal_obj = 1;
        av_ref_obj(obj);
    } else {
        cobj = NULL;
    }

    AV_LOCK(cachelock);
    oldcobj = cacheobj2_find(name);

    if(oldcobj != NULL )
        av_unref_obj(oldcobj);

    if(cobj != NULL)
        cacheobj_insert(cobj);

    AV_UNLOCK(cachelock);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_cache2_setsize ( const char *  name,
avoff_t  diskusage 
)

Definition at line 429 of file cache.c.

{
    struct cacheobj *cobj;

    AV_LOCK(cachelock);
    cobj = cacheobj2_find(name);
    if(cobj->obj != NULL && cobj->diskusage != diskusage) {
        disk_usage -= cobj->diskusage;
        cobj->diskusage = diskusage;
        disk_usage += cobj->diskusage;
        
        cache_checkspace(0, cobj);
    }
    AV_UNLOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 319 of file cache.c.

{
    AV_LOCK(cachelock);
    cache_checkspace(0,NULL);
    AV_UNLOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 326 of file cache.c.

{
    AV_LOCK(cachelock);
    cache_checkspace(1,NULL);
    AV_UNLOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* av_cacheobj_get ( struct cacheobj cobj)

Definition at line 347 of file cache.c.

{
    void *obj;

    if(cobj == NULL)
        return NULL;

    AV_LOCK(cachelock);
    obj = cobj->obj;
    if(obj != NULL) {
        cacheobj_remove(cobj);
        cacheobj_insert(cobj);
        av_ref_obj(obj);
    }
    AV_UNLOCK(cachelock);

    return obj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct cacheobj* av_cacheobj_new ( void *  obj,
const char *  name 
) [read]

cache V1 interface using external cache objects The object created by _new is not referenced by the cache itself so the user has to take care of this.

The object is required to access to object stored in the cache.

Definition at line 234 of file cache.c.

{
    struct cacheobj *cobj;

    if(obj == NULL)
        return NULL;

    AV_NEW_OBJ(cobj, cacheobj_delete);
    cobj->obj = obj;
    cobj->diskusage = 0;
    cobj->name = av_strdup(name);
    cobj->internal_obj = 0;
    av_ref_obj(obj);

    AV_LOCK(cachelock);
    cacheobj_insert(cobj);
    AV_UNLOCK(cachelock);

    return cobj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_cacheobj_setsize ( struct cacheobj cobj,
avoff_t  diskusage 
)

Definition at line 334 of file cache.c.

{
    AV_LOCK(cachelock);
    if(cobj->obj != NULL && cobj->diskusage != diskusage) {
        disk_usage -= cobj->diskusage;
        cobj->diskusage = diskusage;
        disk_usage += cobj->diskusage;
        
        cache_checkspace(0, cobj);
    }
    AV_UNLOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_init_cache ( )

Definition at line 138 of file cache.c.

{
    struct statefile statf;

    cachelist.next = &cachelist;
    cachelist.prev = &cachelist;

    statf.get = cache_getoff;
    statf.set = cache_setoff;
 
    statf.data = &disk_cache_limit;
    av_avfsstat_register("cache/limit", &statf);
    
    statf.data = &disk_keep_free;
    av_avfsstat_register("cache/keep_free", &statf);

    statf.set = NULL;
    statf.data = &disk_usage;
    av_avfsstat_register("cache/usage", &statf);

    statf.set = cache_setfunc;
    statf.get = cache_getfunc;
    statf.data = cache_clear;
    av_avfsstat_register("cache/clear", &statf);
    
    av_add_exithandler(destroy_cache);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static AV_LOCK_DECL ( cachelock  ) [static]
static void cache_checkspace ( int  full,
struct cacheobj skip_entry 
) [static]

Definition at line 290 of file cache.c.

{
    avoff_t tmpfree;
    avoff_t limit;
    avoff_t keepfree;
    
    if(full)
        tmpfree = 0;
    else
        tmpfree = av_tmp_free();

    /* If free space can't be determined, then it is taken to be infinite */
    if(tmpfree == -1)
        tmpfree = AV_MAXOFF;
    
    keepfree = disk_keep_free;
    if(keepfree < 100 * 1024)
        keepfree = 100 * 1024;

    limit = disk_usage - disk_keep_free + tmpfree;
    if(disk_cache_limit < limit)
        limit = disk_cache_limit;
    
    while(disk_usage > limit)
        if(!cache_free_one(skip_entry))
            break;        
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_clear ( ) [static]

Definition at line 281 of file cache.c.

{
    AV_LOCK(cachelock);
    while(cache_free_one(NULL));
    AV_UNLOCK(cachelock);
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_free_one ( struct cacheobj skip_entry) [static]

Definition at line 255 of file cache.c.

{
    struct cacheobj *cobj;
    struct cacheobj tmpcobj;

    cobj = cachelist.prev;
    if(cobj == skip_entry)
       cobj = cobj->prev;
    if(cobj == &cachelist)
        return 0;

    if(cobj->internal_obj) {
        av_unref_obj(cobj);
    } else {
        cacheobj_remove(cobj);
        disk_usage -= cobj->diskusage;
        tmpcobj = *cobj;
        cobj->obj = NULL;
        AV_UNLOCK(cachelock);
        cacheobj_free(&tmpcobj);
        AV_LOCK(cachelock);
    }

    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_getfunc ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 56 of file cache.c.

{
    *retp = av_strdup("");
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_getoff ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 73 of file cache.c.

{
    char buf[64];
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    avoff_t *offp = (avoff_t *)  sf->data;

    AV_LOCK(cachelock);
    sprintf(buf, "%llu\n", *offp);
    AV_UNLOCK(cachelock);

    *retp = av_strdup(buf);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_setfunc ( struct entry ent,
const char *  param,
const char *  val 
) [static]

Definition at line 62 of file cache.c.

{
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    int (*func)() = (int (*)()) sf->data;
    
    if(strlen(val) > 0)
        return func();

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_setoff ( struct entry ent,
const char *  param,
const char *  val 
) [static]

Definition at line 87 of file cache.c.

{
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    avoff_t *offp = (avoff_t *) sf->data;
    avoff_t offval;
    char *end;
    
    /* Make truncate work with fuse */
    if(!val[0])
        offval = 0;
    else {
        offval = strtoll(val, &end, 0);
        if(end == val)
            return -EINVAL;
        if(*end == '\n')
            end ++;
        if(*end != '\0')
            return -EINVAL;
        if(offval < 0)
            return -EINVAL;
    }

    AV_LOCK(cachelock);
    *offp = offval;
    AV_UNLOCK(cachelock);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct cacheobj* cacheobj2_find ( const char *  name) [static, read]

Definition at line 366 of file cache.c.

{
    struct cacheobj *cobj;
    
    for(cobj = cachelist.next; cobj != &cachelist; cobj = cobj->next) {
        if(cobj->internal_obj == 1)
            if(strcmp(cobj->name, name) == 0)
                break;
    }

    if(cobj->obj == NULL)
        return NULL;

    return cobj;
}

Here is the caller graph for this function:

static void cacheobj_delete ( struct cacheobj cobj) [static]

This is the destructor for external cacheobj's created using the V1 interface.

Definition at line 202 of file cache.c.

{
    AV_LOCK(cachelock);
    if(cobj->obj != NULL) {
        cacheobj_remove(cobj);
        disk_usage -= cobj->diskusage;
    }
    AV_UNLOCK(cachelock);

    if(cobj->obj != NULL)
        cacheobj_free(cobj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cacheobj_free ( struct cacheobj cobj) [static]

Definition at line 190 of file cache.c.

{
    av_unref_obj(cobj->obj);
    av_log(AVLOG_DEBUG, "got rid of cached object <%s> size %lli",
             cobj->name != NULL ? cobj->name : "?", cobj->diskusage);
    av_free(cobj->name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cacheobj_insert ( struct cacheobj cobj) [static]

Definition at line 177 of file cache.c.

{
    struct cacheobj *next;
    struct cacheobj *prev;

    next = cachelist.next;
    prev = &cachelist;
    next->prev = cobj;
    prev->next = cobj;
    cobj->next = next;
    cobj->prev = prev;
}

Here is the caller graph for this function:

static void cacheobj_internal_delete ( struct cacheobj cobj) [static]

This is the destructor for internal cacheobj's created using the V2 interface Because of possible race conditions the object can only by destroyed when holding the lock.

Definition at line 221 of file cache.c.

{
    if(cobj->obj != NULL) {
        cacheobj_remove(cobj);
        disk_usage -= cobj->diskusage;
    }

    AV_UNLOCK(cachelock);
    if(cobj->obj != NULL)
        cacheobj_free(cobj);
    AV_LOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cacheobj_remove ( struct cacheobj cobj) [static]

Definition at line 166 of file cache.c.

{
    struct cacheobj *next;
    struct cacheobj *prev;
    
    next = cobj->next;
    prev = cobj->prev;
    next->prev = prev;
    prev->next = next;
}

Here is the caller graph for this function:

static void destroy_cache ( ) [static]

This is the exit handler to remove all temporary file stored using the V2 interface.

Definition at line 120 of file cache.c.

{
    struct cacheobj *cobj;

    AV_LOCK(cachelock);
    for(cobj = &cachelist; cobj->next != &cachelist; ) {
        if(cobj->next->internal_obj) {
            /* unref the internal objects which will remove it */
            av_unref_obj(cobj->next);
        } else {
            /* this shouldn't happen, there shouldn't be
             * any external object left at exit */
            cobj = cobj->next;
        }
    }
    AV_UNLOCK(cachelock);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct cacheobj [static]

Definition at line 49 of file cache.c.

avoff_t disk_cache_limit = 100 * MBYTE [static]

Definition at line 50 of file cache.c.

avoff_t disk_keep_free = 10 * MBYTE [static]

Definition at line 51 of file cache.c.

avoff_t disk_usage = 0 [static]

Definition at line 52 of file cache.c.