Added bf_read2 / bf_write2 which does not call exit for errors.
-/* $Id: bfile.c,v 1.50 2006-10-10 10:19:28 adam Exp $
+/* $Id: bfile.c,v 1.51 2006-11-08 22:08:27 adam Exp $
Copyright (C) 1995-2006
Index Data ApS
BFiles bfs_create (const char *spec, const char *base)
{
- BFiles bfs = (BFiles) xmalloc (sizeof(*bfs));
- bfs->commit_area = NULL;
+ BFiles bfs = (BFiles) xmalloc(sizeof(*bfs));
+ bfs->commit_area = 0;
bfs->base = 0;
bfs->cache_fname = 0;
if (base)
- bfs->base = xstrdup (base);
+ bfs->base = xstrdup(base);
bfs->register_area = mf_init("register", spec, base);
if (!bfs->register_area)
{
return bfs;
}
-void bfs_destroy (BFiles bfs)
+void bfs_destroy(BFiles bfs)
{
if (!bfs)
return;
- xfree (bfs->cache_fname);
- xfree (bfs->base);
- mf_destroy (bfs->commit_area);
- mf_destroy (bfs->register_area);
- xfree (bfs);
+ xfree(bfs->cache_fname);
+ xfree(bfs->base);
+ mf_destroy(bfs->commit_area);
+ mf_destroy(bfs->register_area);
+ xfree(bfs);
}
-static FILE *open_cache (BFiles bfs, const char *flags)
+static FILE *open_cache(BFiles bfs, const char *flags)
{
FILE *file;
- file = fopen (bfs->cache_fname, flags);
+ file = fopen(bfs->cache_fname, flags);
return file;
}
-static void unlink_cache (BFiles bfs)
+static void unlink_cache(BFiles bfs)
{
- unlink (bfs->cache_fname);
+ unlink(bfs->cache_fname);
}
-ZEBRA_RES bf_cache (BFiles bfs, const char *spec)
+ZEBRA_RES bf_cache(BFiles bfs, const char *spec)
{
if (spec)
{
- yaz_log (YLOG_LOG, "enabling shadow spec=%s", spec);
+ yaz_log(YLOG_LOG, "enabling shadow spec=%s", spec);
if (!bfs->commit_area)
- bfs->commit_area = mf_init ("shadow", spec, bfs->base);
+ bfs->commit_area = mf_init("shadow", spec, bfs->base);
if (bfs->commit_area)
{
- bfs->cache_fname = xmalloc (strlen(bfs->commit_area->dirs->name)+
+ bfs->cache_fname = xmalloc(strlen(bfs->commit_area->dirs->name)+
8);
- strcpy (bfs->cache_fname, bfs->commit_area->dirs->name);
- strcat (bfs->cache_fname, "/cache");
- yaz_log (YLOG_LOG, "cache_fname = %s", bfs->cache_fname);
+ strcpy(bfs->cache_fname, bfs->commit_area->dirs->name);
+ strcat(bfs->cache_fname, "/cache");
+ yaz_log(YLOG_LOG, "cache_fname = %s", bfs->cache_fname);
}
else
{
}
}
else
- bfs->commit_area = NULL;
+ bfs->commit_area = 0;
return ZEBRA_OK;
}
-int bf_close (BFile bf)
+int bf_close(BFile bf)
{
- zebra_lock_rdwr_destroy (&bf->rdwr_lock);
+ zebra_lock_rdwr_destroy(&bf->rdwr_lock);
if (bf->cf)
- cf_close (bf->cf);
- mf_close (bf->mf);
+ cf_close(bf->cf);
+ if (bf->mf)
+ mf_close(bf->mf);
xfree(bf->alloc_buf);
xfree(bf->magic);
xfree(bf);
return bf;
}
-int bf_xclose (BFile bf, int version, const char *more_info)
+int bf_xclose(BFile bf, int version, const char *more_info)
{
if (bf->header_dirty)
{
return bf_close(bf);
}
-BFile bf_open (BFiles bfs, const char *name, int block_size, int wflag)
+BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
{
- BFile bf = (BFile) xmalloc(sizeof(struct BFile_struct));
+ BFile bf = (BFile) xmalloc(sizeof(*bf));
bf->alloc_buf = 0;
bf->magic = 0;
bf->block_size = block_size;
bf->header_dirty = 0;
+ bf->cf = 0;
+ bf->mf = 0;
+ zebra_lock_rdwr_init(&bf->rdwr_lock);
+
if (bfs->commit_area)
{
int first_time;
- bf->mf = mf_open (bfs->register_area, name, block_size, 0);
- bf->cf = cf_open (bf->mf, bfs->commit_area, name, block_size,
- wflag, &first_time);
+ bf->mf = mf_open(bfs->register_area, name, block_size, 0);
+ bf->cf = cf_open(bf->mf, bfs->commit_area, name, block_size,
+ wflag, &first_time);
+ if (!bf->cf)
+ {
+ yaz_log(YLOG_FATAL, "cf_open failed for %s", name);
+ bf_close(bf);
+ return 0;
+ }
if (first_time)
{
FILE *outf;
if (!outf)
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", bfs->cache_fname);
- exit(1);
+ bf_close(bf);
+ return 0;
}
fprintf(outf, "%s %d\n", name, block_size);
- fclose(outf);
+ if (fclose(outf))
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "fclose %s", bfs->cache_fname);
+ bf_close(bf);
+ return 0;
+ }
}
}
else
{
bf->mf = mf_open(bfs->register_area, name, block_size, wflag);
- bf->cf = NULL;
}
if (!bf->mf)
{
yaz_log(YLOG_FATAL, "mf_open failed for %s", name);
- xfree(bf);
+ bf_close(bf);
return 0;
}
- zebra_lock_rdwr_init(&bf->rdwr_lock);
return bf;
}
-int bf_read (BFile bf, zint no, int offset, int nbytes, void *buf)
+int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
{
- int r;
+ int ret = bf_read2(bf, no, offset, nbytes, buf);
- zebra_lock_rdwr_rlock (&bf->rdwr_lock);
+ if (ret == -1)
+ {
+ exit(1);
+ }
+ return ret;
+}
+
+int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf)
+{
+ int ret;
+
+ zebra_lock_rdwr_rlock(&bf->rdwr_lock);
if (bf->cf)
{
- if ((r = cf_read (bf->cf, no, offset, nbytes, buf)) == -1)
- r = mf_read (bf->mf, no, offset, nbytes, buf);
+ if ((ret = cf_read(bf->cf, no, offset, nbytes, buf)) == 0)
+ ret = mf_read(bf->mf, no, offset, nbytes, buf);
}
else
- r = mf_read (bf->mf, no, offset, nbytes, buf);
- zebra_lock_rdwr_runlock (&bf->rdwr_lock);
- return r;
+ ret = mf_read(bf->mf, no, offset, nbytes, buf);
+ zebra_lock_rdwr_runlock(&bf->rdwr_lock);
+ return ret;
+}
+
+int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
+{
+ int ret = bf_write2(bf, no, offset, nbytes, buf);
+
+ if (ret == -1)
+ {
+ exit(1);
+ }
+ return ret;
}
-int bf_write (BFile bf, zint no, int offset, int nbytes, const void *buf)
+int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf)
{
int r;
- zebra_lock_rdwr_wlock (&bf->rdwr_lock);
+ zebra_lock_rdwr_wlock(&bf->rdwr_lock);
if (bf->cf)
- r = cf_write (bf->cf, no, offset, nbytes, buf);
+ r = cf_write(bf->cf, no, offset, nbytes, buf);
else
- r = mf_write (bf->mf, no, offset, nbytes, buf);
- zebra_lock_rdwr_wunlock (&bf->rdwr_lock);
+ r = mf_write(bf->mf, no, offset, nbytes, buf);
+ zebra_lock_rdwr_wunlock(&bf->rdwr_lock);
return r;
}
-int bf_commitExists (BFiles bfs)
+int bf_commitExists(BFiles bfs)
{
FILE *inf;
- inf = open_cache (bfs, "rb");
+ inf = open_cache(bfs, "rb");
if (inf)
{
- fclose (inf);
+ fclose(inf);
return 1;
}
return 0;
}
-void bf_reset (BFiles bfs)
+void bf_reset(BFiles bfs)
{
if (!bfs)
return;
mf_reset(bfs->commit_area, 1);
mf_reset(bfs->register_area, 1);
+ unlink_cache(bfs);
}
-void bf_commitExec (BFiles bfs)
+void bf_commitExec(BFiles bfs)
{
FILE *inf;
int block_size;
CFile cf;
int first_time;
- assert (bfs->commit_area);
- if (!(inf = open_cache (bfs, "rb")))
+ assert(bfs->commit_area);
+ if (!(inf = open_cache(bfs, "rb")))
{
- yaz_log (YLOG_LOG, "No commit file");
+ yaz_log(YLOG_LOG, "No commit file");
return ;
}
- while (fscanf (inf, "%s %d", path, &block_size) == 2)
+ while (fscanf(inf, "%s %d", path, &block_size) == 2)
{
- mf = mf_open (bfs->register_area, path, block_size, 1);
- cf = cf_open (mf, bfs->commit_area, path, block_size, 0, &first_time);
+ mf = mf_open(bfs->register_area, path, block_size, 1);
+ cf = cf_open(mf, bfs->commit_area, path, block_size, 0, &first_time);
- cf_commit (cf);
+ cf_commit(cf);
- cf_close (cf);
- mf_close (mf);
+ cf_close(cf);
+ mf_close(mf);
}
- fclose (inf);
+ fclose(inf);
}
-void bf_commitClean (BFiles bfs, const char *spec)
+void bf_commitClean(BFiles bfs, const char *spec)
{
int mustDisable = 0;
if (!bfs->commit_area)
{
- bf_cache (bfs, spec);
+ bf_cache(bfs, spec);
mustDisable = 1;
}
mf_reset(bfs->commit_area, 1);
- unlink_cache (bfs);
+ unlink_cache(bfs);
if (mustDisable)
- bf_cache (bfs, 0);
+ bf_cache(bfs, 0);
}
int bf_alloc(BFile bf, int no, zint *blocks)
-/* $Id: cfile.c,v 1.37 2006-08-14 10:40:05 adam Exp $
+/* $Id: cfile.c,v 1.38 2006-11-08 22:08:27 adam Exp $
Copyright (C) 1995-2006
Index Data ApS
#include "mfile.h"
#include "cfile.h"
-static int write_head (CFile cf)
+static int write_head(CFile cf)
{
int left = cf->head.hash_size * sizeof(zint);
int bno = 1;
+ int r = 0;
const char *tab = (char*) cf->array;
if (!tab)
return 0;
while (left >= (int) HASH_BSIZE)
{
- mf_write (cf->hash_mf, bno++, 0, 0, tab);
+ r = mf_write(cf->hash_mf, bno++, 0, 0, tab);
+ if (r)
+ return r;
tab += HASH_BSIZE;
left -= HASH_BSIZE;
}
if (left > 0)
- mf_write (cf->hash_mf, bno, 0, left, tab);
- return 0;
+ r = mf_write(cf->hash_mf, bno, 0, left, tab);
+ return r;
}
-static int read_head (CFile cf)
+static int read_head(CFile cf)
{
int left = cf->head.hash_size * sizeof(zint);
int bno = 1;
return 0;
while (left >= (int) HASH_BSIZE)
{
- mf_read (cf->hash_mf, bno++, 0, 0, tab);
+ if (mf_read(cf->hash_mf, bno++, 0, 0, tab) == -1)
+ return -1;
tab += HASH_BSIZE;
left -= HASH_BSIZE;
}
if (left > 0)
- mf_read (cf->hash_mf, bno, 0, left, tab);
- return 0;
+ {
+ if (mf_read(cf->hash_mf, bno, 0, left, tab) == -1)
+ return -1;
+ }
+ return 1;
}
-CFile cf_open (MFile mf, MFile_area area, const char *fname,
- int block_size, int wflag, int *firstp)
+CFile cf_open(MFile mf, MFile_area area, const char *fname,
+ int block_size, int wflag, int *firstp)
{
char path[1024];
- int i;
- CFile cf = (CFile) xmalloc (sizeof(*cf));
+ int i, ret;
+ CFile cf = (CFile) xmalloc(sizeof(*cf));
int hash_bytes;
+
+ yaz_log(YLOG_DEBUG, "cf: open %s %s", cf->rmf->name,
+ wflag ? "rdwr" : "rd");
+ cf->block_mf = 0;
+ cf->hash_mf = 0;
cf->rmf = mf;
- yaz_log (YLOG_DEBUG, "cf: open %s %s", cf->rmf->name, wflag ? "rdwr" : "rd");
- sprintf (path, "%s-b", fname);
- if (!(cf->block_mf = mf_open (area, path, block_size, wflag)))
+
+ assert(firstp);
+
+ cf->bucket_lru_front = cf->bucket_lru_back = NULL;
+ cf->bucket_in_memory = 0;
+ cf->max_bucket_in_memory = 100;
+ cf->dirty = 0;
+ cf->iobuf = (char *) xmalloc(block_size);
+ memset(cf->iobuf, 0, block_size);
+ cf->no_hits = 0;
+ cf->no_miss = 0;
+ cf->parray = 0;
+ cf->array = 0;
+ cf->block_mf = 0;
+ cf->hash_mf = 0;
+
+ zebra_mutex_init(&cf->mutex);
+
+ sprintf(path, "%s-b", fname);
+ if (!(cf->block_mf = mf_open(area, path, block_size, wflag)))
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path);
- exit (1);
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path);
+ cf_close(cf);
+ return 0;
}
- sprintf (path, "%s-i", fname);
- if (!(cf->hash_mf = mf_open (area, path, HASH_BSIZE, wflag)))
+ sprintf(path, "%s-i", fname);
+ if (!(cf->hash_mf = mf_open(area, path, HASH_BSIZE, wflag)))
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path);
- exit (1);
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to open %s", path);
+ cf_close(cf);
+ return 0;
}
- assert (firstp);
- if (!mf_read (cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head) ||
- !cf->head.state)
+ ret = mf_read(cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head);
+
+ if (ret == -1)
+ {
+ cf_close(cf);
+ return 0;
+ }
+ if (ret == 0 || !cf->head.state)
{
*firstp = 1;
cf->head.state = 1;
cf->head.flat_bucket = cf->head.next_bucket = cf->head.first_bucket =
(hash_bytes+sizeof(cf->head))/HASH_BSIZE + 2;
cf->head.next_block = 1;
- if (wflag)
- mf_write (cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head);
- cf->array = (zint *) xmalloc (hash_bytes);
+ cf->array = (zint *) xmalloc(hash_bytes);
for (i = 0; i<cf->head.hash_size; i++)
cf->array[i] = 0;
if (wflag)
- write_head (cf);
+ {
+ if (mf_write(cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head))
+ {
+ cf_close(cf);
+ return 0;
+ }
+ if (write_head(cf))
+ {
+ cf_close(cf);
+ return 0;
+ }
+ }
}
else
{
*firstp = 0;
- assert (cf->head.block_size == block_size);
- assert (cf->head.hash_size > 2);
+ assert(cf->head.block_size == block_size);
+ assert(cf->head.hash_size > 2);
hash_bytes = cf->head.hash_size * sizeof(zint);
- assert (cf->head.next_bucket > 0);
- assert (cf->head.next_block > 0);
+ assert(cf->head.next_bucket > 0);
+ assert(cf->head.next_block > 0);
if (cf->head.state == 1)
- cf->array = (zint *) xmalloc (hash_bytes);
+ cf->array = (zint *) xmalloc(hash_bytes);
else
cf->array = NULL;
- read_head (cf);
+ if (read_head(cf) == -1)
+ {
+ cf_close(cf);
+ return 0;
+ }
}
if (cf->head.state == 1)
{
cf->parray = (struct CFile_hash_bucket **)
- xmalloc (cf->head.hash_size * sizeof(*cf->parray));
+ xmalloc(cf->head.hash_size * sizeof(*cf->parray));
for (i = 0; i<cf->head.hash_size; i++)
cf->parray[i] = NULL;
}
- else
- cf->parray = NULL;
- cf->bucket_lru_front = cf->bucket_lru_back = NULL;
- cf->bucket_in_memory = 0;
- cf->max_bucket_in_memory = 100;
- cf->dirty = 0;
- cf->iobuf = (char *) xmalloc (cf->head.block_size);
- memset (cf->iobuf, 0, cf->head.block_size);
- cf->no_hits = 0;
- cf->no_miss = 0;
- zebra_mutex_init (&cf->mutex);
return cf;
}
-static int cf_hash (CFile cf, zint no)
+static int cf_hash(CFile cf, zint no)
{
return (int) (((no >> 3) % cf->head.hash_size));
}
-static void release_bucket (CFile cf, struct CFile_hash_bucket *p)
+static void release_bucket(CFile cf, struct CFile_hash_bucket *p)
{
if (p->lru_prev)
p->lru_prev->lru_next = p->lru_next;
p->h_next->h_prev = p->h_prev;
--(cf->bucket_in_memory);
- xfree (p);
+ xfree(p);
}
-static void flush_bucket (CFile cf, int no_to_flush)
+static void flush_bucket(CFile cf, int no_to_flush)
{
int i;
struct CFile_hash_bucket *p;
break;
if (p->dirty)
{
- mf_write (cf->hash_mf, p->ph.this_bucket, 0, 0, &p->ph);
+ mf_write(cf->hash_mf, p->ph.this_bucket, 0, 0, &p->ph);
cf->dirty = 1;
}
- release_bucket (cf, p);
+ release_bucket(cf, p);
}
}
-static struct CFile_hash_bucket *alloc_bucket (CFile cf, zint block_no, int hno)
+static struct CFile_hash_bucket *alloc_bucket(CFile cf, zint block_no, int hno)
{
struct CFile_hash_bucket *p, **pp;
if (cf->bucket_in_memory == cf->max_bucket_in_memory)
- flush_bucket (cf, 1);
- assert (cf->bucket_in_memory < cf->max_bucket_in_memory);
+ flush_bucket(cf, 1);
+ assert(cf->bucket_in_memory < cf->max_bucket_in_memory);
++(cf->bucket_in_memory);
- p = (struct CFile_hash_bucket *) xmalloc (sizeof(*p));
+ p = (struct CFile_hash_bucket *) xmalloc(sizeof(*p));
p->lru_next = NULL;
p->lru_prev = cf->bucket_lru_front;
return p;
}
-static struct CFile_hash_bucket *get_bucket (CFile cf, zint block_no, int hno)
+static struct CFile_hash_bucket *get_bucket(CFile cf, zint block_no, int hno)
{
struct CFile_hash_bucket *p;
- p = alloc_bucket (cf, block_no, hno);
- if (!mf_read (cf->hash_mf, block_no, 0, 0, &p->ph))
+ p = alloc_bucket(cf, block_no, hno);
+ p->dirty = 0;
+ if (!mf_read(cf->hash_mf, block_no, 0, 0, &p->ph))
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "read get_bucket");
- exit (1);
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "read get_bucket");
+ release_bucket(cf, p);
+ return 0;
}
- assert (p->ph.this_bucket == block_no);
- p->dirty = 0;
+ assert(p->ph.this_bucket == block_no);
return p;
}
-static struct CFile_hash_bucket *new_bucket (CFile cf, zint *block_nop, int hno)
+static struct CFile_hash_bucket *new_bucket(CFile cf, zint *block_nop, int hno)
{
struct CFile_hash_bucket *p;
int i;
zint block_no;
block_no = *block_nop = cf->head.next_bucket++;
- p = alloc_bucket (cf, block_no, hno);
+ p = alloc_bucket(cf, block_no, hno);
+ p->dirty = 1;
for (i = 0; i<HASH_BUCKET; i++)
{
}
p->ph.next_bucket = 0;
p->ph.this_bucket = block_no;
- p->dirty = 1;
return p;
}
-static zint cf_lookup_flat (CFile cf, zint no)
+static int cf_lookup_flat(CFile cf, zint no, zint *vno)
{
zint hno = (no*sizeof(zint))/HASH_BSIZE;
int off = (int) ((no*sizeof(zint)) - hno*HASH_BSIZE);
- zint vno = 0;
- mf_read (cf->hash_mf, hno+cf->head.next_bucket, off, sizeof(zint), &vno);
- return vno;
+ *vno = 0;
+ mf_read(cf->hash_mf, hno+cf->head.next_bucket, off, sizeof(zint), vno);
+ if (*vno)
+ return 1;
+ return 0;
}
-static zint cf_lookup_hash (CFile cf, zint no)
+static int cf_lookup_hash(CFile cf, zint no, zint *vno)
{
- int hno = cf_hash (cf, no);
+ int hno = cf_hash(cf, no);
struct CFile_hash_bucket *hb;
zint block_no;
int i;
if (hb->ph.no[i] == no)
{
(cf->no_hits)++;
- return hb->ph.vno[i];
+ *vno = hb->ph.vno[i];
+ return 1;
}
}
for (block_no = cf->array[hno]; block_no; block_no = hb->ph.next_bucket)
{
if (hb->ph.this_bucket == block_no)
{
- yaz_log (YLOG_FATAL, "Found hash bucket on other chain (1)");
- abort ();
+ yaz_log(YLOG_FATAL, "Found hash bucket on other chain(1)");
+ abort();
}
for (i = 0; i<HASH_BUCKET && hb->ph.vno[i]; i++)
if (hb->ph.no[i] == no)
{
- yaz_log (YLOG_FATAL, "Found hash bucket on other chain (2)");
- abort ();
+ yaz_log(YLOG_FATAL, "Found hash bucket on other chain (2)");
+ abort();
}
}
#endif
(cf->no_miss)++;
- hb = get_bucket (cf, block_no, hno);
+ hb = get_bucket(cf, block_no, hno);
+ if (!hb)
+ return -1;
for (i = 0; i<HASH_BUCKET && hb->ph.vno[i]; i++)
if (hb->ph.no[i] == no)
- return hb->ph.vno[i];
+ {
+ *vno = hb->ph.vno[i];
+ return 1;
+ }
}
return 0;
}
-static void cf_write_flat (CFile cf, zint no, zint vno)
+static int cf_write_flat(CFile cf, zint no, zint vno)
{
zint hno = (no*sizeof(zint))/HASH_BSIZE;
int off = (int) ((no*sizeof(zint)) - hno*HASH_BSIZE);
if (hno >= cf->head.flat_bucket)
cf->head.flat_bucket = hno+1;
cf->dirty = 1;
- mf_write (cf->hash_mf, hno, off, sizeof(zint), &vno);
+ return mf_write(cf->hash_mf, hno, off, sizeof(zint), &vno);
}
-static void cf_moveto_flat (CFile cf)
+static int cf_moveto_flat(CFile cf)
{
struct CFile_hash_bucket *p;
int j;
zint i;
- yaz_log (YLOG_DEBUG, "cf: Moving to flat shadow: %s", cf->rmf->name);
- yaz_log (YLOG_DEBUG, "cf: hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT " total="
+ yaz_log(YLOG_LOG, "cf: Moving to flat shadow: %s", cf->rmf->name);
+ yaz_log(YLOG_DEBUG, "cf: Moving to flat shadow: %s", cf->rmf->name);
+ yaz_log(YLOG_DEBUG, "cf: hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT " total="
ZINT_FORMAT,
cf->no_hits, cf->no_miss, cf->bucket_in_memory,
cf->head.next_bucket - cf->head.first_bucket);
- assert (cf->head.state == 1);
- flush_bucket (cf, -1);
- assert (cf->bucket_in_memory == 0);
- p = (struct CFile_hash_bucket *) xmalloc (sizeof(*p));
+ assert(cf->head.state == 1);
+ flush_bucket(cf, -1);
+ assert(cf->bucket_in_memory == 0);
+ p = (struct CFile_hash_bucket *) xmalloc(sizeof(*p));
for (i = cf->head.first_bucket; i < cf->head.next_bucket; i++)
{
- if (!mf_read (cf->hash_mf, i, 0, 0, &p->ph))
+ if (mf_read(cf->hash_mf, i, 0, 0, &p->ph) != 1)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "read bucket moveto flat");
- exit (1);
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "read bucket moveto flat");
+ xfree(p);
+ return -1;
}
for (j = 0; j < HASH_BUCKET && p->ph.vno[j]; j++)
- cf_write_flat (cf, p->ph.no[j], p->ph.vno[j]);
+ {
+ if (cf_write_flat(cf, p->ph.no[j], p->ph.vno[j]))
+ {
+ xfree(p);
+ return -1;
+ }
+ }
}
- xfree (p);
- xfree (cf->array);
+ xfree(p);
+ xfree(cf->array);
cf->array = NULL;
- xfree (cf->parray);
+ xfree(cf->parray);
cf->parray = NULL;
cf->head.state = 2;
cf->dirty = 1;
+ return 0;
}
-static zint cf_lookup (CFile cf, zint no)
+static int cf_lookup(CFile cf, zint no, zint *vno)
{
if (cf->head.state > 1)
- return cf_lookup_flat (cf, no);
- return cf_lookup_hash (cf, no);
+ return cf_lookup_flat(cf, no, vno);
+ return cf_lookup_hash(cf, no, vno);
}
-static zint cf_new_flat (CFile cf, zint no)
+static zint cf_new_flat(CFile cf, zint no)
{
zint vno = (cf->head.next_block)++;
- cf_write_flat (cf, no, vno);
+ cf_write_flat(cf, no, vno);
return vno;
}
-static zint cf_new_hash (CFile cf, zint no)
+static zint cf_new_hash(CFile cf, zint no)
{
- int hno = cf_hash (cf, no);
+ int hno = cf_hash(cf, no);
struct CFile_hash_bucket *hbprev = NULL, *hb = cf->parray[hno];
zint *bucketpp = &cf->array[hno];
int i;
{
if (hb->ph.this_bucket == *bucketpp)
{
- yaz_log (YLOG_FATAL, "Found hash bucket on other chain");
- abort ();
+ yaz_log(YLOG_FATAL, "Found hash bucket on other chain");
+ abort();
}
}
#endif
(cf->no_miss)++;
- hb = get_bucket (cf, *bucketpp, hno);
- assert (hb);
+ hb = get_bucket(cf, *bucketpp, hno);
+ if (!hb)
+ return 0;
for (i = 0; i<HASH_BUCKET; i++)
if (!hb->ph.vno[i])
{
}
if (hbprev)
hbprev->dirty = 1;
- hb = new_bucket (cf, bucketpp, hno);
+ hb = new_bucket(cf, bucketpp, hno);
hb->ph.no[0] = no;
hb->ph.vno[0] = vno;
return vno;
}
-zint cf_new (CFile cf, zint no)
+zint cf_new(CFile cf, zint no)
{
if (cf->head.state > 1)
- return cf_new_flat (cf, no);
+ return cf_new_flat(cf, no);
if (cf->no_miss*2 > cf->no_hits)
{
- cf_moveto_flat (cf);
- assert (cf->head.state > 1);
- return cf_new_flat (cf, no);
+ if (cf_moveto_flat(cf))
+ return -1;
+ assert(cf->head.state > 1);
+ return cf_new_flat(cf, no);
}
- return cf_new_hash (cf, no);
+ return cf_new_hash(cf, no);
}
-int cf_read (CFile cf, zint no, int offset, int nbytes, void *buf)
+/** \brief reads block from commit area
+ \param cf commit file
+ \param no block number
+ \param offset offset in block
+ \param nbytes number of bytes to read
+ \param buf buffer for content (if read was succesful)
+ \retval 0 block could not be fully read
+ \retval 1 block could be read
+ \retval -1 error
+*/
+int cf_read(CFile cf, zint no, int offset, int nbytes, void *buf)
{
zint block;
+ int ret;
- assert (cf);
- zebra_mutex_lock (&cf->mutex);
- if (!(block = cf_lookup (cf, no)))
+ assert(cf);
+ zebra_mutex_lock(&cf->mutex);
+ ret = cf_lookup(cf, no, &block);
+ zebra_mutex_unlock(&cf->mutex);
+ if (ret != 1)
{
- zebra_mutex_unlock (&cf->mutex);
- return -1;
+ /* block could not be read or error */
+ return ret;
}
- zebra_mutex_unlock (&cf->mutex);
- if (!mf_read (cf->block_mf, block, offset, nbytes, buf))
+ if (mf_read(cf->block_mf, block, offset, nbytes, buf) != 1)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "cf_read no=" ZINT_FORMAT " block=" ZINT_FORMAT, no, block);
- exit (1);
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "cf_read no=" ZINT_FORMAT " block=" ZINT_FORMAT, no, block);
+ return -1;
}
return 1;
}
-int cf_write (CFile cf, zint no, int offset, int nbytes, const void *buf)
+/** \brief writes block to commit area
+ \param cf commit file
+ \param no block number
+ \param offset offset in block
+ \param nbytes number of bytes to be written
+ \param buf buffer to be written
+ \retval 0 block written
+ \retval -1 error
+*/
+int cf_write(CFile cf, zint no, int offset, int nbytes, const void *buf)
{
zint block;
+ int ret;
+
+ assert(cf);
+ zebra_mutex_lock(&cf->mutex);
- assert (cf);
- zebra_mutex_lock (&cf->mutex);
- if (!(block = cf_lookup (cf, no)))
+ ret = cf_lookup(cf, no, &block);
+
+ if (ret == -1)
{
- block = cf_new (cf, no);
+ zebra_mutex_unlock(&cf->mutex);
+ return ret;
+ }
+ if (ret == 0)
+ {
+ block = cf_new(cf, no);
+ if (!block)
+ {
+ zebra_mutex_unlock(&cf->mutex);
+ return -1;
+ }
if (offset || nbytes)
{
- mf_read (cf->rmf, no, 0, 0, cf->iobuf);
- memcpy (cf->iobuf + offset, buf, nbytes);
+ mf_read(cf->rmf, no, 0, 0, cf->iobuf);
+ memcpy(cf->iobuf + offset, buf, nbytes);
buf = cf->iobuf;
offset = 0;
nbytes = 0;
}
}
- zebra_mutex_unlock (&cf->mutex);
- if (mf_write (cf->block_mf, block, offset, nbytes, buf))
- {
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "cf_write no=" ZINT_FORMAT
- " block=" ZINT_FORMAT, no, block);
- exit (1);
- }
- return 0;
+ zebra_mutex_unlock(&cf->mutex);
+ return mf_write(cf->block_mf, block, offset, nbytes, buf);
}
-int cf_close (CFile cf)
+int cf_close(CFile cf)
{
- yaz_log (YLOG_DEBUG, "cf: close hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT
+ yaz_log(YLOG_DEBUG, "cf: close hits=%d miss=%d bucket_in_memory=" ZINT_FORMAT
" total=" ZINT_FORMAT,
cf->no_hits, cf->no_miss, cf->bucket_in_memory,
cf->head.next_bucket - cf->head.first_bucket);
- flush_bucket (cf, -1);
- if (cf->dirty)
+ flush_bucket(cf, -1);
+ if (cf->hash_mf)
{
- mf_write (cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head);
- write_head (cf);
+ if (cf->dirty)
+ {
+ mf_write(cf->hash_mf, 0, 0, sizeof(cf->head), &cf->head);
+ write_head(cf);
+ }
+ mf_close(cf->hash_mf);
}
- mf_close (cf->hash_mf);
- mf_close (cf->block_mf);
- xfree (cf->array);
- xfree (cf->parray);
- xfree (cf->iobuf);
- zebra_mutex_destroy (&cf->mutex);
- xfree (cf);
+ if (cf->block_mf)
+ mf_close(cf->block_mf);
+ xfree(cf->array);
+ xfree(cf->parray);
+ xfree(cf->iobuf);
+ zebra_mutex_destroy(&cf->mutex);
+ xfree(cf);
return 0;
}
-/* $Id: mfile.c,v 1.69 2006-10-10 10:19:28 adam Exp $
+/* $Id: mfile.c,v 1.70 2006-11-08 22:08:27 adam Exp $
Copyright (C) 1995-2006
Index Data ApS
*/
-
-
-
- /*
- * TODO: The size estimates in init may not be accurate due to
- * only partially written final blocks.
- */
-
#include <sys/types.h>
#include <fcntl.h>
#ifdef WIN32
break;
if (!yaz_is_abspath(ad) && base)
{
- strcpy (dirname, base);
+ strcpy(dirname, base);
i = strlen(dirname);
dirname[i++] = '/';
}
while (*ad)
{
- if (*ad == ':' && strchr ("+-0123456789", ad[1]))
+ if (*ad == ':' && strchr("+-0123456789", ad[1]))
break;
if (i < FILENAME_MAX)
dirname[i++] = *ad;
dirname[i] = '\0';
if (*ad++ != ':')
{
- yaz_log (YLOG_WARN, "Missing colon after path: %s", ad0);
+ yaz_log(YLOG_WARN, "Missing colon after path: %s", ad0);
return -1;
}
if (i == 0)
{
- yaz_log (YLOG_WARN, "Empty path: %s", ad0);
+ yaz_log(YLOG_WARN, "Empty path: %s", ad0);
return -1;
}
while (*ad == ' ' || *ad == '\t')
size = 0;
if (*ad < '0' || *ad > '9')
{
- yaz_log (YLOG_FATAL, "Missing size after path: %s", ad0);
+ yaz_log(YLOG_FATAL, "Missing size after path: %s", ad0);
return -1;
}
size = 0;
case 'M': case 'm': multi = 1048576; break;
case 'G': case 'g': multi = 1073741824; break;
case '\0':
- yaz_log (YLOG_FATAL, "Missing unit: %s", ad0);
+ yaz_log(YLOG_FATAL, "Missing unit: %s", ad0);
return -1;
default:
- yaz_log (YLOG_FATAL, "Illegal unit: %c in %s", *ad, ad0);
+ yaz_log(YLOG_FATAL, "Illegal unit: %c in %s", *ad, ad0);
return -1;
}
ad++;
return 0;
}
+/** \brief position within metafile (perform seek)
+ \param mf metafile handle
+ \param pos block position
+ \param offset offset within block
+ \retval 0 OK
+ \retval -1 ERROR
+ \retval -2 OK, but file does not created (read-only)
+*/
+
static zint file_position(MFile mf, zint pos, int offset)
{
zint off = 0, ps;
(O_BINARY|O_RDONLY), 0666)) < 0)
{
if (!mf->wr && errno == ENOENT && off == 0)
+ {
+ /* we can't open it for reading. But not really an error */
return -2;
- yaz_log (YLOG_WARN|YLOG_ERRNO, "Failed to open %s", mf->files[c].path);
+ }
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to open %s", mf->files[c].path);
return -1;
}
}
ps = pos - off;
- if (mfile_seek(mf->files[c].fd, ps * (mfile_off_t) mf->blocksize + offset,
+ if (mfile_seek(mf->files[c].fd, ps *(mfile_off_t) mf->blocksize + offset,
SEEK_SET) < 0)
{
- yaz_log (YLOG_WARN|YLOG_ERRNO, "Failed to seek in %s", mf->files[c].path);
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to seek in %s", mf->files[c].path);
yaz_log(YLOG_WARN, "pos=" ZINT_FORMAT " off=" ZINT_FORMAT " blocksize=%d offset=%d",
pos, off, mf->blocksize, offset);
return -1;
return 0;
}
-/*
- * Create a new area, cotaining metafiles in directories.
- * Find the part-files in each directory, and inventory the existing metafiles.
- */
+/** \brief creates a metafile area
+ \param name of area (does not show up on disk - purely for notation)
+ \param spec area specification (e.g. "/a:1G dir /b:2000M"
+ \param base base directory (NULL for no base)
+ \returns metafile area handle or NULL if error occurs
+*/
MFile_area mf_init(const char *name, const char *spec, const char *base)
{
MFile_area ma = (MFile_area) xmalloc(sizeof(*ma));
int fd, number;
char metaname[FILENAME_MAX+1], tmpnam[FILENAME_MAX+1];
- yaz_log (YLOG_DEBUG, "mf_init(%s)", name);
+ yaz_log(YLOG_DEBUG, "mf_init(%s)", name);
strcpy(ma->name, name);
ma->mfiles = 0;
ma->dirs = 0;
if (scan_areadef(ma, spec, base) < 0)
{
- yaz_log (YLOG_WARN, "Failed to access description of '%s'", name);
+ yaz_log(YLOG_WARN, "Failed to access description of '%s'", name);
return 0;
}
/* look at each directory */
{
if (!(dd = opendir(dirp->name)))
{
- yaz_log (YLOG_WARN|YLOG_ERRNO, "Failed to open directory %s",
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to open directory %s",
dirp->name);
return 0;
}
while ((dent = readdir(dd)))
{
int len = strlen(dent->d_name);
- const char *cp = strrchr (dent->d_name, '-');
- if (strchr (".-", *dent->d_name))
+ const char *cp = strrchr(dent->d_name, '-');
+ if (strchr(".-", *dent->d_name))
continue;
- if (len < 5 || !cp || strcmp (dent->d_name + len - 3, ".mf"))
+ if (len < 5 || !cp || strcmp(dent->d_name + len - 3, ".mf"))
continue;
number = atoi(cp+1);
- memcpy (metaname, dent->d_name, cp - dent->d_name);
+ memcpy(metaname, dent->d_name, cp - dent->d_name);
metaname[ cp - dent->d_name] = '\0';
for (meta_f = ma->mfiles; meta_f; meta_f = meta_f->next)
if (!meta_f)
{
meta_f = (meta_file *) xmalloc(sizeof(*meta_f));
- zebra_mutex_init (&meta_f->mutex);
+ zebra_mutex_init(&meta_f->mutex);
meta_f->ma = ma;
meta_f->next = ma->mfiles;
meta_f->open = 0;
/* get size */
if ((fd = open(part_f->path, O_BINARY|O_RDONLY)) < 0)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "Failed to access %s",
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to access %s",
dent->d_name);
return 0;
}
if ((part_f->bytes = mfile_seek(fd, 0, SEEK_END)) < 0)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "Failed to seek in %s",
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to seek in %s",
dent->d_name);
return 0;
}
}
for (meta_f = ma->mfiles; meta_f; meta_f = meta_f->next)
{
- yaz_log (YLOG_DEBUG, "mf_init: %s consists of %d part(s)", meta_f->name,
+ yaz_log(YLOG_DEBUG, "mf_init: %s consists of %d part(s)", meta_f->name,
meta_f->no_files);
qsort(meta_f->files, meta_f->no_files, sizeof(part_file),
cmp_part_file);
return ma;
}
+/** \brief destroys metafile area handle
+ \param ma metafile area handle
+*/
void mf_destroy(MFile_area ma)
{
mf_dir *dp;
{
mf_dir *d = dp;
dp = dp->next;
- xfree (d);
+ xfree(d);
}
mf_reset(ma, 0);
- xfree (ma);
+ xfree(ma);
}
+/** \brief reset all files in a metafile area (optionally delete them as well)
+ \param ma metafile area
+ \param unlink_flag if unlink_flag=1 all files are removed from FS
+*/
void mf_reset(MFile_area ma, int unlink_flag)
{
meta_file *meta_f;
meta_f = meta_f->next;
- assert (!m->open);
+ assert(!m->open);
for (i = 0; i<m->no_files; i++)
{
if (unlink_flag)
- unlink (m->files[i].path);
- xfree (m->files[i].path);
+ unlink(m->files[i].path);
+ xfree(m->files[i].path);
}
- zebra_mutex_destroy (&m->mutex);
- xfree (m);
+ zebra_mutex_destroy(&m->mutex);
+ xfree(m);
}
ma->mfiles = 0;
}
-/*
- * Open a metafile.
+/** \brief opens metafile
+ \param ma metafile area handle
+ \param name pseudo filename (name*.mf)
+ \param block_size block size for this file
+ \param wflag write flag, 0=read, 1=write&read
+ \returns metafile handle, or NULL for error (could not be opened)
*/
MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag)
{
yaz_log(YLOG_DEBUG, "mf_open(%s bs=%d, %s)", name, block_size,
wflag ? "RW" : "RDONLY");
- assert (ma);
+ assert(ma);
for (mnew = ma->mfiles; mnew; mnew = mnew->next)
if (!strcmp(name, mnew->name))
{
if (mnew->open)
- abort();
- else
- break;
+ {
+ yaz_log(YLOG_WARN, "metafile %s already open", name);
+ return 0;
+ }
}
if (!mnew)
{
mnew = (meta_file *) xmalloc(sizeof(*mnew));
strcpy(mnew->name, name);
/* allocate one, empty file */
- zebra_mutex_init (&mnew->mutex);
+ zebra_mutex_init(&mnew->mutex);
mnew->no_files = 1;
mnew->files[0].bytes = 0;
mnew->files[0].blocks = 0;
mnew->min_bytes_creat; dp = dp->next);
if (!dp)
{
- yaz_log (YLOG_FATAL, "Insufficient space for new mfile.");
+ yaz_log(YLOG_FATAL, "Insufficient space for new mfile.");
return 0;
}
mnew->files[0].dir = dp;
return mnew;
}
-/*
- * Close a metafile.
- */
+/** \brief closes metafile
+ \param mf metafile handle
+ \retval 0 OK
+*/
int mf_close(MFile mf)
{
int i;
- yaz_log (YLOG_DEBUG, "mf_close(%s)", mf->name);
+ yaz_log(YLOG_DEBUG, "mf_close(%s)", mf->name);
assert(mf->open);
for (i = 0; i < mf->no_files; i++)
{
return 0;
}
-/*
- * Read one block from a metafile. Interface mirrors bfile.
+/** \brief reads block from metafile
+ \param mf metafile handle
+ \param no block position
+ \param offset offset within block
+ \param nbytes no of bytes to read (0 for whole block)
+ \param buf content (filled with data if OK)
+ \retval 0 block partially read
+ \retval 1 block fully read
+ \retval -1 block could not be read due to error
*/
int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf)
{
zint rd;
int toread;
- zebra_mutex_lock (&mf->mutex);
+ zebra_mutex_lock(&mf->mutex);
if ((rd = file_position(mf, no, offset)) < 0)
{
if (rd == -2)
{
- zebra_mutex_unlock (&mf->mutex);
+ zebra_mutex_unlock(&mf->mutex);
return 0;
}
else
{
- yaz_log (YLOG_FATAL, "mf_read %s internal error", mf->name);
- exit(1);
+ yaz_log(YLOG_FATAL, "mf_read2 %s internal error", mf->name);
+ return -1;
}
}
toread = nbytes ? nbytes : mf->blocksize;
if ((rd = read(mf->files[mf->cur_file].fd, buf, toread)) < 0)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "mf_read: Read failed (%s)",
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "mf_read2: Read failed (%s)",
mf->files[mf->cur_file].path);
- exit(1);
+ return -1;
}
- zebra_mutex_unlock (&mf->mutex);
+ zebra_mutex_unlock(&mf->mutex);
if (rd < toread)
return 0;
else
return 1;
}
-/*
- * Write.
+
+/** \brief writes block to metafile
+ \param mf metafile handle
+ \param no block position
+ \param offset offset within block
+ \param nbytes no of bytes to write (0 for whole block)
+ \param buf content to be written
+ \retval 0 block written
+ \retval -1 error (block not written)
*/
int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf)
{
char tmp[FILENAME_MAX+1];
unsigned char dummych = '\xff';
- zebra_mutex_lock (&mf->mutex);
+ zebra_mutex_lock(&mf->mutex);
if ((ps = file_position(mf, no, offset)) < 0)
{
- yaz_log (YLOG_FATAL, "mf_write %s internal error (1)", mf->name);
- exit(1);
+ yaz_log(YLOG_FATAL, "mf_write %s internal error (1)", mf->name);
+ return -1;
}
/* file needs to grow */
while (ps >= mf->files[mf->cur_file].blocks)
if ((nblocks = (int) (mf->files[mf->cur_file].dir->avail_bytes /
mf->blocksize)) > 0)
{
- yaz_log (YLOG_DEBUG, "Capping off file %s at pos " ZINT_FORMAT,
+ yaz_log(YLOG_DEBUG, "Capping off file %s at pos " ZINT_FORMAT,
mf->files[mf->cur_file].path, nblocks);
if ((ps = file_position(mf,
(mf->cur_file ? mf->files[mf->cur_file-1].top : 0) +
mf->files[mf->cur_file].blocks + nblocks - 1, 0)) < 0)
{
- yaz_log (YLOG_FATAL, "mf_write %s internal error (2)",
+ yaz_log(YLOG_FATAL, "mf_write %s internal error (2)",
mf->name);
- exit(1);
+ return -1;
}
- yaz_log (YLOG_DEBUG, "ps = " ZINT_FORMAT, ps);
+ yaz_log(YLOG_DEBUG, "ps = " ZINT_FORMAT, ps);
if (write(mf->files[mf->cur_file].fd, &dummych, 1) < 1)
{
- yaz_log (YLOG_ERRNO|YLOG_FATAL, "mf_write %s internal error (3)",
+ yaz_log(YLOG_ERRNO|YLOG_FATAL, "mf_write %s internal error (3)",
mf->name);
- exit(1);
+ return -1;
}
mf->files[mf->cur_file].blocks += nblocks;
mf->files[mf->cur_file].bytes += nblocks * mf->blocksize;
mf->blocksize;
}
/* get other bit */
- yaz_log (YLOG_DEBUG, "Creating new file.");
+ yaz_log(YLOG_DEBUG, "Creating new file.");
for (dp = mf->ma->dirs; dp && dp->max_bytes >= 0 &&
dp->avail_bytes < needed; dp = dp->next);
if (!dp)
{
- yaz_log (YLOG_FATAL, "Cannot allocate more space for %s",
+ yaz_log(YLOG_FATAL, "Cannot allocate more space for %s",
mf->name);
- exit(1);
+ return -1;
}
mf->files[mf->cur_file].top = (mf->cur_file ?
mf->files[mf->cur_file-1].top : -1) +
/* open new file and position at beginning */
if ((ps = file_position(mf, no, offset)) < 0)
{
- yaz_log (YLOG_FATAL, "mf_write %s internal error (4)",
+ yaz_log(YLOG_FATAL, "mf_write %s internal error (4)",
mf->name);
- exit(1);
+ return -1;
}
}
else
towrite = nbytes ? nbytes : mf->blocksize;
if (write(mf->files[mf->cur_file].fd, buf, towrite) < towrite)
{
- yaz_log (YLOG_FATAL|YLOG_ERRNO, "Write failed for file %s part %d",
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "Write failed for file %s part %d",
mf->name, mf->cur_file);
- exit(1);
+ return -1;
}
- zebra_mutex_unlock (&mf->mutex);
+ zebra_mutex_unlock(&mf->mutex);
return 0;
}
+/** \brief metafile area statistics
+ \param ma metafile area handle
+ \param no area number (0=first, 1=second, ..)
+ \param directory holds directory upon completion (if non-NULL)
+ \param used_bytes holds used bytes upon completion (if non-NULL)
+ \param max_bytes holds max size bytes upon completion (if non-NULL)
+ \retval 0 area number does not exist
+ \retval 1 area number exists (and directory,used_bytes,.. are set)
+*/
int mf_area_directory_stat(MFile_area ma, int no, const char **directory,
double *used_bytes, double *max_bytes)
{
-/* $Id: bfile.h,v 1.10 2006-08-14 10:40:14 adam Exp $
+/* $Id: bfile.h,v 1.11 2006-11-08 22:08:26 adam Exp $
Copyright (C) 1995-2006
Index Data ApS
const char *magic, int *read_version,
const char **more_info);
+/** \brief read from block file (may call exit)
+ \param bf block file handle
+ \param no block no (first block is 0, second is 1..)
+ \param offset offset within block to be read
+ \param nbytes number of bytes to read (0 for whole block)
+ \param buf raw bytes with content (at least nbytes of size)
+ \retval 1 whole block could be read
+ \retval 0 whole block could not be read
+ */
+YAZ_EXPORT
+int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf);
+
/** \brief read from block file
\param bf block file handle
\param no block no (first block is 0, second is 1..)
\param buf raw bytes with content (at least nbytes of size)
\retval 1 whole block could be read
\retval 0 whole block could not be read
+ \retval -1 error
+ */
+YAZ_EXPORT
+int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf);
+
+
+/** \brief writes block of bytes to file (may call exit)
+ \param bf block file handle
+ \param no block no
+ \param offset within block
+ \param nbytes number of bytes to write
+ \param buf buffer to write
+ \retval 0 success (block could be written)
+
+ This function can not return a failure. System calls exit(1)
+ if write failed.
*/
YAZ_EXPORT
-int bf_read (BFile bf, zint no, int offset, int nbytes, void *buf);
+int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf);
+
/** \brief writes block of bytes to file
\param bf block file handle
\param offset within block
\param nbytes number of bytes to write
\param buf buffer to write
- \retval 0 succes (block could be written)
+ \retval 0 success (block written)
+ \retval -1 error
This function can not return a failure. System calls exit(1)
if write failed.
*/
YAZ_EXPORT
-int bf_write (BFile bf, zint no, int offset, int nbytes, const void *buf);
+int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf);
+
/** \brief enables or disables shadow for block files
\param bfs block files