X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcaseproto.h;h=8af1b0b4919e18af6df9ed834990ed2422ddef4d;hb=e0cbdf0daefcca81be9572aab0deedf945687f5a;hp=b0f45c418c47aae8017b0469a5307cff6b9cd7f6;hpb=07db00919d6f067fd5dd6c6c1c2c2fba4f42cf21;p=pspp diff --git a/src/data/caseproto.h b/src/data/caseproto.h index b0f45c418c..8af1b0b491 100644 --- a/src/data/caseproto.h +++ b/src/data/caseproto.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,24 +21,19 @@ #include #include #include -#include -#include -#include + +#include "data/value.h" +#include "libpspp/cast.h" +#include "libpspp/compiler.h" /* Case prototype. A case prototype specifies the number and type of the values in a case. It is essentially an array of integers, where the array index is an index into a case and each element - represents the width of a value in a case. Valid widths are: - - * 0, indicating a numeric value. - - * A positive integer between 1 and 32767, indicating the - size in bytes of a string value. - - * -1, indicating that the value at this index in the case - is not used at all. (This is rarely useful.) + represents the width of a value in a case. A width of 0 + indicates a numeric value, and any positive integer up to + MAX_STRING indicate the size in bytes of a string value. Case prototypes are reference counted. A newly created case prototype has a single owner (the code that created it), @@ -50,9 +45,7 @@ piece of code that incremented the reference count. Functions that modifying case prototypes automatically unshare - them as necessary. All of these functions potentially move - the caseproto around in memory even when the case prototype is - not shared. Thus it is very important that every caller of a + them as necessary. Thus it is very important that every caller of a function that modifies a case prototype thereafter uses the returned caseproto instead of the one passed in as an argument. @@ -63,24 +56,24 @@ struct caseproto { size_t ref_cnt; /* Reference count. */ - /* Tracking of long string widths. Lazily maintained: when - 'long_strings' is null and 'n_long_strings' is nonzero, - the former must be regenerated. */ - size_t *long_strings; /* Array of indexes of long string widths. */ - size_t n_long_strings; /* Number of long string widths. */ + /* Tracking of string widths. Lazily maintained: when 'strings' is null + and 'n_strings' is nonzero, the former must be regenerated. */ + size_t *strings; /* Array of indexes of string widths. */ + size_t n_strings; /* Number of string widths. */ /* Widths. */ size_t n_widths; /* Number of widths. */ size_t allocated_widths; /* Space allocated for 'widths' array. */ - short int widths[1]; /* Width of each case value. */ + short int *widths; /* Width of each case value. */ }; struct pool; /* Creation and destruction. */ struct caseproto *caseproto_create (void) MALLOC_LIKE; -static inline struct caseproto *caseproto_ref (const struct caseproto *); -struct caseproto *caseproto_ref_pool (const struct caseproto *, struct pool *); +struct caseproto *caseproto_from_widths (short int *, size_t n) MALLOC_LIKE; +static inline struct caseproto *caseproto_ref (const struct caseproto *) WARN_UNUSED_RESULT; +struct caseproto *caseproto_ref_pool (const struct caseproto *, struct pool *) WARN_UNUSED_RESULT; static inline void caseproto_unref (struct caseproto *); /* Inspecting stored widths. */ @@ -99,11 +92,11 @@ struct caseproto *caseproto_insert_width (struct caseproto *, size_t before, int width) WARN_UNUSED_RESULT; struct caseproto *caseproto_remove_widths (struct caseproto *, - size_t idx, size_t cnt) + size_t idx, size_t n) WARN_UNUSED_RESULT; struct caseproto *caseproto_move_widths (struct caseproto *, size_t old_start, size_t new_start, - size_t cnt) + size_t n) WARN_UNUSED_RESULT; /* Working with "union value" arrays. */ @@ -117,23 +110,23 @@ void caseproto_destroy_values (const struct caseproto *, union value[]); void caseproto_copy (const struct caseproto *, size_t idx, size_t count, union value *dst, const union value *src); -/* Inspecting the cache of long string widths. +/* Inspecting the cache of string widths. - (These functions are useful for allocating cases, which - requires allocating a block memory for each long string value - in the case.) */ -static inline size_t caseproto_get_n_long_strings (const struct caseproto *); -static inline size_t caseproto_get_long_string_idx (const struct caseproto *, - size_t idx1); + (These functions are useful for allocating cases, which requires allocating + a block of memory for each string value in the case.) */ +static inline size_t caseproto_get_n_strings (const struct caseproto *); +static inline size_t caseproto_get_string_idx (const struct caseproto *, + size_t idx1); /* For use in assertions. */ bool caseproto_range_is_valid (const struct caseproto *, size_t ofs, size_t count); bool caseproto_is_conformable (const struct caseproto *a, const struct caseproto *b); -bool caseproto_equal (const struct caseproto *a, size_t a_start, - const struct caseproto *b, size_t b_start, - size_t n); +bool caseproto_range_equal (const struct caseproto *a, size_t a_start, + const struct caseproto *b, size_t b_start, + size_t n); +bool caseproto_equal (const struct caseproto *, const struct caseproto *); /* Creation and destruction. */ @@ -157,7 +150,7 @@ caseproto_ref (const struct caseproto *proto_) static inline void caseproto_unref (struct caseproto *proto) { - if (proto != NULL && !--proto->ref_cnt) + if (proto != NULL && --proto->ref_cnt == 0) caseproto_free__ (proto); } @@ -181,30 +174,27 @@ caseproto_get_n_widths (const struct caseproto *proto) /* Inspecting the cache of long string widths. */ -void caseproto_refresh_long_string_cache__ (const struct caseproto *); +void caseproto_refresh_string_cache__ (const struct caseproto *); -/* Returns the number of long string widths in PROTO; that is, - the number of widths in PROTO that are greater than to - MAX_SHORT_STRING. */ +/* Returns the number of strings in PROTO. */ static inline size_t -caseproto_get_n_long_strings (const struct caseproto *proto) +caseproto_get_n_strings (const struct caseproto *proto) { - return proto->n_long_strings; + return proto->n_strings; } -/* Given long string width IDX1, returns a value IDX2 for which - caseproto_get_width(PROTO, IDX2) will return a value greater - than MAX_SHORT_STRING. IDX1 must be less than - caseproto_get_n_long_strings(PROTO), and IDX2 will be less - than caseproto_get_n_widths(PROTO). */ +/* Given string width IDX1, returns a value IDX2 for which + caseproto_get_width(PROTO, IDX2) will return a value greater than 0. IDX1 + must be less than caseproto_get_n_strings(PROTO), and IDX2 will be less than + caseproto_get_n_widths(PROTO). */ static inline size_t -caseproto_get_long_string_idx (const struct caseproto *proto, size_t idx1) +caseproto_get_string_idx (const struct caseproto *proto, size_t idx1) { - if (proto->long_strings == NULL) - caseproto_refresh_long_string_cache__ (proto); + if (proto->strings == NULL) + caseproto_refresh_string_cache__ (proto); - assert (idx1 < proto->n_long_strings); - return proto->long_strings[idx1]; + assert (idx1 < proto->n_strings); + return proto->strings[idx1]; } #endif /* data/caseproto.h */