diff --git a/src/data/case.c b/src/data/case.c index dc40292..36aa539 100644 --- a/src/data/case.c +++ b/src/data/case.c @@ -65,7 +65,9 @@ case_try_create (const struct caseproto *proto) if (caseproto_try_init_values (proto, c->values)) { c->proto = caseproto_ref (proto); +#if ! DEBUG_CASEREFS c->ref_cnt = 1; +#endif return c; } free (c); @@ -148,7 +150,9 @@ case_unshare_and_resize (struct ccase *c, const struct caseproto *proto) size_t old_n_values = caseproto_get_n_widths (c->proto); size_t new_n_values = caseproto_get_n_widths (proto); case_copy (new, 0, c, 0, MIN (old_n_values, new_n_values)); +#if ! DEBUG_CASEREFS c->ref_cnt--; +#endif return new; } } @@ -420,7 +424,9 @@ case_unshare__ (struct ccase *old) { struct ccase *new = case_create (old->proto); case_copy (new, 0, old, 0, caseproto_get_n_widths (new->proto)); +#if ! DEBUG_CASEREFS --old->ref_cnt; +#endif return new; } diff --git a/src/data/case.h b/src/data/case.h index d00c2ad..c6f68ae 100644 --- a/src/data/case.h +++ b/src/data/case.h @@ -24,6 +24,9 @@ #include #include +/* Set to non-zero to use deep copying instead of reference counting */ +#define DEBUG_CASEREFS 1 + struct variable; /* A count of cases or the index of a case within a collection of @@ -52,7 +55,9 @@ typedef long int casenumber; struct ccase { struct caseproto *proto; /* Case prototype. */ +#if DEGBUG_CASEREFS size_t ref_cnt; /* Reference count. */ +#endif union value values[1]; /* Values. */ }; @@ -61,7 +66,7 @@ struct ccase *case_try_create (const struct caseproto *) MALLOC_LIKE; struct ccase *case_clone (const struct ccase *) MALLOC_LIKE; static inline struct ccase *case_unshare (struct ccase *) WARN_UNUSED_RESULT; -static inline struct ccase *case_ref (const struct ccase *); +static inline struct ccase *case_ref (const struct ccase *) WARN_UNUSED_RESULT; static inline void case_unref (struct ccase *); static inline bool case_is_shared (const struct ccase *); @@ -135,9 +140,13 @@ case_unshare (struct ccase *c) static inline struct ccase * case_ref (const struct ccase *c_) { +#if DEBUG_CASEREFS + return case_unshare__ (CONST_CAST (struct ccase *,c_)); +#else struct ccase *c = CONST_CAST (struct ccase *, c_); c->ref_cnt++; return c; +#endif } /* Decrements case C's reference count. Frees C if its @@ -147,18 +156,29 @@ case_ref (const struct ccase *c_) static inline void case_unref (struct ccase *c) { - if (c != NULL && !--c->ref_cnt) - case_unref__ (c); + if (c != NULL) +#if ! DEBUG_CASEREFS + if (!--c->ref_cnt) +#endif + case_unref__ (c); } /* Returns true if case C is shared. A case that is shared cannot be modified directly. Instead, an unshared copy must first be made with case_unshare(). */ +#if DEBUG_CASEREFS +static inline bool +case_is_shared (const struct ccase *c UNUSED) +{ + return false; +} +#else static inline bool case_is_shared (const struct ccase *c) { return c->ref_cnt > 1; } +#endif /* Returns the number of union values in C. */ static inline size_t