diff options
author | cbdev <cb@cbcdn.com> | 2021-06-22 03:29:08 +0200 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2021-06-22 03:29:08 +0200 |
commit | ca055614db57386f0e43d65bb10e501bdde699ef (patch) | |
tree | a9c94e89952d952a6a4e6f5cb30105c6aae2b32e /core/backend.c | |
parent | 68818d94980bfc22d6414ed29d2d9cbb6be24cb1 (diff) | |
download | midimonster-ca055614db57386f0e43d65bb10e501bdde699ef.tar.gz midimonster-ca055614db57386f0e43d65bb10e501bdde699ef.tar.bz2 midimonster-ca055614db57386f0e43d65bb10e501bdde699ef.zip |
Keep channel registry map in sync when updating identifiers (#76)
Diffstat (limited to 'core/backend.c')
-rw-r--r-- | core/backend.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/core/backend.c b/core/backend.c index 16e095c..8a8588f 100644 --- a/core/backend.c +++ b/core/backend.c @@ -94,9 +94,9 @@ int backends_notify(size_t nev, channel** c, channel_value* v){ MM_API channel* mm_channel(instance* inst, uint64_t ident, uint8_t create){ size_t u, bucket = channelstore_hash(inst, ident); - DBGPF("\tSearching for inst %" PRIu64 " ident %" PRIu64, inst, ident); + DBGPF("\tSearching for inst %" PRIu64 " ident %" PRIu64, (uint64_t) inst, ident); for(u = 0; u < channels.n[bucket]; u++){ - DBGPF("\tBucket %" PRIsize_t " entry %" PRIsize_t " inst %" PRIu64 " ident %" PRIu64, bucket, u, channels.entry[bucket][u]->instance, channels.entry[bucket][u]->ident); + DBGPF("\tBucket %" PRIsize_t " entry %" PRIsize_t " inst %" PRIu64 " ident %" PRIu64, bucket, u, (uint64_t) channels.entry[bucket][u]->instance, channels.entry[bucket][u]->ident); if(channels.entry[bucket][u]->instance == inst && channels.entry[bucket][u]->ident == ident){ DBGPF("Requested channel %" PRIu64 " on instance %s already exists, reusing (bucket %" PRIsize_t ", %" PRIsize_t " search steps)\n", ident, inst->name, bucket, u); @@ -128,6 +128,49 @@ MM_API channel* mm_channel(instance* inst, uint64_t ident, uint8_t create){ return channels.entry[bucket][(channels.n[bucket]++)]; } +MM_API void mm_channel_update(channel* chan, uint64_t ident){ + size_t bucket = channelstore_hash(chan->instance, chan->ident), new_bucket = channelstore_hash(chan->instance, ident); + size_t u; + + DBGPF("Updating identifier for inst %" PRIu64 " ident %" PRIu64 " (bucket %" PRIsize_t " to %" PRIsize_t ") to %" PRIu64, (uint64_t) chan->instance, chan->ident, bucket, new_bucket, ident); + + if(bucket == new_bucket){ + chan->ident = ident; + return; + } + + for(u = 0; u < channels.n[bucket]; u++){ + if(channels.entry[bucket][u]->instance == chan->instance + && channels.entry[bucket][u]->ident == chan->ident){ + break; + } + } + + if(u == channels.n[bucket]){ + DBGPF("Failed to find channel to update in bucket %" PRIsize_t, bucket); + return; + } + + DBGPF("Removing channel from slot %" PRIsize_t " of %" PRIsize_t " of bucket %" PRIsize_t, u, channels.n[bucket], bucket); + //remove channel from old bucket + for(; u < channels.n[bucket] - 1; u++){ + channels.entry[bucket][u] = channels.entry[bucket][u + 1]; + } + + //add to new bucket + channels.entry[new_bucket] = realloc(channels.entry[new_bucket], (channels.n[new_bucket] + 1) * sizeof(channel*)); + if(!channels.entry[new_bucket]){ + fprintf(stderr, "Failed to allocate memory\n"); + channels.n[new_bucket] = 0; + return; + } + + channels.entry[new_bucket][channels.n[new_bucket]] = chan; + chan->ident = ident; + channels.n[bucket]--; + channels.n[new_bucket]++; +} + instance* mm_instance(backend* b){ size_t u = 0, n = 0; |