178 lines
4.6 KiB
C
178 lines
4.6 KiB
C
/*
|
|
Copyright (C) 2004,2005 Wolfgang Hottgenroth
|
|
|
|
This file is part of smmapdfw.
|
|
|
|
smmapdfw is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
smmapdfw is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with smmapdfw. If not, write to the Free Software Foundation, 59
|
|
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
#if HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <syslog.h>
|
|
#include <pthread.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
|
|
#if ENABLE_CACHE == 1
|
|
#define DB_DBM_HSEARCH 1
|
|
#include <db.h>
|
|
#endif
|
|
|
|
#include "htcache.h"
|
|
#include "htmalloc.h"
|
|
|
|
struct mydata_s {
|
|
time_t timestamp;
|
|
int value_size;
|
|
char value[1];
|
|
};
|
|
|
|
typedef struct mydata_s mydata_t;
|
|
|
|
|
|
|
|
htcache_t *htcache_init(const char *file, int expiry) {
|
|
#if ENABLE_CACHE == 1
|
|
htcache_t *handle = (htcache_t*) htmalloc(sizeof(htcache_t));
|
|
handle->mutex = (pthread_mutex_t*) htmalloc(sizeof(pthread_mutex_t));
|
|
pthread_mutex_init(handle->mutex, NULL);
|
|
pthread_mutex_unlock(handle->mutex);
|
|
handle->file = file;
|
|
handle->expiry = expiry;
|
|
|
|
return handle;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
void htcache_destroy(htcache_t *handle) {
|
|
#if ENABLE_CACHE == 1
|
|
pthread_mutex_destroy(handle->mutex);
|
|
free(handle->mutex);
|
|
free(handle);
|
|
#endif
|
|
}
|
|
|
|
void htcache_insert(htcache_t *handle, const char *key, const char *value, int value_size) {
|
|
#if ENABLE_CACHE == 1
|
|
DBM *cache;
|
|
datum data, dkey;
|
|
int ret;
|
|
mydata_t *mydata;
|
|
|
|
syslog(LOG_DEBUG, "cache_insert: inserting %s -> %s (size %d)", key, (char*) value, value_size);
|
|
dkey.dsize = strlen(key) + 1; /* one more for the terminating \0 */
|
|
dkey.dptr = (char*) key;
|
|
data.dsize = (sizeof(mydata_t) + value_size + 1);
|
|
mydata = (mydata_t *) htmalloc(data.dsize);
|
|
mydata->timestamp = time(NULL);
|
|
mydata->value_size = value_size;
|
|
memcpy(mydata->value, value, value_size);
|
|
data.dptr = (char*) mydata;
|
|
|
|
pthread_mutex_lock(handle->mutex);
|
|
if (NULL != (cache = dbm_open(handle->file, O_RDWR | O_CREAT, 0644))) {
|
|
ret = dbm_store(cache, dkey, data, DBM_INSERT);
|
|
if (ret != 0) {
|
|
syslog(LOG_DEBUG, "cache_insert: couldn't insert record");
|
|
} else {
|
|
syslog(LOG_DEBUG, "cache_insert: record inserted");
|
|
}
|
|
dbm_close(cache);
|
|
}
|
|
pthread_mutex_unlock(handle->mutex);
|
|
|
|
free(mydata);
|
|
#else
|
|
syslog(LOG_DEBUG, "cache_insert: cache disabled");
|
|
#endif /* ENABLE_CACHE */
|
|
}
|
|
|
|
|
|
int htcache_lookup(htcache_t *handle, const char* key, char** value, int* value_size2) {
|
|
#if ENABLE_CACHE == 1
|
|
DBM *cache;
|
|
datum data, dkey;
|
|
char *output;
|
|
mydata_t *mydata;
|
|
int value_size, ret, res = -1;
|
|
|
|
syslog(LOG_DEBUG, "cache_lookup: looking up %s, expiry %d",
|
|
key, handle->expiry);
|
|
|
|
if (NULL != (cache = dbm_open(handle->file, O_RDONLY, 0644))) {
|
|
dkey.dsize = strlen(key) + 1; /* one more for the terminating \0 */
|
|
dkey.dptr = (char*) key;
|
|
data = dbm_fetch(cache, dkey);
|
|
if (NULL == data.dptr) {
|
|
syslog(LOG_DEBUG, "cache_lookup: nothing found");
|
|
dbm_close(cache);
|
|
} else {
|
|
mydata = (mydata_t *) data.dptr;
|
|
syslog(LOG_DEBUG, "cache_lookup: found: %s %d %d %s (size %d)",
|
|
key, mydata->timestamp, mydata->value_size, mydata->value, data.dsize);
|
|
if ((mydata->timestamp + handle->expiry) > time(NULL)) {
|
|
syslog(LOG_DEBUG, "cache_lookup: not yet expired");
|
|
value_size = mydata->value_size;
|
|
output = (char*) htmalloc(value_size+5);
|
|
memcpy(output, mydata->value, value_size);
|
|
|
|
*value_size2 = value_size;
|
|
*value = output;
|
|
|
|
/* Berkeley DB frees on its own! */
|
|
/* free(data.dptr); */
|
|
dbm_close(cache);
|
|
res = 0;
|
|
} else {
|
|
syslog(LOG_DEBUG, "cache_lookup: expired, will be deleted from cache");
|
|
/* free(data.dptr); --- Berkeley DB frees on its own */
|
|
dbm_close(cache);
|
|
|
|
pthread_mutex_lock(handle->mutex);
|
|
if (NULL != (cache = dbm_open(handle->file, O_RDWR, 0644))) {
|
|
ret = dbm_delete(cache, dkey);
|
|
if (ret != 0) {
|
|
syslog(LOG_DEBUG, "cache_insert: couldn't delete record");
|
|
} else {
|
|
syslog(LOG_DEBUG, "cache_insert: record deleted");
|
|
}
|
|
dbm_close(cache);
|
|
res = -2;
|
|
}
|
|
pthread_mutex_unlock(handle->mutex);
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
#else
|
|
return -1;
|
|
#endif /* ENABLE_CACHE */
|
|
}
|
|
|
|
|
|
|