Replaced qsort by a lazy update of a bare-bones BST when using 'list'
This commit is contained in:
parent
11fc655bb7
commit
e20de151ec
95
src/sfxd.c
95
src/sfxd.c
|
@ -46,8 +46,13 @@ struct sfx_pool {
|
|||
|
||||
float volume;
|
||||
float pitch_min, pitch_max;
|
||||
|
||||
int bst_parent, bst_left, bst_right;
|
||||
bool inside_bst;
|
||||
} *sounds;
|
||||
int cap, use;
|
||||
|
||||
int bst_root;
|
||||
};
|
||||
|
||||
ssize_t send_data(struct msg_target tgt, const void *data, ssize_t len);
|
||||
|
@ -69,7 +74,7 @@ struct sfx_pool_item *sfx_pool_load(const char *key, const char *path);
|
|||
|
||||
struct ipc_data ipc = { 0 };
|
||||
struct audio_data audio = { 0 };
|
||||
struct sfx_pool sounds_pool = { 0, 0, 0 };
|
||||
struct sfx_pool sounds_pool = { 0, 0, 0, .bst_root = -1 };
|
||||
|
||||
#ifndef NO_COUNTERS
|
||||
struct global_counters {
|
||||
|
@ -82,10 +87,80 @@ struct global_counters {
|
|||
} global_counters = { 0 };
|
||||
#endif
|
||||
|
||||
static int qsort_compare_index_of_key(const void *p1, const void *p2) {
|
||||
struct sfx_pool_item *it1 = &sounds_pool.sounds[*(int *)p1];
|
||||
struct sfx_pool_item *it2 = &sounds_pool.sounds[*(int *)p2];
|
||||
return strcmp(it1->key, it2->key);
|
||||
void sfx_pool_bst_insert(struct sfx_pool_item* lst, int *root_idx_ptr, int new_idx) {
|
||||
// TODO balanced
|
||||
struct sfx_pool_item *new_item = lst + new_idx;
|
||||
int *new_idx_ptr = root_idx_ptr;
|
||||
int parent_idx = -1;
|
||||
int depth = 0;
|
||||
|
||||
int next_parent_idx;
|
||||
while ((next_parent_idx = *new_idx_ptr) >= 0) {
|
||||
depth++;
|
||||
parent_idx = next_parent_idx;
|
||||
struct sfx_pool_item *parent_item = lst + parent_idx;
|
||||
if (strcmp(new_item->key, parent_item->key) < 0) {
|
||||
new_idx_ptr = &parent_item->bst_left;
|
||||
} else {
|
||||
new_idx_ptr = &parent_item->bst_right;
|
||||
}
|
||||
}
|
||||
|
||||
*new_idx_ptr = new_idx;
|
||||
new_item->bst_parent = parent_idx;
|
||||
new_item->bst_left = -1;
|
||||
new_item->bst_right = -1;
|
||||
new_item->inside_bst = true;
|
||||
send_txt((struct msg_target){ stdout, 0, 0, 0 }, "INF: Sorting element at index %d with key '%s' under the element at index %d with depth of %d\n", new_idx, lst[new_idx].key, parent_idx, depth);
|
||||
}
|
||||
|
||||
// We don't need deletion support
|
||||
|
||||
void sfx_pool_bst_insert_all(struct sfx_pool_item *lst, int *root_idx_ptr, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!lst[i].inside_bst && lst[i].key[0] != '\0') {
|
||||
sfx_pool_bst_insert(lst, root_idx_ptr, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sfx_pool_bst_leftmost(const struct sfx_pool_item *lst, int parent_idx) {
|
||||
if (parent_idx < 0) {
|
||||
return parent_idx;
|
||||
}
|
||||
|
||||
int next_idx;
|
||||
while ((next_idx = lst[parent_idx].bst_left) >= 0) {
|
||||
parent_idx = next_idx;
|
||||
}
|
||||
return parent_idx;
|
||||
}
|
||||
|
||||
int sfx_pool_bst_go_right(const struct sfx_pool_item *lst, int cur_idx) {
|
||||
if (cur_idx < 0) {
|
||||
return cur_idx;
|
||||
}
|
||||
const struct sfx_pool_item *cur_item = lst + cur_idx;
|
||||
if (cur_item->bst_right >= 0) {
|
||||
return sfx_pool_bst_leftmost(lst, cur_item->bst_right);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
int parent_idx = cur_item->bst_parent;
|
||||
if (parent_idx < 0) {
|
||||
// We are a root => end iterator
|
||||
return parent_idx;
|
||||
}
|
||||
|
||||
if (lst[parent_idx].bst_left == cur_idx) {
|
||||
// We are a left child
|
||||
return parent_idx;
|
||||
}
|
||||
|
||||
// We are a right child
|
||||
cur_idx = parent_idx;
|
||||
cur_item = lst + cur_idx;
|
||||
}
|
||||
}
|
||||
|
||||
void usage(int argc, char **argv) {
|
||||
|
@ -331,18 +406,14 @@ void execute_command(struct msg_target tgt, const char *command, const char *par
|
|||
}
|
||||
}
|
||||
} else if (0 == strcmp(command, "list") || 0 == strcmp(command, "ls")) {
|
||||
// TODO: find a better way to do this!
|
||||
int *indices = calloc(sounds_pool.cap, sizeof(int));
|
||||
for (int i = 0; i < sounds_pool.cap; i++) indices[i] = i;
|
||||
qsort(indices, sounds_pool.cap, sizeof(int), qsort_compare_index_of_key);
|
||||
for (int i = 0; i < sounds_pool.cap; i++) {
|
||||
struct sfx_pool_item *item = &sounds_pool.sounds[indices[i]];
|
||||
sfx_pool_bst_insert_all(sounds_pool.sounds, &sounds_pool.bst_root, sounds_pool.cap);
|
||||
for (int i = sfx_pool_bst_leftmost(sounds_pool.sounds, sounds_pool.bst_root); i >= 0; i = sfx_pool_bst_go_right(sounds_pool.sounds, i)) {
|
||||
struct sfx_pool_item *item = &sounds_pool.sounds[i];
|
||||
if (item->key[0] == '\0') continue;
|
||||
if (0 == fnmatch(params, item->key, 0) || strlen(params) == 0) {
|
||||
send_txt(tgt, "%s\n", item->key);
|
||||
}
|
||||
}
|
||||
free(indices);
|
||||
} else if (0 == strcmp(command, "source")) {
|
||||
if (strlen(params) == 0) {
|
||||
send_txt(tgt, "ERR: argument required: PATH\n");
|
||||
|
|
Loading…
Reference in New Issue