Fix old typo in file merging code.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <sys/types.h>
37 #include "razor-internal.h"
41 provider_satisfies_requirement(struct razor_property *provider,
42 const char *provider_strings,
47 const char *provided = &provider_strings[provider->version];
52 if (flags & RAZOR_PROPERTY_LESS)
58 cmp = razor_versioncmp(provided, required);
60 switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
61 case RAZOR_PROPERTY_LESS:
64 case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
67 /* fall through: FIXME, make sure this is correct */
69 case RAZOR_PROPERTY_EQUAL:
73 /* "foo == 1.1" is satisfied by "foo 1.1-2" */
74 len = strlen(required);
75 if (!strncmp(required, provided, len) && provided[len] == '-')
79 case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
82 case RAZOR_PROPERTY_GREATER:
86 /* shouldn't happen */
90 #define TRANS_PACKAGE_PRESENT 1
91 #define TRANS_PACKAGE_UPDATE 2
92 #define TRANS_PROPERTY_SATISFIED 0x80000000
94 struct transaction_set {
95 struct razor_set *set;
100 struct razor_transaction {
101 int package_count, errors;
102 struct transaction_set system, upstream;
107 transaction_set_init(struct transaction_set *ts, struct razor_set *set)
112 count = set->packages.size / sizeof (struct razor_package);
113 ts->packages = zalloc(count * sizeof *ts->packages);
114 count = set->properties.size / sizeof (struct razor_property);
115 ts->properties = zalloc(count * sizeof *ts->properties);
119 transaction_set_release(struct transaction_set *ts)
122 free(ts->properties);
126 transaction_set_install_package(struct transaction_set *ts,
127 struct razor_package *package)
129 struct razor_package *pkgs;
133 pkgs = ts->set->packages.data;
135 if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
138 ts->packages[i] = TRANS_PACKAGE_PRESENT;
140 prop = list_first(&package->properties, &ts->set->property_pool);
142 ts->properties[prop->data]++;
143 prop = list_next(prop);
148 transaction_set_remove_package(struct transaction_set *ts,
149 struct razor_package *package)
151 struct razor_package *pkgs;
155 pkgs = ts->set->packages.data;
157 if (ts->packages[i] == 0)
162 prop = list_first(&package->properties, &ts->set->property_pool);
164 ts->properties[prop->data]--;
165 prop = list_next(prop);
169 RAZOR_EXPORT struct razor_transaction *
170 razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
172 struct razor_transaction *trans;
173 struct razor_package *p, *spkgs, *pend;
175 trans = zalloc(sizeof *trans);
176 transaction_set_init(&trans->system, system);
177 transaction_set_init(&trans->upstream, upstream);
179 spkgs = trans->system.set->packages.data;
180 pend = trans->system.set->packages.data +
181 trans->system.set->packages.size;
182 for (p = spkgs; p < pend; p++)
183 transaction_set_install_package(&trans->system, p);
189 razor_transaction_install_package(struct razor_transaction *trans,
190 struct razor_package *package)
192 assert (trans != NULL);
193 assert (package != NULL);
195 transaction_set_install_package(&trans->upstream, package);
200 razor_transaction_remove_package(struct razor_transaction *trans,
201 struct razor_package *package)
203 assert (trans != NULL);
204 assert (package != NULL);
206 transaction_set_remove_package(&trans->system, package);
211 razor_transaction_update_package(struct razor_transaction *trans,
212 struct razor_package *package)
214 struct razor_package *spkgs, *upkgs, *end;
216 assert (trans != NULL);
217 assert (package != NULL);
219 spkgs = trans->system.set->packages.data;
220 upkgs = trans->upstream.set->packages.data;
221 end = trans->system.set->packages.data +
222 trans->system.set->packages.size;
223 if (spkgs <= package && package < end)
224 trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
226 trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
230 struct razor_property *p, *start, *end;
236 prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
238 pi->p = ts->set->properties.data;
239 pi->start = ts->set->properties.data;
240 pi->end = ts->set->properties.data + ts->set->properties.size;
241 pi->pool = ts->set->string_pool.data;
242 pi->present = ts->properties;
246 prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
248 while (pi->p < pi->end) {
249 if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
250 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
260 static struct razor_property *
261 prop_iter_seek_to(struct prop_iter *pi,
262 uint32_t flags, const char *match)
266 while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
269 if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
273 while (pi->p < pi->end &&
274 pi->p->name == name &&
275 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
278 if (pi->p == pi->end || pi->p->name != name)
284 /* Remove packages from set that provide any of the matching (same
285 * name and type) providers from ppi onwards that match the
286 * requirement that rpi points to. */
288 remove_matching_providers(struct razor_transaction *trans,
289 struct prop_iter *ppi,
293 struct razor_property *p;
294 struct razor_package *pkg, *pkgs;
295 struct razor_package_iterator pkg_iter;
296 struct razor_set *set;
300 if (ppi->present == trans->system.properties)
301 set = trans->system.set;
303 set = trans->upstream.set;
305 pkgs = (struct razor_package *) set->packages.data;
306 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
309 p->name == ppi->p->name &&
310 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
312 if (!ppi->present[p - ppi->start])
314 if (!provider_satisfies_requirement(p, ppi->pool,
318 razor_package_iterator_init_for_property(&pkg_iter, set, p);
319 while (razor_package_iterator_next(&pkg_iter, &pkg,
320 RAZOR_DETAIL_NAME, &n,
321 RAZOR_DETAIL_VERSION, &v,
322 RAZOR_DETAIL_LAST)) {
323 fprintf(stderr, "removing %s-%s\n", n, v);
324 razor_transaction_remove_package(trans, pkg);
330 flag_matching_providers(struct razor_transaction *trans,
331 struct prop_iter *ppi,
332 struct razor_property *r,
333 struct prop_iter *rpi,
336 struct razor_property *p;
337 struct razor_package *pkg, *pkgs;
338 struct razor_package_iterator pkg_iter;
339 struct razor_set *set;
340 const char *name, *version;
341 uint32_t *flags, type;
343 if (ppi->present == trans->system.properties) {
344 set = trans->system.set;
345 flags = trans->system.packages;
347 set = trans->upstream.set;
348 flags = trans->upstream.packages;
351 pkgs = (struct razor_package *) set->packages.data;
352 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
355 p->name == ppi->p->name &&
356 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
358 if (!ppi->present[p - ppi->start])
360 if (!provider_satisfies_requirement(p, ppi->pool,
362 &rpi->pool[r->version]))
365 razor_package_iterator_init_for_property(&pkg_iter, set, p);
366 while (razor_package_iterator_next(&pkg_iter, &pkg,
367 RAZOR_DETAIL_NAME, &name,
368 RAZOR_DETAIL_VERSION, &version,
369 RAZOR_DETAIL_LAST)) {
371 fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
375 rpi->pool + r->version);
376 flags[pkg - pkgs] |= flag;
381 static struct razor_package *
382 pick_matching_provider(struct razor_set *set,
383 struct prop_iter *ppi,
387 struct razor_property *p;
388 struct razor_package *pkgs;
392 /* This is where we decide which pkgs to pull in to satisfy a
393 * requirement. There may be several different providers
394 * (different versions) and each version of a provider may
395 * come from a number of packages. We pick the first package
396 * from the first provider that matches. */
398 pkgs = set->packages.data;
399 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
402 p->name == ppi->p->name &&
403 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
404 ppi->present[p - ppi->start] == 0;
406 if (!provider_satisfies_requirement(p, ppi->pool,
410 i = list_first(&p->packages, &set->package_pool);
412 return &pkgs[i->data];
419 remove_obsoleted_packages(struct razor_transaction *trans)
421 struct razor_property *up;
422 struct razor_package *spkgs;
423 struct prop_iter spi, upi;
425 spkgs = trans->system.set->packages.data;
426 prop_iter_init(&spi, &trans->system);
427 prop_iter_init(&upi, &trans->upstream);
429 while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
430 if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
431 &upi.pool[up->name]))
433 remove_matching_providers(trans, &spi, up->flags,
434 &upi.pool[up->version]);
439 any_provider_satisfies_requirement(struct prop_iter *ppi,
443 struct razor_property *p;
446 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
449 p->name == ppi->p->name &&
450 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
452 if (ppi->present[p - ppi->start] > 0 &&
453 provider_satisfies_requirement(p, ppi->pool,
462 clear_requires_flags(struct transaction_set *ts)
464 struct razor_property *p;
468 count = ts->set->properties.size / sizeof *p;
469 p = ts->set->properties.data;
470 pool = ts->set->string_pool.data;
471 for (i = 0; i < count; i++) {
472 ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
473 if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
474 ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
479 mark_satisfied_requires(struct razor_transaction *trans,
480 struct transaction_set *rts,
481 struct transaction_set *pts)
483 struct prop_iter rpi, ppi;
484 struct razor_property *rp;
486 prop_iter_init(&rpi, rts);
487 prop_iter_init(&ppi, pts);
489 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
490 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
491 &rpi.pool[rp->name]))
494 if (any_provider_satisfies_requirement(&ppi, rp->flags,
495 &rpi.pool[rp->version]))
496 rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
501 mark_all_satisfied_requires(struct razor_transaction *trans)
503 clear_requires_flags(&trans->system);
504 clear_requires_flags(&trans->upstream);
505 mark_satisfied_requires(trans, &trans->system, &trans->system);
506 mark_satisfied_requires(trans, &trans->system, &trans->upstream);
507 mark_satisfied_requires(trans, &trans->upstream, &trans->system);
508 mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
512 update_unsatisfied_packages(struct razor_transaction *trans)
514 struct razor_package *spkgs, *pkg;
515 struct razor_property *sp;
516 struct prop_iter spi;
517 struct razor_package_iterator pkg_iter;
520 spkgs = trans->system.set->packages.data;
521 prop_iter_init(&spi, &trans->system);
523 while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
524 if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
527 razor_package_iterator_init_for_property(&pkg_iter,
530 while (razor_package_iterator_next(&pkg_iter, &pkg,
531 RAZOR_DETAIL_NAME, &name,
532 RAZOR_DETAIL_LAST)) {
533 fprintf(stderr, "updating %s because %s %s %s "
535 name, spi.pool + sp->name,
536 razor_property_relation_to_string(sp),
537 spi.pool + sp->version);
538 trans->system.packages[pkg - spkgs] |=
539 TRANS_PACKAGE_UPDATE;
545 razor_transaction_update_all(struct razor_transaction *trans)
547 struct razor_package *p;
550 assert (trans != NULL);
552 count = trans->system.set->packages.size / sizeof *p;
553 for (i = 0; i < count; i++)
554 trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
558 update_conflicted_packages(struct razor_transaction *trans)
560 struct razor_package *pkg, *spkgs;
561 struct razor_property *up, *sp;
562 struct prop_iter spi, upi;
563 struct razor_package_iterator pkg_iter;
564 const char *name, *version;
566 spkgs = trans->system.set->packages.data;
567 prop_iter_init(&spi, &trans->system);
568 prop_iter_init(&upi, &trans->upstream);
570 while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
571 if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
572 &spi.pool[sp->name]))
575 if (!any_provider_satisfies_requirement(&upi, sp->flags,
576 &spi.pool[sp->version]))
579 razor_package_iterator_init_for_property(&pkg_iter,
582 while (razor_package_iterator_next(&pkg_iter, &pkg,
583 RAZOR_DETAIL_NAME, &name,
584 RAZOR_DETAIL_VERSION, &version,
585 RAZOR_DETAIL_LAST)) {
586 fprintf(stderr, "updating %s %s because it "
587 "conflicts with %s\n",
588 name, version, spi.pool + sp->name);
589 trans->system.packages[pkg - spkgs] |=
590 TRANS_PACKAGE_UPDATE;
594 prop_iter_init(&spi, &trans->system);
595 prop_iter_init(&upi, &trans->upstream);
597 while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
598 sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
599 &upi.pool[upi.p->name]);
602 flag_matching_providers(trans, &spi, up, &upi,
603 TRANS_PACKAGE_UPDATE);
608 pull_in_requirements(struct razor_transaction *trans,
609 struct prop_iter *rpi, struct prop_iter *ppi)
611 struct razor_property *rp, *pp;
612 struct razor_package *pkg, *upkgs;
614 upkgs = trans->upstream.set->packages.data;
615 while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
616 if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
619 pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
620 &rpi->pool[rp->name]);
623 pkg = pick_matching_provider(trans->upstream.set,
625 &rpi->pool[rp->version]);
629 rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
631 fprintf(stderr, "pulling in %s-%s.%s which provides %s %s %s "
632 "to satisfy %s %s %s\n",
633 ppi->pool + pkg->name,
634 ppi->pool + pkg->version,
635 ppi->pool + pkg->arch,
636 ppi->pool + pp->name,
637 razor_property_relation_to_string(pp),
638 ppi->pool + pp->version,
639 &rpi->pool[rp->name],
640 razor_property_relation_to_string(rp),
641 &rpi->pool[rp->version]);
643 trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
648 pull_in_all_requirements(struct razor_transaction *trans)
650 struct prop_iter rpi, ppi;
652 prop_iter_init(&rpi, &trans->system);
653 prop_iter_init(&ppi, &trans->upstream);
654 pull_in_requirements(trans, &rpi, &ppi);
656 prop_iter_init(&rpi, &trans->upstream);
657 prop_iter_init(&ppi, &trans->upstream);
658 pull_in_requirements(trans, &rpi, &ppi);
662 flush_scheduled_system_updates(struct razor_transaction *trans)
664 struct razor_package_iterator *pi;
665 struct razor_package *p, *pkg, *spkgs;
666 struct prop_iter ppi;
667 const char *name, *version;
669 spkgs = trans->system.set->packages.data;
670 pi = razor_package_iterator_create(trans->system.set);
671 prop_iter_init(&ppi, &trans->upstream);
673 while (razor_package_iterator_next(pi, &p,
674 RAZOR_DETAIL_NAME, &name,
675 RAZOR_DETAIL_VERSION, &version,
676 RAZOR_DETAIL_LAST)) {
677 if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
680 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
683 pkg = pick_matching_provider(trans->upstream.set, &ppi,
684 RAZOR_PROPERTY_GREATER, version);
688 fprintf(stderr, "updating %s-%s to %s-%s\n",
690 &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
692 razor_transaction_remove_package(trans, p);
693 razor_transaction_install_package(trans, pkg);
696 razor_package_iterator_destroy(pi);
700 flush_scheduled_upstream_updates(struct razor_transaction *trans)
702 struct razor_package_iterator *pi;
703 struct razor_package *p, *upkgs;
704 struct prop_iter spi;
705 const char *name, *version;
707 upkgs = trans->upstream.set->packages.data;
708 pi = razor_package_iterator_create(trans->upstream.set);
709 prop_iter_init(&spi, &trans->system);
711 while (razor_package_iterator_next(pi, &p,
712 RAZOR_DETAIL_NAME, &name,
713 RAZOR_DETAIL_VERSION, &version,
714 RAZOR_DETAIL_LAST)) {
715 if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
718 if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
719 remove_matching_providers(trans,
723 razor_transaction_install_package(trans, p);
724 fprintf(stderr, "installing %s-%s\n", name, version);
729 razor_transaction_resolve(struct razor_transaction *trans)
733 flush_scheduled_system_updates(trans);
734 flush_scheduled_upstream_updates(trans);
736 while (last < trans->changes) {
737 last = trans->changes;
738 remove_obsoleted_packages(trans);
739 mark_all_satisfied_requires(trans);
740 update_unsatisfied_packages(trans);
741 update_conflicted_packages(trans);
742 pull_in_all_requirements(trans);
743 flush_scheduled_system_updates(trans);
744 flush_scheduled_upstream_updates(trans);
747 return trans->changes;
751 describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
753 struct razor_package_iterator pi;
754 struct razor_package *pkg;
755 const char *name, *version, *arch, *pool;
757 pool = set->string_pool.data;
758 if (pool[rp->version] == '\0') {
759 razor_package_iterator_init_for_property(&pi, set, rp);
760 while (razor_package_iterator_next(&pi, &pkg,
761 RAZOR_DETAIL_NAME, &name,
762 RAZOR_DETAIL_VERSION, &version,
763 RAZOR_DETAIL_ARCH, &arch,
765 fprintf(stderr, "%s is needed by %s-%s.%s\n",
767 name, version, arch);
769 razor_package_iterator_init_for_property(&pi, set, rp);
770 while (razor_package_iterator_next(&pi, &pkg,
771 RAZOR_DETAIL_NAME, &name,
772 RAZOR_DETAIL_VERSION, &version,
773 RAZOR_DETAIL_ARCH, &arch,
775 fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
777 razor_property_relation_to_string(rp),
779 name, version, arch);
784 razor_transaction_describe(struct razor_transaction *trans)
786 struct prop_iter rpi;
787 struct razor_property *rp;
790 flush_scheduled_system_updates(trans);
791 flush_scheduled_upstream_updates(trans);
792 mark_all_satisfied_requires(trans);
795 prop_iter_init(&rpi, &trans->system);
796 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
797 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
798 describe_unsatisfied(trans->system.set, rp);
803 prop_iter_init(&rpi, &trans->upstream);
804 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
805 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
806 describe_unsatisfied(trans->upstream.set, rp);
815 razor_transaction_unsatisfied_property(struct razor_transaction *trans,
821 struct razor_property *p;
823 prop_iter_init(&pi, &trans->system);
824 while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
825 if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
827 strcmp(&pi.pool[p->name], name) == 0 &&
828 strcmp(&pi.pool[p->version], version) == 0)
833 prop_iter_init(&pi, &trans->upstream);
834 while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
835 if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
837 strcmp(&pi.pool[p->name], name) == 0 &&
838 strcmp(&pi.pool[p->version], version) == 0)
846 RAZOR_EXPORT struct razor_set *
847 razor_transaction_finish(struct razor_transaction *trans)
849 struct razor_merger *merger;
850 struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
854 s = trans->system.set->packages.data;
855 spkgs = trans->system.set->packages.data;
856 send = trans->system.set->packages.data +
857 trans->system.set->packages.size;
858 spool = trans->system.set->string_pool.data;
860 u = trans->upstream.set->packages.data;
861 upkgs = trans->upstream.set->packages.data;
862 uend = trans->upstream.set->packages.data +
863 trans->upstream.set->packages.size;
864 upool = trans->upstream.set->string_pool.data;
866 merger = razor_merger_create(trans->system.set, trans->upstream.set);
867 while (s < send || u < uend) {
868 if (s < send && u < uend)
869 cmp = strcmp(&spool[s->name], &upool[u->name]);
876 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
877 razor_merger_add_package(merger, s);
879 } else if (cmp == 0) {
880 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
881 razor_merger_add_package(merger, s);
882 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
883 razor_merger_add_package(merger, u);
888 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
889 razor_merger_add_package(merger, u);
894 razor_transaction_destroy(trans);
896 return razor_merger_finish(merger);
900 razor_transaction_destroy(struct razor_transaction *trans)
902 assert (trans != NULL);
904 transaction_set_release(&trans->system);
905 transaction_set_release(&trans->upstream);