- int i, j;
-
- if (saveCount >= p->cache_cur)
- saveCount = 0;
-
- rec_write_multiple (p, saveCount);
-
- for (i = 0; i<p->cache_cur - saveCount; i++)
- {
- struct record_cache_entry *e = p->record_cache + i;
- rec_rm (&e->rec);
- }
- /* i still being used ... */
- for (j = 0; j<saveCount; j++, i++)
- memcpy (p->record_cache+j, p->record_cache+i,
- sizeof(*p->record_cache));
- p->cache_cur = saveCount;
-}
-
-static Record *rec_cache_lookup (Records p, int sysno,
- enum recordCacheFlag flag)
-{
- int i;
- for (i = 0; i<p->cache_cur; i++)
- {
- struct record_cache_entry *e = p->record_cache + i;
- if (e->rec->sysno == sysno)
- {
- if (flag != recordFlagNop && e->flag == recordFlagNop)
- e->flag = flag;
- return &e->rec;
- }
- }
- return NULL;
-}
-
-static void rec_cache_insert (Records p, Record rec, enum recordCacheFlag flag)
-{
- struct record_cache_entry *e;
-
- if (p->cache_cur == p->cache_max)
- rec_cache_flush (p, 1);
- else if (p->cache_cur > 0)
- {
- int i, j;
- int used = 0;
- for (i = 0; i<p->cache_cur; i++)
- {
- Record r = (p->record_cache + i)->rec;
- for (j = 0; j<REC_NO_INFO; j++)
- used += r->size[j];
- }
- if (used > 90000)
- 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);
-}
-
-void rec_close (Records *pp)
-{
- Records p = *pp;
- int i;
-
- assert (p);
-
- rec_cache_flush (p, 0);
- xfree (p->record_cache);
-
- if (p->rw)
- rec_write_head (p);
-
- if (p->index_BFile)
- bf_close (p->index_BFile);
-
- for (i = 0; i<REC_BLOCK_TYPES; i++)
- {
- if (p->data_BFile[i])
- bf_close (p->data_BFile[i]);
- xfree (p->data_fname[i]);
- }
- xfree (p->tmp_buf);
- xfree (p);
- *pp = NULL;
-}
-
-
-Record rec_get (Records p, int sysno)
-{
- int i, in_size;
- Record rec, *recp;
- struct record_index_entry entry;
- int freeblock, dst_type;
- char *nptr, *cptr;
- char *in_buf = 0;
- char *bz_buf = 0;
- int bz_size;
- char compression_method;
-
- assert (sysno > 0);
- assert (p);
-
- if ((recp = rec_cache_lookup (p, sysno, recordFlagNop)))
- return rec_cp (*recp);
-
- if (!read_indx (p, sysno, &entry, sizeof(entry), 1))
- return NULL; /* record is not there! */
-
- if (!entry.size)
- return NULL; /* record is deleted */
-
- dst_type = entry.next & 7;
- assert (dst_type < REC_BLOCK_TYPES);
- freeblock = entry.next / 8;
-
- assert (freeblock > 0);
-
- rec = (Record) xmalloc (sizeof(*rec));
- rec_tmp_expand (p, entry.size);
-
- cptr = p->tmp_buf;
- bf_read (p->data_BFile[dst_type], freeblock, 0, 0, cptr);
- memcpy (&freeblock, cptr, sizeof(freeblock));
-
- while (freeblock)
- {
- int tmp;
-
- cptr += p->head.block_size[dst_type] - sizeof(freeblock);
-
- memcpy (&tmp, cptr, sizeof(tmp));
- bf_read (p->data_BFile[dst_type], freeblock, 0, 0, cptr);
- memcpy (&freeblock, cptr, sizeof(freeblock));
- memcpy (cptr, &tmp, sizeof(tmp));
- }
-
- rec->sysno = sysno;
- memcpy (&compression_method, p->tmp_buf + sizeof(int) + sizeof(short),
- sizeof(compression_method));
- in_buf = p->tmp_buf + sizeof(int) + sizeof(short) + sizeof(char);
- in_size = entry.size - sizeof(short) - sizeof(char);
- switch (compression_method)
- {
- case REC_COMPRESS_BZIP2:
-#if HAVE_BZLIB_H
- bz_size = entry.size * 30+100;
- bz_buf = (char *) xmalloc (bz_size);
- i = bzBuffToBuffDecompress (bz_buf, &bz_size, in_buf, in_size, 0, 0);
- logf (LOG_LOG, "decompress %5d %5d", in_size, bz_size);
- if (i != BZ_OK)
- {
- logf (LOG_FATAL, "bzBuffToBuffDecompress error code=%d", i);
- exit (1);
- }
- in_buf = bz_buf;
- in_size = bz_size;
-#else
- logf (LOG_FATAL, "cannot decompress record(s) in BZIP2 format");
- exit (1);
-#endif
- break;
- case REC_COMPRESS_NONE:
- break;
- }
- for (i = 0; i<REC_NO_INFO; i++)
- rec->info[i] = 0;
-
- nptr = in_buf; /* skip ref count */
- while (nptr < in_buf + in_size)
- {
- int this_sysno;
- int len;
- rec_decode_unsigned (&this_sysno, nptr, &len);
- nptr += len;
-
- for (i = 0; i < REC_NO_INFO; i++)
- {
- int this_size;
- rec_decode_unsigned (&this_size, nptr, &len);
- nptr += len;
-
- if (this_size == 0)
- continue;
- rec->size[i] = this_size-1;
-
- if (rec->size[i])
- {
- rec->info[i] = nptr;
- nptr += rec->size[i];
- }
- else
- rec->info[i] = NULL;
- }
- if (this_sysno == sysno)
- break;
- }
- for (i = 0; i<REC_NO_INFO; i++)
- {
- if (rec->info[i] && rec->size[i])
- {
- char *np = xmalloc (rec->size[i]);
- memcpy (np, rec->info[i], rec->size[i]);
- rec->info[i] = np;
- }
- else
- {
- assert (rec->info[i] == 0);
- assert (rec->size[i] == 0);
- }
- }
- xfree (bz_buf);
- rec_cache_insert (p, rec, recordFlagNop);
- return rec;
-}
-
-Record rec_new (Records p)
-{
- int sysno, i;
- Record rec;