43 #include <yaz/yaz-util.h>
44 #include <yaz/snprintf.h>
55 #define REC_BLOCK_TYPES 2
56 #define REC_HEAD_MAGIC "recindex"
115 #define FAKE_OFFSET 0
116 #define USUAL_RANGE 6000000000LL
120 #define FAKE_OFFSET 6000000000LL
121 #define USUAL_RANGE 2000000000LL
152 char block_and_ref[
sizeof(
zint) +
sizeof(
short)];
159 freeblock = entry.
next;
160 assert(freeblock > 0);
163 freeblock = freeblock / 8;
167 first ?
sizeof(block_and_ref) :
sizeof(
zint),
170 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"read in rec_del_single");
176 memcpy(&ref, block_and_ref +
sizeof(freeblock),
sizeof(ref));
178 memcpy(block_and_ref +
sizeof(freeblock), &ref,
sizeof(ref));
183 sizeof(block_and_ref), block_and_ref))
185 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"write in rec_del_single");
197 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"write in rec_del_single");
201 memcpy(&freeblock, block_and_ref,
sizeof(freeblock));
214 memset(&entry,
'\0',
sizeof(entry));
230 zint block_prev = -1, block_free;
235 memset(&entry,
'\0',
sizeof(entry));
240 while (no_written <
size)
249 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"read in %s at free block "
257 if (block_prev == -1)
259 entry.
next = block_free*8 + dst_type;
270 memcpy(cptr, &block_free,
sizeof(block_free));
272 cptr = p->
tmp_buf + no_written;
274 block_prev = block_free;
279 assert(block_prev != -1);
281 memcpy(cptr, &block_free,
sizeof(block_free));
283 sizeof(block_free) + (p->
tmp_buf+
size) - cptr, cptr);
289 switch(compression_method)
316 p = (
Records) xmalloc(
sizeof(*p));
317 memset(&p->
head,
'\0',
sizeof(p->
head));
361 yaz_log(YLOG_FATAL,
"file %s has bad format",
368 yaz_log(YLOG_FATAL,
"file %s is version %d, but version"
378 yaz_snprintf(str,
sizeof(str),
"recd%c", i +
'A');
388 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"bf_open %s", p->
data_fname[i]);
408 buf[*len] = 128 + (n & 127);
422 while (buf[*len] > 127)
424 n += w*(buf[*len] & 127);
438 buf[*len] = (unsigned) (128 + (n & 127));
442 buf[*len] = (unsigned) n;
452 while (buf[*len] > 127)
454 n += w*(buf[*len] & 127);
464 char **out_buf,
int *out_size,
474 int new_size = *out_offset +
rec->
size[i] + 65536;
475 char *np = (
char *) xmalloc(new_size);
477 memcpy(np, *out_buf, *out_offset);
479 *out_size = new_size;
485 (
unsigned char *) *out_buf + *out_offset, &len);
486 (*out_offset) += len;
492 (*out_offset) += len;
494 else if (last_rec &&
rec->
size[i] == last_rec->
size[i] &&
499 (*out_offset) += len;
504 (
unsigned char *) *out_buf + *out_offset,
506 (*out_offset) += len;
514 char *out_buf,
int out_offset)
522 unsigned int csize = 0;
524 switch (compression_method)
528 csize = out_offset + (out_offset >> 6) + 620;
532 uLongf destLen = csize;
534 r = compress((Bytef *) p->
tmp_buf+
sizeof(
zint)+
sizeof(
short)+
536 &destLen, (
const Bytef *) out_buf, out_offset);
542 if (r != Z_MEM_ERROR)
544 yaz_log(YLOG_WARN,
"compress error: %d", r);
554 csize = out_offset + (out_offset >> 6) + 620;
556 #ifdef BZ_CONFIG_ERROR
557 i = BZ2_bzBuffToBuffCompress
559 i = bzBuffToBuffCompress
563 &csize, out_buf, out_offset, 1, 0, 30);
566 yaz_log(YLOG_WARN,
"bzBuffToBuffCompress error code=%d", i);
579 memcpy(p->
tmp_buf +
sizeof(
zint) +
sizeof(
short) +
sizeof(
char),
580 out_buf, out_offset);
584 memcpy(p->
tmp_buf +
sizeof(
zint), &ref_count,
sizeof(ref_count));
586 &compression_method,
sizeof(compression_method));
603 char *out_buf = (
char *) xmalloc(out_size);
605 zint *sysnop = sysnos;
608 for (i = 0; i<p->
cache_cur - saveCount; i++)
615 &out_size, &out_offset);
627 &out_size, &out_offset);
663 for (i = 0; i<p->
cache_cur - saveCount; i++)
669 for (j = 0; j<saveCount; j++, i++)
766 char compression_method;
780 dst_type = (int) (entry.
next & 7);
782 freeblock = entry.
next / 8;
784 assert(freeblock > 0);
792 memcpy(&freeblock, cptr,
sizeof(freeblock));
800 memcpy(&tmp, cptr,
sizeof(tmp));
804 memcpy(&freeblock, cptr,
sizeof(freeblock));
805 memcpy(cptr, &tmp,
sizeof(tmp));
808 rec = (
Record) xmalloc(
sizeof(*rec));
810 memcpy(&compression_method, p->
tmp_buf +
sizeof(
zint) +
sizeof(
short),
811 sizeof(compression_method));
812 in_buf = p->
tmp_buf +
sizeof(
zint) +
sizeof(
short) +
sizeof(char);
813 in_size = entry.
size -
sizeof(short) -
sizeof(
char);
814 switch (compression_method)
820 unsigned int bz_size = entry.
size * 20 + 100;
823 uLongf destLen = bz_size;
824 bz_buf = (
char *) xmalloc(bz_size);
825 i = uncompress((Bytef *) bz_buf, &destLen,
826 (
const Bytef *) in_buf, in_size);
832 yaz_log(YLOG_LOG,
"failed");
840 yaz_log(YLOG_FATAL,
"cannot decompress record(s) in ZLIB format");
848 unsigned int bz_size = entry.
size * 20 + 100;
851 bz_buf = (
char *) xmalloc(bz_size);
852 #ifdef BZ_CONFIG_ERROR
853 i = BZ2_bzBuffToBuffDecompress
855 i = bzBuffToBuffDecompress
857 (bz_buf, &bz_size, in_buf, in_size, 0, 0);
860 yaz_log(YLOG_LOG,
"failed");
868 yaz_log(YLOG_FATAL,
"cannot decompress record(s) in BZIP2 format");
879 while (nptr < in_buf + in_size)
888 unsigned int this_size;
894 rec->
size[i] = this_size-1;
899 nptr += rec->
size[i];
911 char *np = xmalloc(rec->
size[i]+1);
912 memcpy(np, rec->
info[i], rec->
size[i]);
913 np[rec->
size[i]] =
'\0';
918 assert(rec->
info[i] == 0);
919 assert(rec->
size[i] == 0);
965 rec = (
Record) xmalloc(
sizeof(*rec));
1051 xfree((*recpp)->info[i]);
1061 n = (
Record) xmalloc(
sizeof(*n));
1072 n->
info[i] = (
char *) xmalloc(rec->
size[i]+1);
1090 p = (
char *) xmalloc(*len);
1098 zint total_bytes = 0;
1106 yaz_log (YLOG_LOG,
"Record blocks of size "ZINT_FORMAT,
1109 " Used/Total/Bytes used "
1121 WRBUF w = wrbuf_alloc();
1128 block_free, 0,
sizeof(nblock), &nblock) != 1)
1130 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"read in %s at free block "
1135 block_free = nblock;
1140 yaz_log(YLOG_LOG,
"%s", wrbuf_cstr(w));
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
void bf_close(BFile bf)
closes a Block file (may call exit)
BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
opens and returns a Block file handle
int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file (may call exit)
int recindex_read_indx(recindex_t p, zint sysno, void *buf, int itemsize, int ignoreError)
void recindex_write_indx(recindex_t p, zint sysno, void *buf, int itemsize)
recindex_t recindex_open(BFiles bfs, int rw, int use_isamb)
opens record index handle
void recindex_close(recindex_t p)
closes record index handle
const char * recindex_get_fname(recindex_t p)
ZEBRA_RES recindex_write_head(recindex_t p, const void *buf, size_t len)
int recindex_read_head(recindex_t p, void *buf)
struct records_info * Records
struct record_info * Record
#define REC_COMPRESS_BZIP2
BZIP2 compression (slow and requires big chunks)
#define REC_COMPRESS_ZLIB
zlib compression (faster and works off small chunks)
#define REC_COMPRESS_NONE
No compression ("none")
static ZEBRA_RES rec_cache_flush(Records p, int saveCount)
static void rec_tmp_expand(Records p, int size)
static void rec_encode_unsigned(unsigned n, unsigned char *buf, int *len)
static void rec_cache_flush_block1(Records p, Record rec, Record last_rec, char **out_buf, int *out_size, int *out_offset)
static void rec_decode_zint(zint *np, unsigned char *buf, int *len)
static ZEBRA_RES rec_write_tmp_buf(Records p, int size, zint *sysnos)
zint rec_sysno_to_int(zint sysno)
Record rec_new(Records p)
creates new record (to be written to file storage)
static zint rec_sysno_to_ext(zint sysno)
static ZEBRA_RES rec_write_multiple(Records p, int saveCount)
Records rec_open(BFiles bfs, int rw, int compression_method)
opens records system
Record rec_get(Records p, zint sysno)
gets record - with given system number
static Record rec_get_int(Records p, zint sysno)
ZEBRA_RES rec_put(Records p, Record *recpp)
puts record (writes into file storage)
static Record rec_new_int(Records p)
static Record * rec_cache_lookup(Records p, zint sysno, enum recordCacheFlag flag)
static void rec_decode_unsigned(unsigned *np, unsigned char *buf, int *len)
static ZEBRA_RES rec_cache_insert(Records p, Record rec, enum recordCacheFlag flag)
static ZEBRA_RES rec_release_blocks(Records p, zint sysno)
ZEBRA_RES rec_close(Records *pp)
char * rec_strdup(const char *s, size_t *len)
void rec_free(Record *recpp)
frees record (from memory)
Record rec_get_next(Records p, Record rec)
gets next record - with given records
static ZEBRA_RES rec_delete_single(Records p, Record rec)
ZEBRA_RES rec_del(Records p, Record *recpp)
marks record for deletion (on file storage)
void rec_prstat(Records records, int verbose)
Record rec_cp(Record rec)
int rec_check_compression_method(int compression_method)
check whether a compression method is supported
static ZEBRA_RES rec_flush_shared(Records p, short ref_count, zint *sysnos, char *out_buf, int out_offset)
Record rec_get_root(Records p)
gets root record
static void rec_encode_zint(zint n, unsigned char *buf, int *len)
enum recordCacheFlag flag
zint block_free[REC_BLOCK_TYPES]
zint block_size[REC_BLOCK_TYPES]
zint block_move[REC_BLOCK_TYPES]
zint block_used[REC_BLOCK_TYPES]
zint block_last[REC_BLOCK_TYPES]
struct record_cache_entry * record_cache
int compression_chunk_size
char * data_fname[REC_BLOCK_TYPES]
struct records_info::records_head head
BFile data_BFile[REC_BLOCK_TYPES]
#define CAST_ZINT_TO_INT(x)
short ZEBRA_RES
Common return type for Zebra API.
int zebra_mutex_unlock(Zebra_mutex *p)
int zebra_mutex_init(Zebra_mutex *p)
int zebra_mutex_lock(Zebra_mutex *p)
int zebra_mutex_destroy(Zebra_mutex *p)