- char compression_method;
-
- assert(sysno > 0);
- assert(p);
-
- if ((recp = rec_cache_lookup(p, sysno, recordFlagNop)))
- return rec_cp(*recp);
-
- if (read_indx(p, rec_sysno_to_int(sysno), &entry, sizeof(entry), 1) < 1)
- return NULL; /* record is not there! */
-
- if (!entry.size)
- return NULL; /* record is deleted */
-
- dst_type = (int) (entry.next & 7);
- assert(dst_type < REC_BLOCK_TYPES);
- freeblock = entry.next / 8;
-
- assert(freeblock > 0);
-
- rec_tmp_expand(p, entry.size);
-
- cptr = p->tmp_buf;
- r = bf_read(p->data_BFile[dst_type], freeblock, 0, 0, cptr);
- if (r < 0)
- return 0;
- memcpy(&freeblock, cptr, sizeof(freeblock));
-
- while (freeblock)
- {
- zint tmp;
-
- cptr += p->head.block_size[dst_type] - sizeof(freeblock);
-
- memcpy(&tmp, cptr, sizeof(tmp));
- r = bf_read(p->data_BFile[dst_type], freeblock, 0, 0, cptr);
- if (r < 0)
- return 0;
- memcpy(&freeblock, cptr, sizeof(freeblock));
- memcpy(cptr, &tmp, sizeof(tmp));
- }
-
- rec = (Record) xmalloc(sizeof(*rec));
- rec->sysno = sysno;
- memcpy(&compression_method, p->tmp_buf + sizeof(zint) + sizeof(short),
- sizeof(compression_method));
- in_buf = p->tmp_buf + sizeof(zint) + 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 * 20 + 100;
- while (1)
- {
- bz_buf = (char *) xmalloc(bz_size);
-#ifdef BZ_CONFIG_ERROR
- i = BZ2_bzBuffToBuffDecompress
-#else
- i = bzBuffToBuffDecompress
-#endif
- (bz_buf, &bz_size, in_buf, in_size, 0, 0);
- yaz_log(YLOG_LOG, "decompress %5d %5d", in_size, bz_size);
- if (i == BZ_OK)
- break;
- yaz_log(YLOG_LOG, "failed");
- xfree(bz_buf);
- bz_size *= 2;
- }
- in_buf = bz_buf;
- in_size = bz_size;
-#else
- yaz_log(YLOG_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)
- {
- zint this_sysno;
- int len;
- rec_decode_zint(&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 == rec_sysno_to_int(sysno))
- break;
- }
- for (i = 0; i<REC_NO_INFO; i++)
- {
- if (rec->info[i] && rec->size[i])
- {
- char *np = xmalloc(rec->size[i]+1);
- memcpy(np, rec->info[i], rec->size[i]);
- np[rec->size[i]] = '\0';
- 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_get(Records p, SYSNO sysno)
-{
- Record rec;
- zebra_mutex_lock(&p->mutex);
-
- rec = rec_get_int(p, sysno);
- zebra_mutex_unlock(&p->mutex);
- return rec;
-}
-
-Record rec_get_root(Records p)
-{
- return rec_get(p, rec_sysno_to_ext(1));