-/* $Id: recindex.c,v 1.45 2005-08-09 12:30:46 adam Exp $
+/* $Id: recindex.c,v 1.47 2006-03-26 14:17:01 adam Exp $
Copyright (C) 1995-2005
Index Data ApS
return sysno - FAKE_OFFSET;
}
-static void rec_write_head(Records p)
+static ZEBRA_RES rec_write_head(Records p)
{
int r;
if (r)
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "write head of %s", p->index_fname);
- exit(1);
+ return ZEBRA_FAIL;
}
+ return ZEBRA_OK;
}
static void rec_tmp_expand(Records p, int size)
if (r != 1 && !ignoreError)
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "read in %s at pos %ld",
- p->index_fname, (long) pos);
- exit(1);
+ p->index_fname, (long) pos);
}
return r;
}
(char*) buf + sz1);
}
-static void rec_release_blocks(Records p, SYSNO sysno)
+static ZEBRA_RES rec_release_blocks(Records p, SYSNO sysno)
{
struct record_index_entry entry;
zint freeblock;
int first = 1;
if (read_indx(p, sysno, &entry, sizeof(entry), 1) != 1)
- return ;
+ return ZEBRA_FAIL;
freeblock = entry.next;
assert(freeblock > 0);
block_and_ref) != 1)
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "read in rec_del_single");
- exit(1);
+ return ZEBRA_FAIL;
}
if (first)
{
sizeof(block_and_ref), block_and_ref))
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "write in rec_del_single");
- exit(1);
+ return ZEBRA_FAIL;
}
- return;
+ return ZEBRA_OK;
}
first = 0;
}
&p->head.block_free[dst_type]))
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "write in rec_del_single");
- exit(1);
+ return ZEBRA_FAIL;
}
p->head.block_free[dst_type] = freeblock;
memcpy(&freeblock, block_and_ref, sizeof(freeblock));
p->head.block_used[dst_type]--;
}
p->head.total_bytes -= entry.size;
+ return ZEBRA_OK;
}
-static void rec_delete_single(Records p, Record rec)
+static ZEBRA_RES rec_delete_single(Records p, Record rec)
{
struct record_index_entry entry;
- rec_release_blocks(p, rec_sysno_to_int(rec->sysno));
+ if (rec_release_blocks(p, rec_sysno_to_int(rec->sysno)) != ZEBRA_OK)
+ return ZEBRA_FAIL;
entry.next = p->head.index_free;
entry.size = 0;
p->head.index_free = rec_sysno_to_int(rec->sysno);
write_indx(p, rec_sysno_to_int(rec->sysno), &entry, sizeof(entry));
+ return ZEBRA_OK;
}
-static void rec_write_tmp_buf(Records p, int size, SYSNO *sysnos)
+static ZEBRA_RES rec_write_tmp_buf(Records p, int size, SYSNO *sysnos)
{
struct record_index_entry entry;
int no_written = 0;
yaz_log(YLOG_FATAL|YLOG_ERRNO, "read in %s at free block "
ZINT_FORMAT,
p->data_fname[dst_type], block_free);
- exit(1);
+ return ZEBRA_FAIL;
}
}
else
memcpy(cptr, &block_free, sizeof(block_free));
bf_write(p->data_BFile[dst_type], block_prev, 0,
sizeof(block_free) + (p->tmp_buf+size) - cptr, cptr);
+ return ZEBRA_OK;
}
Records rec_open(BFiles bfs, int rw, int compression_method)
Records p;
int i, r;
int version;
+ ZEBRA_RES ret = ZEBRA_OK;
p = (Records) xmalloc(sizeof(*p));
p->compression_method = compression_method;
p->rw = rw;
p->tmp_size = 1024;
- p->tmp_buf = (char *) xmalloc(p->tmp_size);
p->index_fname = "reci";
p->index_BFile = bf_open(bfs, p->index_fname, RIDX_CHUNK, rw);
if (p->index_BFile == NULL)
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", p->index_fname);
- exit(1);
+ xfree(p);
+ return 0;
}
+ p->tmp_buf = (char *) xmalloc(p->tmp_size);
r = bf_read(p->index_BFile, 0, 0, 0, p->tmp_buf);
switch (r)
{
p->head.block_move[i] = p->head.block_size[i] * 24;
}
if (rw)
- rec_write_head(p);
+ {
+ if (rec_write_head(p) != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
+ }
break;
case 1:
memcpy(&p->head, p->tmp_buf, sizeof(p->head));
if (memcmp(p->head.magic, REC_HEAD_MAGIC, sizeof(p->head.magic)))
{
yaz_log(YLOG_FATAL, "file %s has bad format", p->index_fname);
- exit(1);
+ ret = ZEBRA_FAIL;
}
version = atoi(p->head.version);
if (version != REC_VERSION)
{
yaz_log(YLOG_FATAL, "file %s is version %d, but version"
" %d is required", p->index_fname, version, REC_VERSION);
- exit(1);
+ ret = ZEBRA_FAIL;
}
break;
}
rw)))
{
yaz_log(YLOG_FATAL|YLOG_ERRNO, "bf_open %s", p->data_fname[i]);
- exit(1);
+ ret = ZEBRA_FAIL;
}
}
p->cache_max = 400;
p->record_cache = (struct record_cache_entry *)
xmalloc(sizeof(*p->record_cache)*p->cache_max);
zebra_mutex_init(&p->mutex);
+ if (ret == ZEBRA_FAIL)
+ rec_close(&p);
return p;
}
if (i == 0)
{
rec_encode_zint(rec_sysno_to_int(rec->sysno),
- *out_buf + *out_offset, &len);
+ (unsigned char *) *out_buf + *out_offset, &len);
(*out_offset) += len;
}
if (rec->size[i] == 0)
{
- rec_encode_unsigned(1, *out_buf + *out_offset, &len);
+ rec_encode_unsigned(1, (unsigned char *) *out_buf + *out_offset,
+ &len);
(*out_offset) += len;
}
else if (last_rec && rec->size[i] == last_rec->size[i] &&
!memcmp(rec->info[i], last_rec->info[i], rec->size[i]))
{
- rec_encode_unsigned(0, *out_buf + *out_offset, &len);
+ rec_encode_unsigned(0, (unsigned char *) *out_buf + *out_offset,
+ &len);
(*out_offset) += len;
}
else
{
- rec_encode_unsigned(rec->size[i]+1, *out_buf + *out_offset, &len);
+ rec_encode_unsigned(rec->size[i]+1,
+ (unsigned char *) *out_buf + *out_offset,
+ &len);
(*out_offset) += len;
memcpy(*out_buf + *out_offset, rec->info[i], rec->size[i]);
(*out_offset) += rec->size[i];
}
}
-static void rec_write_multiple(Records p, int saveCount)
+static ZEBRA_RES rec_write_multiple(Records p, int saveCount)
{
int i;
short ref_count = 0;
char *out_buf = (char *) xmalloc(out_size);
SYSNO *sysnos = (SYSNO *) xmalloc(sizeof(*sysnos) * (p->cache_cur + 1));
SYSNO *sysnop = sysnos;
+ ZEBRA_RES ret = ZEBRA_OK;
for (i = 0; i<p->cache_cur - saveCount; i++)
{
last_rec = e->rec;
break;
case recordFlagWrite:
- rec_release_blocks(p, rec_sysno_to_int(e->rec->sysno));
+ if (rec_release_blocks(p, rec_sysno_to_int(e->rec->sysno))
+ != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
+
rec_cache_flush_block1(p, e->rec, last_rec, &out_buf,
&out_size, &out_offset);
*sysnop++ = rec_sysno_to_int(e->rec->sysno);
last_rec = e->rec;
break;
case recordFlagDelete:
- rec_delete_single(p, e->rec);
+ if (rec_delete_single(p, e->rec) != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
+
e->flag = recordFlagNop;
break;
default:
*sysnop = -1;
if (ref_count)
{
- int csize = 0; /* indicate compression "not performed yet" */
+ unsigned int csize = 0; /* indicate compression "not performed yet" */
compression_method = p->compression_method;
switch (compression_method)
{
&compression_method, sizeof(compression_method));
/* -------- compression */
- rec_write_tmp_buf(p, csize + sizeof(short) + sizeof(char), sysnos);
+ if (rec_write_tmp_buf(p, csize + sizeof(short) + sizeof(char), sysnos)
+ != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
}
xfree(out_buf);
xfree(sysnos);
+ return ret;
}
-static void rec_cache_flush(Records p, int saveCount)
+static ZEBRA_RES rec_cache_flush(Records p, int saveCount)
{
int i, j;
+ ZEBRA_RES ret;
if (saveCount >= p->cache_cur)
saveCount = 0;
- rec_write_multiple(p, saveCount);
+ ret = rec_write_multiple(p, saveCount);
for (i = 0; i<p->cache_cur - saveCount; i++)
{
memcpy(p->record_cache+j, p->record_cache+i,
sizeof(*p->record_cache));
p->cache_cur = saveCount;
+ return ret;
}
static Record *rec_cache_lookup(Records p, SYSNO sysno,
return NULL;
}
-static void rec_cache_insert(Records p, Record rec, enum recordCacheFlag flag)
+static ZEBRA_RES rec_cache_insert(Records p, Record rec, enum recordCacheFlag flag)
{
struct record_cache_entry *e;
+ ZEBRA_RES ret = ZEBRA_OK;
if (p->cache_cur == p->cache_max)
- rec_cache_flush(p, 1);
+ ret = rec_cache_flush(p, 1);
else if (p->cache_cur > 0)
{
int i, j;
used += r->size[j];
}
if (used > 90000)
- rec_cache_flush(p, 1);
+ ret = rec_cache_flush(p, 1);
}
assert(p->cache_cur < p->cache_max);
e = p->record_cache + (p->cache_cur)++;
e->flag = flag;
e->rec = rec_cp(rec);
+ return ret;
}
-void rec_close(Records *pp)
+ZEBRA_RES rec_close(Records *pp)
{
Records p = *pp;
int i;
+ ZEBRA_RES ret = ZEBRA_OK;
- assert(p);
+ if (!p)
+ return ret;
zebra_mutex_destroy(&p->mutex);
- rec_cache_flush(p, 0);
+ if (rec_cache_flush(p, 0) != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
+
xfree(p->record_cache);
if (p->rw)
- rec_write_head(p);
+ {
+ if (rec_write_head(p) != ZEBRA_OK)
+ ret = ZEBRA_FAIL;
+ }
if (p->index_BFile)
bf_close(p->index_BFile);
xfree(p->tmp_buf);
xfree(p);
*pp = NULL;
+ return ret;
}
static Record rec_get_int(Records p, SYSNO sysno)
char *in_buf = 0;
char *bz_buf = 0;
#if HAVE_BZLIB_H
- int bz_size;
+ unsigned int bz_size;
#endif
char compression_method;
in_size = bz_size;
#else
yaz_log(YLOG_FATAL, "cannot decompress record(s) in BZIP2 format");
- exit(1);
+ return 0;
#endif
break;
case REC_COMPRESS_NONE:
{
zint this_sysno;
int len;
- rec_decode_zint(&this_sysno, nptr, &len);
+ rec_decode_zint(&this_sysno, (unsigned char *) nptr, &len);
nptr += len;
for (i = 0; i < REC_NO_INFO; i++)
{
- int this_size;
- rec_decode_unsigned(&this_size, nptr, &len);
+ unsigned int this_size;
+ rec_decode_unsigned(&this_size, (unsigned char *) nptr, &len);
nptr += len;
if (this_size == 0)
}
}
xfree(bz_buf);
- rec_cache_insert(p, rec, recordFlagNop);
+ if (rec_cache_insert(p, rec, recordFlagNop) != ZEBRA_OK)
+ return 0;
return rec;
}
{
struct record_index_entry entry;
- read_indx(p, p->head.index_free, &entry, sizeof(entry), 0);
+ if (read_indx(p, p->head.index_free, &entry, sizeof(entry), 0) < 1)
+ {
+ xfree(rec);
+ return 0;
+ }
sysno = p->head.index_free;
p->head.index_free = entry.next;
}
return rec;
}
-void rec_del(Records p, Record *recpp)
+ZEBRA_RES rec_del(Records p, Record *recpp)
{
Record *recp;
+ ZEBRA_RES ret = ZEBRA_OK;
zebra_mutex_lock(&p->mutex);
(p->head.no_records)--;
}
else
{
- rec_cache_insert(p, *recpp, recordFlagDelete);
+ ret = rec_cache_insert(p, *recpp, recordFlagDelete);
rec_rm(recpp);
}
zebra_mutex_unlock(&p->mutex);
*recpp = NULL;
+ return ret;
}
-void rec_put(Records p, Record *recpp)
+ZEBRA_RES rec_put(Records p, Record *recpp)
{
Record *recp;
+ ZEBRA_RES ret = ZEBRA_OK;
zebra_mutex_lock(&p->mutex);
if ((recp = rec_cache_lookup(p, (*recpp)->sysno, recordFlagWrite)))
}
else
{
- rec_cache_insert(p, *recpp, recordFlagWrite);
+ ret = rec_cache_insert(p, *recpp, recordFlagWrite);
rec_rm(recpp);
}
zebra_mutex_unlock(&p->mutex);
*recpp = NULL;
+ return ret;
}
void rec_rm(Record *recpp)