Skip to content

Commit

Permalink
Simplify gnc_commodity equality and compare functions.
Browse files Browse the repository at this point in the history
gnc_commodity_compare is used for sorting and so needs to have a less-than
return value. The only place it's used presents nothing to the UI; a GncGUID
ordering is fast and stable.

GnuCash allows only one commodity per book for any namespace/mnemonic pair, so
the exhaustive string comparisons are superflous. While the current engine
design allows only one instance of any object, meaning that a pointer comparison
is sufficient to determine equality, that may not be true in the future, but the
GncGUID is guaranteed to sufficiently identify a single commodity. Note that
gnc_commodity_equiv is used to enforce that single-commodity rule and so cannot
use GncGUID comparison.
  • Loading branch information
jralls committed Jan 24, 2023
1 parent a81b72f commit 46f9fb0
Showing 1 changed file with 12 additions and 59 deletions.
71 changes: 12 additions & 59 deletions libgnucash/engine/gnc-commodity.c
Expand Up @@ -38,6 +38,8 @@
#include "gnc-commodity.h"
#include "gnc-locale-utils.h"
#include "gnc-prefs.h"
#include "guid.h"
#include "qofinstance.h"

static QofLogModule log_module = GNC_MOD_COMMODITY;

Expand Down Expand Up @@ -1647,77 +1649,28 @@ gnc_commodity_equiv(const gnc_commodity * a, const gnc_commodity * b)
priv_b = GET_PRIVATE(b);
if (priv_a->name_space != priv_b->name_space) return FALSE;
if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0) return FALSE;

return TRUE;
}

gboolean
gnc_commodity_equal(const gnc_commodity * a, const gnc_commodity * b)
{
gnc_commodityPrivate* priv_a;
gnc_commodityPrivate* priv_b;
gboolean same_book;

if (a == b) return TRUE;

if (!a || !b)
{
DEBUG ("one is NULL");
return FALSE;
}

priv_a = GET_PRIVATE(a);
priv_b = GET_PRIVATE(b);
same_book = qof_instance_get_book(QOF_INSTANCE(a)) == qof_instance_get_book(QOF_INSTANCE(b));

if ((same_book && priv_a->name_space != priv_b->name_space)
|| (!same_book && g_strcmp0( gnc_commodity_namespace_get_name(priv_a->name_space),
gnc_commodity_namespace_get_name(priv_b->name_space)) != 0))
{
DEBUG ("namespaces differ: %p(%s) vs %p(%s)",
priv_a->name_space, gnc_commodity_namespace_get_name(priv_a->name_space),
priv_b->name_space, gnc_commodity_namespace_get_name(priv_b->name_space));
return FALSE;
}

if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0)
{
DEBUG ("mnemonics differ: %s vs %s", priv_a->mnemonic, priv_b->mnemonic);
return FALSE;
}

if (g_strcmp0(priv_a->fullname, priv_b->fullname) != 0)
{
DEBUG ("fullnames differ: %s vs %s", priv_a->fullname, priv_b->fullname);
return FALSE;
}

if (g_strcmp0(priv_a->cusip, priv_b->cusip) != 0)
{
DEBUG ("cusips differ: %s vs %s", priv_a->cusip, priv_b->cusip);
return FALSE;
}

if (priv_a->fraction != priv_b->fraction)
{
DEBUG ("fractions differ: %d vs %d", priv_a->fraction, priv_b->fraction);
return FALSE;
}

return TRUE;
return gnc_commodity_compare(a, b) == 0;
}

// Used as a sorting callback for deleting old prices, so it needs to be
// stable but doesn't need to be in any particular order sensible to humans.
int gnc_commodity_compare(const gnc_commodity * a, const gnc_commodity * b)
{
if (gnc_commodity_equal(a, b))
{
return 0;
}
else
{
return 1;
}
if (a == b) return 0;
if (a && !b) return 1;
if (b && !a) return -1;
return qof_instance_guid_compare(a, b);
}

// Used as a callback to g_list_find_custom, it should return 0
// when the commodities match.
int gnc_commodity_compare_void(const void * a, const void * b)
{
return gnc_commodity_compare(a, b);
Expand Down

0 comments on commit 46f9fb0

Please sign in to comment.