Abstract out dive/sample allocation a bit

We're going to start to want to allocate dives and samples for the
libdivecomputer import too, so let's clean things up a bit for that.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2011-09-12 12:56:34 -07:00
parent d45db9fac7
commit aa416e3c96
3 changed files with 64 additions and 49 deletions

73
dive.c
View file

@ -3,6 +3,51 @@
#include "dive.h" #include "dive.h"
struct dive *alloc_dive(void)
{
const int initial_samples = 5;
unsigned int size;
struct dive *dive;
size = dive_size(initial_samples);
dive = malloc(size);
if (!dive)
exit(1);
memset(dive, 0, size);
dive->alloc_samples = initial_samples;
return dive;
}
struct sample *prepare_sample(struct dive **divep)
{
struct dive *dive = *divep;
if (dive) {
int nr = dive->samples;
int alloc_samples = dive->alloc_samples;
struct sample *sample;
if (nr >= alloc_samples) {
unsigned int size;
alloc_samples = (alloc_samples * 3)/2 + 10;
size = dive_size(alloc_samples);
dive = realloc(dive, size);
if (!dive)
return NULL;
dive->alloc_samples = alloc_samples;
*divep = dive;
}
sample = dive->sample + nr;
memset(sample, 0, sizeof(*sample));
return sample;
}
return NULL;
}
void finish_sample(struct dive *dive, struct sample *sample)
{
dive->samples++;
}
/* /*
* So when we re-calculate maxdepth and meandepth, we will * So when we re-calculate maxdepth and meandepth, we will
* not override the old numbers if they are close to the * not override the old numbers if they are close to the
@ -133,24 +178,15 @@ struct dive *fixup_dive(struct dive *dive)
#define MERGE_MAX(res, a, b, n) res->n = MAX(a->n, b->n) #define MERGE_MAX(res, a, b, n) res->n = MAX(a->n, b->n)
#define MERGE_MIN(res, a, b, n) res->n = (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n) #define MERGE_MIN(res, a, b, n) res->n = (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n)
static int alloc_samples;
static struct dive *add_sample(struct sample *sample, int time, struct dive *dive) static struct dive *add_sample(struct sample *sample, int time, struct dive *dive)
{ {
int nr = dive->samples; struct sample *p = prepare_sample(&dive);
struct sample *d;
if (nr >= alloc_samples) { if (!p)
alloc_samples = (alloc_samples + 64) * 3 / 2; return NULL;
dive = realloc(dive, dive_size(alloc_samples)); *p = *sample;
if (!dive) p->time.seconds = time;
return NULL; finish_sample(dive, p);
}
dive->samples = nr+1;
d = dive->sample + nr;
*d = *sample;
d->time.seconds = time;
return dive; return dive;
} }
@ -274,15 +310,12 @@ struct dive *try_to_merge(struct dive *a, struct dive *b)
if (a->when != b->when) if (a->when != b->when)
return NULL; return NULL;
alloc_samples = 5; res = alloc_dive();
res = malloc(dive_size(alloc_samples));
if (!res)
return NULL;
memset(res, 0, dive_size(alloc_samples));
res->when = a->when; res->when = a->when;
res->location = merge_text(a->location, b->location); res->location = merge_text(a->location, b->location);
res->notes = merge_text(a->notes, b->notes); res->notes = merge_text(a->notes, b->notes);
MERGE_MAX(res, a, b, number);
MERGE_MAX(res, a, b, maxdepth.mm); MERGE_MAX(res, a, b, maxdepth.mm);
res->meandepth.mm = 0; res->meandepth.mm = 0;
MERGE_MAX(res, a, b, duration.seconds); MERGE_MAX(res, a, b, duration.seconds);

8
dive.h
View file

@ -137,7 +137,7 @@ struct dive {
depth_t visibility; depth_t visibility;
temperature_t airtemp, watertemp; temperature_t airtemp, watertemp;
cylinder_t cylinder[MAX_CYLINDERS]; cylinder_t cylinder[MAX_CYLINDERS];
int samples; int samples, alloc_samples;
struct sample sample[]; struct sample sample[];
}; };
@ -193,6 +193,12 @@ static inline unsigned int dive_size(int samples)
return sizeof(struct dive) + samples*sizeof(struct sample); return sizeof(struct dive) + samples*sizeof(struct sample);
} }
extern struct dive *alloc_dive(void);
extern void record_dive(struct dive *dive);
extern struct sample *prepare_sample(struct dive **divep);
extern void finish_sample(struct dive *dive, struct sample *sample);
extern struct dive *fixup_dive(struct dive *dive); extern struct dive *fixup_dive(struct dive *dive);
extern struct dive *try_to_merge(struct dive *a, struct dive *b); extern struct dive *try_to_merge(struct dive *a, struct dive *b);

View file

@ -16,7 +16,7 @@ struct dive_table dive_table;
/* /*
* Add a dive into the dive_table array * Add a dive into the dive_table array
*/ */
static void record_dive(struct dive *dive) void record_dive(struct dive *dive)
{ {
int nr = dive_table.nr, allocated = dive_table.allocated; int nr = dive_table.nr, allocated = dive_table.allocated;
struct dive **dives = dive_table.dives; struct dive **dives = dive_table.dives;
@ -90,7 +90,6 @@ const struct units IMPERIAL_units = {
/* /*
* Dive info as it is being built up.. * Dive info as it is being built up..
*/ */
static int alloc_samples;
static struct dive *dive; static struct dive *dive;
static struct sample *sample; static struct sample *sample;
static struct tm tm; static struct tm tm;
@ -984,17 +983,9 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
*/ */
static void dive_start(void) static void dive_start(void)
{ {
unsigned int size;
if (dive) if (dive)
return; return;
dive = alloc_dive();
alloc_samples = 5;
size = dive_size(alloc_samples);
dive = malloc(size);
if (!dive)
exit(1);
memset(dive, 0, size);
memset(&tm, 0, sizeof(tm)); memset(&tm, 0, sizeof(tm));
} }
@ -1143,22 +1134,7 @@ static void cylinder_end(void)
static void sample_start(void) static void sample_start(void)
{ {
int nr; sample = prepare_sample(&dive);
if (!dive)
return;
nr = dive->samples;
if (nr >= alloc_samples) {
unsigned int size;
alloc_samples = (alloc_samples * 3)/2 + 10;
size = dive_size(alloc_samples);
dive = realloc(dive, size);
if (!dive)
return;
}
sample = dive->sample + nr;
memset(sample, 0, sizeof(*sample));
event_index = 0; event_index = 0;
} }
@ -1167,8 +1143,8 @@ static void sample_end(void)
if (!dive) if (!dive)
return; return;
finish_sample(dive, sample);
sample = NULL; sample = NULL;
dive->samples++;
} }
static void entry(const char *name, int size, const char *raw) static void entry(const char *name, int size, const char *raw)