+/** \fn rfd_delete_base
+ *
+ * puts an rfd into the freelist of the rset. Only when the rset gets
+ * deleted, will all the nmem disappear */
+void rset_close(RSFD rfd)
+{
+ RSFD *pfd;
+ RSET rs = rfd->rset;
+
+ if (rs->hits_count == 0)
+ {
+ TERMID termid;
+ char buf[100];
+ while(rfd->counted_items < rs->hits_limit
+ && rset_default_read(rfd, buf, &termid))
+ ;
+
+ rs->hits_count = rfd->counted_items;
+ rs->hits_approx = 0;
+ if (rs->hits_count >= rs->hits_limit)
+ {
+ double cur, tot;
+ zint est;
+ rset_pos(rfd, &cur, &tot);
+ if (tot > 0) {
+ int i;
+ double ratio = cur/tot;
+ est = (zint)(0.5 + rs->hits_count / ratio);
+ yaz_log(log_level, "Estimating hits (%s) "
+ "%0.1f->" ZINT_FORMAT
+ "; %0.1f->" ZINT_FORMAT,
+ rs->control->desc,
+ cur, rs->hits_count,
+ tot, est);
+ i = 0; /* round to significant digits */
+ while (est > rs->hits_round) {
+ est /= 10;
+ i++;
+ }
+ while (i--)
+ est *= 10;
+ rs->hits_count = est;
+ rs->hits_approx = 1;
+ }
+ }
+ yaz_log(log_level, "rset_close p=%p count=" ZINT_FORMAT, rs,
+ rs->hits_count);
+ }
+ (*rs->control->f_close)(rfd);
+
+ yaz_log(log_level, "rfd_delete_base: rfd=%p rs=%p priv=%p fl=%p",
+ rfd, rs, rfd->priv, rs->free_list);
+ for (pfd = &rs->use_list; *pfd; pfd = &(*pfd)->next)
+ if (*pfd == rfd)
+ {
+ *pfd = (*pfd)->next;
+ rfd->next = rs->free_list;
+ rs->free_list = rfd;
+ return;
+ }
+ yaz_log(YLOG_WARN, "rset_close handle not found. type=%s",
+ rs->control->desc);
+}
+
+RSET rset_create_base(const struct rset_control *sel,
+ NMEM nmem, struct rset_key_control *kcontrol,
+ int scope, TERMID term,
+ int no_children, RSET *children)
+{
+ RSET rset;
+ NMEM M;
+ assert(nmem); /* can not yet be used, api/t4 fails */
+ if (!log_level_initialized)
+ {
+ log_level = yaz_log_module_level("rset");
+ log_level_initialized = 1;
+ }
+
+ if (nmem)
+ M = nmem;
+ else
+ M = nmem_create();
+ rset = (RSET) nmem_malloc(M, sizeof(*rset));
+ yaz_log(log_level, "rs_create(%s) rs=%p (nm=%p)", sel->desc, rset, nmem);
+ rset->nmem = M;
+ if (nmem)
+ rset->my_nmem = 0;
+ else
+ rset->my_nmem = 1;
+ rset->control = sel;
+ rset->refcount = 1;
+ rset->priv = 0;
+ rset->free_list = NULL;
+ rset->use_list = NULL;
+ rset->hits_count = 0;
+ rset->hits_limit = 1000;
+ rset->hits_round = 1000;
+ rset->keycontrol = kcontrol;
+ (*kcontrol->inc)(kcontrol);
+ rset->scope = scope;
+ rset->term = term;
+ if (term)
+ term->rset = rset;
+
+ rset->no_children = no_children;
+ rset->children = 0;
+ if (no_children)
+ {
+ rset->children = (RSET*)
+ nmem_malloc(rset->nmem, no_children*sizeof(RSET *));
+ memcpy(rset->children, children, no_children*sizeof(RSET *));
+ }
+ return rset;
+}
+
+void rset_delete(RSET rs)