Commit 2781d1a3 authored by Rich Prohaska's avatar Rich Prohaska

_put sets dirty=1, get_and_pin sets dirty=0 for fetched items

git-svn-id: file:///svn/tokudb@314 c7de825b-a66e-492c-adef-691d508d4ae1
parent 1328a05a
......@@ -275,10 +275,117 @@ void test_multi_filehandles (void) {
r = cachetable_close(&t); assert(r==0);
}
void test_dirty_flush(CACHEFILE f, CACHEKEY key, void *value, int write, int keep) {
printf("test_dirty_flush %p %lld %p %d %d\n", f, key, value, write, keep);
}
int test_dirty_fetch(CACHEFILE f, CACHEKEY key, void **value_ptr, void *arg) {
*value_ptr = arg;
printf("test_dirty_fetch %p %lld %p %p\n", f, key, *value_ptr, arg);
return 0;
}
void test_dirty() {
CACHETABLE t;
CACHEFILE f;
CACHEKEY key; void *value;
int dirty; long long pinned;
int r;
r = create_cachetable(&t, 4);
assert(r == 0);
char *fname = "test.dat";
unlink(fname);
r = cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777);
assert(r == 0);
key = 1; value = (void*)1;
r = cachetable_put(f, key, value, test_dirty_flush, 0, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 1);
assert(pinned == 1);
r = cachetable_unpin(f, key, 0);
assert(r == 0);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 1);
assert(pinned == 0);
r = cachetable_get_and_pin(f, key, &value, test_dirty_flush,
test_dirty_fetch, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 1);
assert(pinned == 1);
r = cachetable_unpin(f, key, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 1);
assert(pinned == 0);
key = 2;
r = cachetable_get_and_pin(f, key, &value, test_dirty_flush,
test_dirty_fetch, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 0);
assert(pinned == 1);
r = cachetable_unpin(f, key, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 0);
assert(pinned == 0);
r = cachetable_get_and_pin(f, key, &value, test_dirty_flush,
test_dirty_fetch, 0);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 0);
assert(pinned == 1);
r = cachetable_unpin(f, key, 1);
assert(r == 0);
// cachetable_print_state(t);
r = cachetable_get_state(t, key, &value, &dirty, &pinned);
assert(r == 0);
assert(dirty == 1);
assert(pinned == 0);
r = cachefile_close(&f);
assert(r == 0);
r = cachetable_close(&t);
assert(r == 0);
}
int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
test0();
test_nested_pin();
test_multi_filehandles ();
test_dirty();
malloc_cleanup();
printf("ok\n");
return 0;
......
#include "cachetable.h"
#include "memory.h"
#include "yerror.h"
......@@ -26,8 +27,8 @@ struct ctpair {
PAIR next,prev; // In LRU list.
PAIR hash_chain;
CACHEFILE cachefile;
void (*flush_callback)(CACHEFILE,CACHEKEY,void*, int write_me, int keep_me);
int (*fetch_callback)(CACHEFILE,CACHEKEY,void**,void*extrargs);
cachetable_flush_func_t flush_callback;
cachetable_fetch_func_t fetch_callback;
void*extraargs;
};
......@@ -59,12 +60,13 @@ void cachetable_print_state (CACHETABLE ct) {
PAIR p;
printf("t[%d]=", i);
for (p=ct->table[i]; p; p=p->hash_chain) {
printf(" {%lld, %p}", p->key, p->cachefile);
printf(" {%lld, %p, dirty=%d, pin=%lld}", p->key, p->cachefile, p->dirty, p->pinned);
}
printf("\n");
}
}
int create_cachetable (CACHETABLE *result, int n_entries) {
TAGMALLOC(CACHETABLE, t);
int i;
......@@ -269,31 +271,13 @@ static int maybe_flush_some (CACHETABLE t) {
return 0;
}
int cachetable_put (CACHEFILE cachefile, CACHEKEY key, void*value,
void (*flush_callback)(CACHEFILE,CACHEKEY,void*, int /*write_me*/, int /*keep_me*/),
int (*fetch_callback)(CACHEFILE,CACHEKEY,void**,void*/*extraargs*/),
void*extraargs
) {
int h = hashit(cachefile->cachetable, key);
WHEN_TRACE_CT(printf("%s:%d CT cachetable_put(%lld)=%p\n", __FILE__, __LINE__, key, value));
{
PAIR p;
for (p=cachefile->cachetable->table[h]; p; p=p->hash_chain) {
if (p->key==key && p->cachefile==cachefile) {
// Semantically, these two asserts are not strictly right. After all, when are two functions eq?
// In practice, the functions better be the same.
assert(p->flush_callback==flush_callback);
assert(p->fetch_callback==fetch_callback);
return -1; /* Already present. */
}
}
}
if (maybe_flush_some(cachefile->cachetable)) return -2;
{
static int cachetable_insert_at(CACHEFILE cachefile, int h, CACHEKEY key, void *value,
cachetable_flush_func_t flush_callback,
cachetable_fetch_func_t fetch_callback,
void *extraargs, int dirty) {
TAGMALLOC(PAIR, p);
p->pinned=1;
p->dirty =1;
p->pinned = 1;
p->dirty = dirty;
//printf("%s:%d p=%p dirty=%d\n", __FILE__, __LINE__, p, p->dirty);
p->key = key;
p->value = value;
......@@ -307,14 +291,31 @@ int cachetable_put (CACHEFILE cachefile, CACHEKEY key, void*value,
cachefile->cachetable->table[h] = p;
cachefile->cachetable->n_in_table++;
return 0;
}
int cachetable_put (CACHEFILE cachefile, CACHEKEY key, void*value,
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) {
int h = hashit(cachefile->cachetable, key);
WHEN_TRACE_CT(printf("%s:%d CT cachetable_put(%lld)=%p\n", __FILE__, __LINE__, key, value));
{
PAIR p;
for (p=cachefile->cachetable->table[h]; p; p=p->hash_chain) {
if (p->key==key && p->cachefile==cachefile) {
// Semantically, these two asserts are not strictly right. After all, when are two functions eq?
// In practice, the functions better be the same.
assert(p->flush_callback==flush_callback);
assert(p->fetch_callback==fetch_callback);
return -1; /* Already present. */
}
}
}
if (maybe_flush_some(cachefile->cachetable))
return -2;
return cachetable_insert_at(cachefile, h, key, value, flush_callback, fetch_callback, extraargs, 1);
}
int cachetable_get_and_pin (CACHEFILE cachefile, CACHEKEY key, void**value,
void(*flush_callback)(CACHEFILE,CACHEKEY,void*,int write_me, int keep_me),
int(*fetch_callback)(CACHEFILE, CACHEKEY key, void**value,void*extraargs), /* If we are asked to fetch something, get it by calling this back. */
void*extraargs
) {
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) {
CACHETABLE t = cachefile->cachetable;
int h = hashit(t,key);
PAIR p;
......@@ -333,7 +334,7 @@ int cachetable_get_and_pin (CACHEFILE cachefile, CACHEKEY key, void**value,
int r;
WHEN_TRACE_CT(printf("%s:%d CT: fetch_callback(%lld...)\n", __FILE__, __LINE__, key));
if ((r=fetch_callback(cachefile, key, &toku_value,extraargs))) return r;
cachetable_put(cachefile, key, toku_value, flush_callback, fetch_callback,extraargs);
cachetable_insert_at(cachefile, h, key, toku_value, flush_callback, fetch_callback, extraargs, 0);
*value = toku_value;
}
WHEN_TRACE_CT(printf("%s:%d did fetch: cachtable_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value));
......@@ -494,3 +495,19 @@ int cachefile_pread (CACHEFILE cf, void *buf, size_t count, off_t offset) {
int cachefile_fd (CACHEFILE cf) {
return cf->fd;
}
/* debug function */
int cachetable_get_state(CACHETABLE ct, CACHEKEY key, void **value_ptr,
int *dirty_ptr, long long *pin_ptr) {
int h = hashit(ct, key);
PAIR p;
for (p = ct->table[h]; p; p = p->hash_chain) {
if (p->key == key) {
*value_ptr = p->value;
*dirty_ptr = p->dirty;
*pin_ptr = p->pinned;
return 0;
}
}
return 1;
}
......@@ -24,18 +24,17 @@ int create_cachetable (CACHETABLE */*result*/, int /*n_entries*/);
int cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname*/, int flags, mode_t mode);
typedef void (*cachetable_flush_func_t)(CACHEFILE, CACHEKEY key, void*value, int write_me, int keep_me);
/* If we are asked to fetch something, get it by calling this back. */
typedef int (*cachetable_fetch_func_t)(CACHEFILE, CACHEKEY key, void**value,void*extraargs);
/* Error if already present. On success, pin the value. */
int cachetable_put (CACHEFILE, CACHEKEY, void*/*value*/,
void(*flush_callback)(CACHEFILE, CACHEKEY key, void*value, int write_me, int keep_me),
int(*fetch_callback)(CACHEFILE, CACHEKEY key, void**value,void*extraargs), /* If we are asked to fetch something, get it by calling this back. */
void*extraargs
);
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs);
int cachetable_get_and_pin (CACHEFILE, CACHEKEY, void**/*value*/,
void(*flush_callback)(CACHEFILE,CACHEKEY,void*,int write_me, int keep_me),
int(*fetch_callback)(CACHEFILE, CACHEKEY key, void**value,void*extraargs), /* If we are asked to fetch something, get it by calling this back. */
void*extraargs
);
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs);
/* If the the item is already in memory, then return 0 and store it in the void**.
* If the item is not in memory, then return nonzero. */
......@@ -59,5 +58,6 @@ int cachefile_fd (CACHEFILE);
// Useful for debugging
void cachetable_print_state (CACHETABLE ct);
int cachetable_get_state(CACHETABLE ct, CACHEKEY key, void **value_ptr,
int *dirty_ptr, long long *pin_ptr);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment