~gmx_ana_indexgrps_t() { for (int i = 0; i < nr; ++i) { gmx_ana_index_deinit(&g[i]); } sfree(g); }
/*! * \param data Data to free (should point to a \p t_methoddata_permute). * * Frees the memory allocated for \c t_methoddata_permute. */ static void free_data_permute(void *data) { t_methoddata_permute *d = (t_methoddata_permute *)data; gmx_ana_index_deinit(&d->g); sfree(d->rperm); }
/*! * \param[in] sel Selection to free. */ void _gmx_selelem_free_values(t_selelem *sel) { int i, n; _gmx_selelem_mempool_release(sel); if ((sel->flags & SEL_ALLOCDATA) && sel->v.u.ptr) { /* The number of position/group structures is constant, so the * backup of using sel->v.nr should work for them. * For strings, we report an error if we don't know the allocation * size here. */ n = (sel->v.nalloc > 0) ? sel->v.nalloc : sel->v.nr; switch (sel->v.type) { case STR_VALUE: if (sel->v.nalloc == 0) { gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values"); break; } for (i = 0; i < n; ++i) { sfree(sel->v.u.s[i]); } break; case POS_VALUE: for (i = 0; i < n; ++i) { gmx_ana_pos_deinit(&sel->v.u.p[i]); } break; case GROUP_VALUE: for (i = 0; i < n; ++i) { gmx_ana_index_deinit(&sel->v.u.g[i]); } break; default: /* No special handling for other types */ break; } } if (sel->flags & SEL_ALLOCVAL) { sfree(sel->v.u.ptr); } _gmx_selvalue_setstore(&sel->v, NULL); if (sel->type == SEL_SUBEXPRREF && sel->u.param) { sel->u.param->val.u.ptr = NULL; } }
void _gmx_selelem_free_param(gmx_ana_selparam_t *param) { if (param->val.u.ptr != NULL) { if (param->val.type == GROUP_VALUE) { for (int i = 0; i < param->val.nr; ++i) { gmx_ana_index_deinit(¶m->val.u.g[i]); } } _gmx_selvalue_free(¶m->val); } }
void gmx_ana_index_union_unsorted(gmx_ana_index_t *dest, gmx_ana_index_t *a, gmx_ana_index_t *b) { if (gmx_ana_index_check_sorted(b)) { gmx_ana_index_union(dest, a, b); } else { gmx_ana_index_t tmp; gmx_ana_index_copy(&tmp, b, true); gmx_ana_index_sort(&tmp); gmx_ana_index_remove_duplicates(&tmp); gmx_ana_index_union(dest, a, &tmp); gmx_ana_index_deinit(&tmp); } }
SelectionCollection::Impl::~Impl() { clearSymbolTable(); // The tree must be freed before the SelectionData objects, since the // tree may hold references to the position data in SelectionData. sc_.root.reset(); sc_.sel.clear(); for (int i = 0; i < sc_.nvars; ++i) { sfree(sc_.varstrs[i]); } sfree(sc_.varstrs); gmx_ana_index_deinit(&sc_.gall); if (sc_.mempool) { _gmx_sel_mempool_destroy(sc_.mempool); } }
/*! * \param[in] g Index groups structure. * * The pointer \p g is invalid after the call. */ void gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g) { int i; if (g->nr == 0) { sfree(g); return; } for (i = 0; i < g->nr; ++i) { gmx_ana_index_deinit(&g->g[i]); } sfree(g->g); g->nr = 0; g->g = NULL; sfree(g); }
/*! * \param[in,out] sc Selection collection to free. * * The pointer \p sc is invalid after the call. */ void gmx_ana_selcollection_free(gmx_ana_selcollection_t *sc) { int i; sfree(sc->selstr); _gmx_selelem_free_chain(sc->root); if (sc->sel) { for (i = 0; i < sc->nr; ++i) { gmx_ana_selection_free(sc->sel[i]); } } sfree(sc->sel); gmx_ana_index_deinit(&sc->gall); _gmx_selcollection_clear_symtab(sc); sfree(sc); }
void SelectionTreeElement::freeValues() { mempoolRelease(); if ((flags & SEL_ALLOCDATA) && v.u.ptr) { /* The number of position/group structures is constant, so the * backup of using sel->v.nr should work for them. * For strings, we report an error if we don't know the allocation * size here. */ int n = (v.nalloc > 0) ? v.nalloc : v.nr; switch (v.type) { case STR_VALUE: GMX_RELEASE_ASSERT(v.nalloc != 0, "SEL_ALLOCDATA should only be set for allocated " "STR_VALUE values"); for (int i = 0; i < n; ++i) { sfree(v.u.s[i]); } break; case GROUP_VALUE: for (int i = 0; i < n; ++i) { gmx_ana_index_deinit(&v.u.g[i]); } break; default: /* No special handling for other types */ break; } } _gmx_selvalue_free(&v); if (type == SEL_SUBEXPRREF && u.param != NULL) { // TODO: This is now called from two different locations. // It is likely that one of them is unnecessary, but that requires // extra analysis to clarify. _gmx_selelem_free_param(u.param); } }
/*! * \param pc Position calculation data to be freed. * * The \p pc pointer is invalid after the call. */ void gmx_ana_poscalc_free(gmx_ana_poscalc_t *pc) { if (!pc) { return; } pc->refcount--; if (pc->refcount > 0) { return; } remove_poscalc(pc); if (pc->b.nalloc_index > 0) { sfree(pc->b.index); } if (pc->b.nalloc_a > 0) { sfree(pc->b.a); } if (pc->flags & POS_COMPLWHOLE) { gmx_ana_index_deinit(&pc->gmax); } if (pc->p) { gmx_ana_pos_free(pc->p); } if (pc->sbase) { gmx_ana_poscalc_free(pc->sbase); sfree(pc->baseid); } sfree(pc); }
SelectionCollection::Impl::~Impl() { _gmx_selelem_free_chain(_sc.root); SelectionList::const_iterator isel; for (isel = _sc.sel.begin(); isel != _sc.sel.end(); ++isel) { delete *isel; } for (int i = 0; i < _sc.nvars; ++i) { sfree(_sc.varstrs[i]); } sfree(_sc.varstrs); gmx_ana_index_deinit(&_sc.gall); if (_sc.mempool) { _gmx_sel_mempool_destroy(_sc.mempool); } if (hasFlag(efOwnPositionCollection)) { gmx_ana_poscalc_coll_free(_sc.pcc); } clearSymbolTable(); }
/*! * \param[in] sel Selection to free. */ void _gmx_selelem_free_exprdata(t_selelem *sel) { if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER) { _gmx_selelem_free_method(sel->u.expr.method, sel->u.expr.mdata); sel->u.expr.mdata = NULL; sel->u.expr.method = NULL; /* Free position data */ if (sel->u.expr.pos) { gmx_ana_pos_free(sel->u.expr.pos); sel->u.expr.pos = NULL; } /* Free position calculation data */ if (sel->u.expr.pc) { gmx_ana_poscalc_free(sel->u.expr.pc); sel->u.expr.pc = NULL; } } if (sel->type == SEL_ARITHMETIC) { sfree(sel->u.arith.opstr); sel->u.arith.opstr = NULL; } if (sel->type == SEL_SUBEXPR || sel->type == SEL_ROOT || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE)) { gmx_ana_index_deinit(&sel->u.cgrp); } if (sel->type == SEL_GROUPREF) { sfree(sel->u.gref.name); } }
/*! \brief * Setups the static base calculation for a position calculation. * * \param[in,out] pc Position calculation to setup the base for. */ static void setup_base(gmx_ana_poscalc_t *pc) { gmx_ana_poscalc_t *base, *pbase, *next; gmx_ana_index_t gp, g; /* Exit immediately if pc should not have a base. */ if (!can_use_base(pc)) { return; } gmx_ana_index_set(&gp, pc->b.nra, pc->b.a, NULL, 0); gmx_ana_index_clear(&g); gmx_ana_index_reserve(&g, pc->b.nra); pbase = pc; base = pc->coll->first; while (base) { /* Save the next calculation so that we can safely delete base */ next = base->next; /* Skip pc, calculations that already have a base (we should match the * base instead), as well as calculations that should not have a base. * If the above conditions are met, check whether we should do a * merge. */ if (base != pc && !base->sbase && can_use_base(base) && should_merge(pbase, base, &gp, &g)) { /* Check whether this is the first base found */ if (pbase == pc) { /* Create a real base if one is not present */ if (!base->p) { pbase = create_simple_base(base); } else { pbase = base; } /* Make it a base for pc as well */ merge_to_base(pbase, pc); pc->sbase = pbase; pbase->refcount++; } else /* This was not the first base */ { if (!base->p) { /* If it is not a real base, just make the new base as * the base for it as well. */ merge_to_base(pbase, base); base->sbase = pbase; pbase->refcount++; } else { /* If base is a real base, merge it with the new base * and delete it. */ merge_bases(pbase, base); } } gmx_ana_index_set(&gp, pbase->b.nra, pbase->b.a, NULL, 0); gmx_ana_index_reserve(&g, pc->b.nra); } /* Proceed to the next unchecked calculation */ base = next; } gmx_ana_index_deinit(&g); /* If no base was found, create one if one is required */ if (!pc->sbase && (pc->flags & POS_DYNAMIC) && (pc->flags & (POS_COMPLMAX | POS_COMPLWHOLE))) { create_simple_base(pc); } }
/*! * \param[in] method Method to free. * \param[in] mdata Method data to free. */ void _gmx_selelem_free_method(gmx_ana_selmethod_t *method, void *mdata) { sel_freefunc free_func = NULL; /* Save the pointer to the free function. */ if (method && method->free) { free_func = method->free; } /* Free the method itself. * Has to be done before freeing the method data, because parameter * values are typically stored in the method data, and here we may * access them. */ if (method) { int i, j; /* Free the memory allocated for the parameters that are not managed * by the selection method itself. */ for (i = 0; i < method->nparams; ++i) { gmx_ana_selparam_t *param = &method->param[i]; if (param->val.u.ptr) { if (param->val.type == GROUP_VALUE) { for (j = 0; j < param->val.nr; ++j) { gmx_ana_index_deinit(¶m->val.u.g[j]); } } else if (param->val.type == POS_VALUE) { for (j = 0; j < param->val.nr; ++j) { gmx_ana_pos_deinit(¶m->val.u.p[j]); } } if (param->val.nalloc > 0) { sfree(param->val.u.ptr); } } } sfree(method->param); sfree(method); } /* Free method data. */ if (mdata) { if (free_func) { free_func(mdata); } sfree(mdata); } }