Introduce xbps_array_add_first() to insert obj at the head of array.

The behaviour of this routine mimics the existing xbps_array_add() with
the difference that stored objects are moved to the right to insert
our object as the first element on the array.

Use this to add replaced packages in the transaction array at the head
rather than at the end, to preserve the proper sorting order.
This commit is contained in:
Juan RP 2014-11-13 15:18:21 +01:00
parent 74c30556fc
commit 43c9497feb
6 changed files with 70 additions and 2 deletions

View File

@ -48,7 +48,7 @@
*
* This header documents the full API for the XBPS Library.
*/
#define XBPS_API_VERSION "20141107"
#define XBPS_API_VERSION "20141113"
#ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET"

View File

@ -59,6 +59,7 @@ xbps_object_iterator_t xbps_array_iterator(xbps_array_t);
xbps_object_t xbps_array_get(xbps_array_t, unsigned int);
bool xbps_array_set(xbps_array_t, unsigned int, xbps_object_t);
bool xbps_array_add(xbps_array_t, xbps_object_t);
bool xbps_array_add_first(xbps_array_t, xbps_object_t);
void xbps_array_remove(xbps_array_t, unsigned int);
bool xbps_array_equals(xbps_array_t, xbps_array_t);

View File

@ -59,6 +59,7 @@ prop_object_iterator_t prop_array_iterator(prop_array_t);
prop_object_t prop_array_get(prop_array_t, unsigned int);
bool prop_array_set(prop_array_t, unsigned int, prop_object_t);
bool prop_array_add(prop_array_t, prop_object_t);
bool prop_array_add_first(prop_array_t, prop_object_t);
void prop_array_remove(prop_array_t, unsigned int);
bool prop_array_equals(prop_array_t, prop_array_t);

View File

@ -615,6 +615,45 @@ _prop_array_add(prop_array_t pa, prop_object_t po)
return (true);
}
static bool
_prop_array_add_first(prop_array_t pa, prop_object_t po)
{
unsigned int cnt;
/*
* Array must be WRITE-LOCKED.
*/
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
if (prop_array_is_immutable(pa) ||
(pa->pa_count == pa->pa_capacity &&
_prop_array_expand(pa, pa->pa_capacity + EXPAND_STEP) == false))
return false;
prop_object_retain(po);
if (pa->pa_count) {
cnt = pa->pa_count+1;
/* move all stored elements to the right */
while (--cnt) {
prop_object_t opo = pa->pa_array[cnt-1];
_PROP_ASSERT(opo != NULL);
prop_object_retain(opo);
pa->pa_array[cnt] = opo;
prop_object_release(opo);
printf("%s: po %p\n", __func__, pa->pa_array[cnt]);
}
/* passed in object is now the first element */
pa->pa_array[0] = po;
pa->pa_version++;
pa->pa_count++;
printf("%s: po %p\n", __func__, pa->pa_array[0]);
} else {
pa->pa_array[pa->pa_count++] = po;
pa->pa_version++;
}
return true;
}
/*
* prop_array_set --
* Store a reference to an object at the specified array index.
@ -679,6 +718,26 @@ prop_array_add(prop_array_t pa, prop_object_t po)
return (rv);
}
/*
* prop_array_add_first --
* Add a reference to an object to the specified array, inserting it
* as first element, moving all objects to the right and growing the
* array's capacity, if necessary.
*/
bool
prop_array_add_first(prop_array_t pa, prop_object_t po)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
rv = _prop_array_add_first(pa, po);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_remove --
* Remove the reference to an object from an array at the specified

View File

@ -112,6 +112,12 @@ xbps_array_add(xbps_array_t a, xbps_object_t obj)
return prop_array_add(a, obj);
}
bool
xbps_array_add_first(xbps_array_t a, xbps_object_t obj)
{
return prop_array_add_first(a, obj);
}
void
xbps_array_remove(xbps_array_t a, unsigned int i)
{

View File

@ -123,7 +123,8 @@ xbps_transaction_package_replace(struct xbps_handle *xhp, xbps_array_t pkgs)
*/
xbps_dictionary_set_cstring_nocopy(instd,
"transaction", "remove");
xbps_array_add(pkgs, instd);
if (!xbps_array_add_first(pkgs, instd))
return EINVAL;
free(curpkgname);
}
xbps_object_iterator_release(iter);