~pixelherodev/DSM-9

a7be5f12b0c6d3e90b38818f8d802db84f3f55c2 — Noam Preil a month ago 78cc8aa
Optimize deck loading
3 files changed, 52 insertions(+), 45 deletions(-)

M cli.c
M sm2.c
M sm2.h
M cli.c => cli.c +1 -0
@@ 11,6 11,7 @@
struct sm2_instance instance;
ulong max_cards, start;
int html, all;
char *path;
int offset;

void

M sm2.c => sm2.c +47 -42
@@ 8,70 8,76 @@ void sm2_init(struct sm2_instance *instance){
	instance->cards = nil;
	instance->delimiter = "@@@";
	instance->card_count = 0;
	instance->card_cap = 0;
}

void
card_init(struct sm2_card *card, char *path)
{
	card->field_count = 0;
	card->fields = nil;
	card->next_due = 0;
	card->interval = 1;
	card->repetitions = 0;
	card->easiness = 2.5;
	card->path = path;
}

static struct sm2_card *sm2_find_card(struct sm2_instance *instance, char *id){
	for (unsigned long i = 0; i < instance->card_count; i += 1){
		if(strcmp(instance->cards[i].id, id) == 0){
	for(unsigned long i = 0; i < instance->card_count; i += 1)
		if(strcmp(instance->cards[i].id, id) == 0)
 			return &instance->cards[i];
		}
	}
	return nil;
}

static
struct sm2_card *appendcard(struct sm2_instance *instance)
{
	if(instance->card_count == instance->card_cap){
		instance->card_cap = instance->card_cap * 4 + 8;
		instance->cards = realloc(instance->cards, sizeof(struct sm2_card) * instance->card_cap);
		if(instance->cards == nil)
			sysfatal("Out of memory");
	}
	instance->card_count += 1;
	return &instance->cards[instance->card_count - 1];
}

int sm2_load_deck(struct sm2_instance *instance, char *deck, int overwrite, char *path){
	char *line = strtok(deck, "\n");
	int count;
	count = 0;
	ulong oldcount = instance->card_count;
	struct sm2_card *card;
	while(line != 0){
		if(*line == '#') {
			line = strtok(nil, "\n");
			continue;
		}
		char *delim = strstr(line, instance->delimiter);
		struct sm2_card *card;
		if(delim == nil){
			card = sm2_find_card(instance, line);
			if (card != nil){
				if(overwrite == 0){
					line = strtok(nil, "\n");
					continue;
				}
			}
			else {
				count += 1;
				instance->card_count += 1;
				instance->cards = realloc(instance->cards, sizeof(struct sm2_card) * instance->card_count);
				card = &instance->cards[instance->card_count - 1];
			if(overwrite){
				card = sm2_find_card(instance, line);
				if(card == nil)
					card = appendcard(instance);
			}
			else
				card = appendcard(instance);
			card->id = line;
		} else {
			long len = delim - line;
			char *id = malloc(len + 1);
			strncpy(id, line, len);
			id[len] = 0;
			card = sm2_find_card(instance, id);
			if (card != nil){
				if (overwrite > 0) {
					free(id);
					line = strtok(nil, "\n");
					continue;
				}
			} else {
				count += 1;
				instance->card_count += 1;
				instance->cards = realloc(instance->cards, sizeof(struct sm2_card) * instance->card_count);
				card = &instance->cards[instance->card_count - 1];
				card->id = id;
			if(overwrite){
				card = sm2_find_card(instance, line);
				if(card == nil)
					card = appendcard(instance);
			}
			else
				card = appendcard(instance);
			card->id = id;
		}

		card->field_count = 0;
		card->path = path;
		card->fields = nil;
		card->next_due = 0;
		card->interval = 1;
		card->repetitions = 0;
		card->easiness = 2.5;
		card_init(card, path);

		if(delim == nil){
			// Only field on the line is ID


@@ 98,12 104,11 @@ int sm2_load_deck(struct sm2_instance *instance, char *deck, int overwrite, char
		if (*line != 0) {
			card->field_count += 1;
			card->fields = realloc(card->fields, card->field_count * sizeof(char*));
			card->fields[card->field_count - 1] = malloc(strlen(line) + 1);
			strcpy(card->fields[card->field_count - 1], line);
			card->fields[card->field_count - 1] = strdup(line);
		}
		line = strtok(nil, "\n");
	}
	return count;
	return instance->card_count - oldcount;
}

void

M sm2.h => sm2.h +4 -3
@@ 1,16 1,16 @@
struct sm2_card {
	char *id;
	char *path;
	char **fields;
	unsigned long field_count;
	unsigned long next_due;
	u8int interval;
	u32int repetitions;
	float easiness;
	char *path;
};

struct sm2_instance {
	unsigned long card_count;
	ulong card_count, card_cap;
	// heap-allocated array of size card_count. capacity is always equal to size.
	struct sm2_card *cards;
	char *delimiter;


@@ 24,12 24,13 @@ extern void sm2_init(struct sm2_instance*);
/*
	Loads a deck into the instance. If overwrite is set, any cards with IDs
	matching already-loaded cards will replace the previously known cards.
	If overwrite is not set, then cards with duplicate IDs will be treated as distinct copies of the same card. In other words, log entries for one are considered log entries for BOTH. Behavior is not fully defined for this scenario.
	
	This *will* crash (or worse!) if the instance hasn't been initialized.
	This overwrites the provided string with undefined contents. The caller
	is responsible for duplicating the string if this is unwanted.
*/
extern int sm2_load_deck(struct sm2_instance*, char *, int overwrite, char *);
extern int sm2_load_deck(struct sm2_instance*, char *, int overwrite, char *path);

/*
	Loads and processes logs. While logs can be loaded before decks, any cards not already