Skip to content

Commit

Permalink
Refactor signal_map operation in adapter.
Browse files Browse the repository at this point in the history
The signal_map objects and related index are only created when necessary.

Signed-off-by: Rule Timothy (VM/EMT3) <[email protected]>
  • Loading branch information
timrulebosch committed May 16, 2024
1 parent a090514 commit fc9c9c6
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 117 deletions.
162 changes: 90 additions & 72 deletions dse/modelc/adapter/adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,6 @@ Adapter* adapter_create(void* endpoint)
}


SignalValue* _get_signal_value(Channel* channel, const char* signal_name)
{
SignalValue* sv = hashmap_get(&channel->signal_values, signal_name);
if (sv) return sv;

/* Add a new SignalValue, assume dynamically provided name. */
sv = calloc(1, sizeof(SignalValue));
assert(sv);
sv->name = malloc(strlen(signal_name) + 1);
snprintf(sv->name, strlen(signal_name) + 1, "%s", signal_name);
if (hashmap_set(&channel->signal_values, signal_name, sv)) return sv;
assert(0); /* Should not happen. */
return NULL;
}


static SignalMap* _get_signal_value_map(
Channel* channel, const char** signal_name, uint32_t signal_count)
{
Expand All @@ -187,55 +171,80 @@ static SignalMap* _get_signal_value_map(
}


void _update_signal_value_keys(Channel* channel)
static void _destroy_index(Channel* channel)
{
if (channel->signal_values_keys) {
for (uint32_t _ = 0; _ < channel->signal_values_length; _++)
free(channel->signal_values_keys[_]);
free(channel->signal_values_keys);
channel->signal_values_keys = NULL;
if (channel->index.names) {
for (uint32_t _ = 0; _ < channel->index.count; _++)
free(channel->index.names[_]);
free(channel->index.names);
channel->index.names = NULL;
channel->index.count = 0;
}
if (channel->signal_values_map) {
free(channel->signal_values_map);
channel->signal_values_map = NULL;
if (channel->index.map) {
free(channel->index.map);
channel->index.map = NULL;
}
channel->signal_values_keys = hashmap_keys(&channel->signal_values);
channel->signal_values_length = hashmap_number_keys(channel->signal_values);
channel->signal_values_map = _get_signal_value_map(channel,
(const char**)channel->signal_values_keys,
channel->signal_values_length);
}

static void _generate_index(Channel* channel)
{
_destroy_index(channel);

channel->index.names = hashmap_keys(&channel->signal_values);
channel->index.count = hashmap_number_keys(channel->signal_values);
channel->index.map = _get_signal_value_map(
channel, (const char**)channel->index.names, channel->index.count);
}

static void _invalidate_index(Channel* channel)
{
channel->index.hash_code++; // Signal consumers of index change.
_destroy_index(channel);
}

void _refresh_index(Channel* channel)
{
if (channel->index.names == NULL) _generate_index(channel);
}

SignalValue* _get_signal_value(Channel* channel, const char* signal_name)
{
SignalValue* sv = hashmap_get(&channel->signal_values, signal_name);
if (sv) return sv;

/* Add a new SignalValue, assume dynamically provided name. */
sv = calloc(1, sizeof(SignalValue));
sv->name = strdup(signal_name);
sv = hashmap_set(&channel->signal_values, signal_name, sv);
assert(sv);
_invalidate_index(channel);

return sv;
}


SignalValue* _get_signal_value_byindex(Channel* channel, uint32_t index)
{
assert(index < channel->signal_values_length);
const char* signal_name = channel->signal_values_keys[index];
return _get_signal_value(channel, signal_name);
_refresh_index(channel);
assert(index < channel->index.count);
return _get_signal_value(channel, channel->index.names[index]);
}


SignalMap* adapter_get_signal_map(AdapterModel* am, const char* channel_name,
const char** signal_name, uint32_t signal_count)
{
/* Generate a mapping from Index to SignalValue to avoid constant
hashmap lookups. Generate each time new signals are added.
This will generate an array of map objects. The indexing will
/* This will generate an array of map objects. The indexing will
match the callers signal_name array, the map holds a pointer
to the signal value of the adapter (the consolidation point).
This way, a Model Function can get a _subset_ of all channel signals.
Caller to free SignalMap, but not referenced SignalValue object.
*/
SignalMap* sm;
Channel* ch = _get_channel(am, channel_name);
Channel* ch = _get_channel(am, channel_name);
assert(ch);

sm = _get_signal_value_map(ch, signal_name, signal_count);
_update_signal_value_keys(ch);
return sm;
return _get_signal_value_map(ch, signal_name, signal_count);
}


Expand All @@ -252,7 +261,7 @@ Channel* adapter_init_channel(AdapterModel* am, const char* channel_name,
for (uint32_t i = 0; i < signal_count; i++) {
_get_signal_value(ch, signal_name[i]); /* Creates if missing. */
}
_update_signal_value_keys(ch);
_refresh_index(ch);

/* Return the channel object so that caller can configure other properties.
*/
Expand Down Expand Up @@ -329,7 +338,9 @@ static void _adapter_register(AdapterModel* am)
channel_index++) {
Channel* ch = _get_channel_byindex(am, channel_index);
ns(MessageType_union_ref_t) message;
uint32_t signal_list_length = ch->signal_values_length;

_refresh_index(ch);
uint32_t signal_list_length = ch->index.count;

/* SignalIndex with SignalLookup */
log_simbus("SignalIndex --> [%s]", ch->name);
Expand Down Expand Up @@ -445,26 +456,26 @@ static void sv_delta_to_msgpack(Channel* channel, msgpack_packer* pk)
/* First(root) Object, array, 2 elements. */
msgpack_pack_array(pk, 2);
uint32_t changed_signal_count = 0;
for (uint32_t i = 0; i < channel->signal_values_length; i++) {
SignalValue* sv = channel->signal_values_map[i].signal;
for (uint32_t i = 0; i < channel->index.count; i++) {
SignalValue* sv = channel->index.map[i].signal;
if (sv->uid == 0) continue;
if ((sv->val != sv->final_val) || (sv->bin && sv->bin_size)) {
changed_signal_count++;
}
}
/* 1st Object in root Array, list of UID's. */
msgpack_pack_array(pk, changed_signal_count);
for (uint32_t i = 0; i < channel->signal_values_length; i++) {
SignalValue* sv = channel->signal_values_map[i].signal;
for (uint32_t i = 0; i < channel->index.count; i++) {
SignalValue* sv = channel->index.map[i].signal;
if (sv->uid == 0) continue;
if ((sv->val != sv->final_val) || (sv->bin && sv->bin_size)) {
msgpack_pack_uint32(pk, sv->uid);
}
}
/* 2st Object in root Array, list of Values. */
msgpack_pack_array(pk, changed_signal_count);
for (uint32_t i = 0; i < channel->signal_values_length; i++) {
SignalValue* sv = channel->signal_values_map[i].signal;
for (uint32_t i = 0; i < channel->index.count; i++) {
SignalValue* sv = channel->index.map[i].signal;
if (sv->uid == 0) continue;
if (sv->bin && sv->bin_size) {
msgpack_pack_bin_with_body(pk, sv->bin, sv->bin_size);
Expand Down Expand Up @@ -496,7 +507,7 @@ static int notify_encode_sv(void* value, void* data)
for (uint32_t i = 0; i < am->channels_length; i++) {
Channel* ch = _get_channel_byindex(am, i);
assert(ch);
assert(ch->signal_values_map);
_refresh_index(ch);
log_simbus("SignalVector --> [%s:%u]", ch->name, am->model_uid);

msgpack_sbuffer_clear(&sbuf);
Expand Down Expand Up @@ -736,24 +747,27 @@ void adapter_destroy(Adapter* adapter)
}


static void _destroy_signal_value(void* map_item, void* data)
{
UNUSED(data);

SignalValue* sv = map_item;
if (sv) {
if (sv->name) free(sv->name);
if (sv->bin) free(sv->bin);
free(sv);
}
}


void adapter_destroy_adapter_model(AdapterModel* am)
{
if (am && am->channels_length) {
for (uint32_t i = 0; i < am->channels_length; i++) {
Channel* ch = _get_channel_byindex(am, i);
for (uint32_t si = 0; si < ch->signal_values_length; si++) {
SignalValue* sv = _get_signal_value_byindex(ch, si);
if (sv->name) free(sv->name);
if (sv->bin) free(sv->bin);
if (sv) free(sv);
}
hashmap_destroy(&ch->signal_values);
if (ch->signal_values_keys) {
for (uint32_t _ = 0; _ < ch->signal_values_length; _++)
free(ch->signal_values_keys[_]);
}
free(ch->signal_values_keys);
free(ch->signal_values_map);
hashmap_destroy_ext(
&ch->signal_values, _destroy_signal_value, NULL);
_destroy_index(ch);
if (ch->model_register_set) {
set_destroy(ch->model_register_set);
free(ch->model_register_set);
Expand All @@ -780,8 +794,8 @@ SignalValue* _find_signal_by_uid(Channel* channel, uint32_t uid)
{
if (uid == 0) return NULL;

for (unsigned int i = 0; i < channel->signal_values_length; i++) {
SignalValue* sv = channel->signal_values_map[i].signal;
for (unsigned int i = 0; i < channel->index.count; i++) {
SignalValue* sv = channel->index.map[i].signal;
if (sv->uid == uid) return sv;
}
return NULL;
Expand All @@ -791,6 +805,8 @@ SignalValue* _find_signal_by_uid(Channel* channel, uint32_t uid)
static void process_signal_value_data(
Channel* channel, flatbuffers_uint8_vec_t data_vector, size_t length)
{
_refresh_index(channel);

/* Unpack. */
bool result;
msgpack_unpacker unpacker;
Expand Down Expand Up @@ -940,6 +956,7 @@ static void process_signal_index_message(
return;
}
/* Decode the SignalLookup vector. */
_refresh_index(channel);
ns(SignalLookup_vec_t) vector = ns(SignalIndex_indexes(signal_index_table));
size_t vector_len = ns(SignalLookup_vec_len(vector));
for (uint32_t _vi = 0; _vi < vector_len; _vi++) {
Expand All @@ -953,8 +970,8 @@ static void process_signal_index_message(
log_simbus(" SignalLookup: %s [UID=%u]", signal_name, signal_uid);
if (signal_uid == 0) continue;
/* Update the Adapter signal_value array. */
for (unsigned int i = 0; i < channel->signal_values_length; i++) {
SignalValue* sv = channel->signal_values_map[i].signal;
for (unsigned int i = 0; i < channel->index.count; i++) {
SignalValue* sv = channel->index.map[i].signal;
if (strcmp(sv->name, signal_name) == 0) {
sv->uid = signal_uid;
break;
Expand Down Expand Up @@ -1113,13 +1130,14 @@ void adapter_model_dump_debug(AdapterModel* am, const char* name)
for (uint32_t channel_index = 0; channel_index < am->channels_length;
channel_index++) {
Channel* ch = _get_channel_byindex(am, channel_index);
_refresh_index(ch);
log_simbus("----------------------------------------");
log_simbus("Channel [%u]:", channel_index);
log_simbus(" name : %s", ch->name);
log_simbus(" signal_count : %u", ch->signal_values_length);
log_simbus(" signal_count : %u", ch->index.count);
log_simbus(" signal_value :");
for (uint32_t i = 0; i < ch->signal_values_length; i++) {
SignalValue* sv = ch->signal_values_map[i].signal;
for (uint32_t i = 0; i < ch->index.count; i++) {
SignalValue* sv = ch->index.map[i].signal;
log_simbus(" [%u] uid=%u, val=%f, final_val=%f, name=%s", i,
sv->uid, sv->val, sv->final_val, sv->name);
}
Expand Down
27 changes: 13 additions & 14 deletions dse/modelc/adapter/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,20 @@ typedef struct Channel {
void* endpoint_channel; // Reference to an Endpoint object
// which represents this Channel.
/* Signal properties. */
HashMap signal_values; // Collection of SignalValue, key is name.
char** signal_values_keys; // Cached result of hashmap_keys, update
// on hashmap_set/remove.
uint32_t signal_values_length;
SignalMap* signal_values_map; // Generated based on signal_values_keys,
// cached speedup.
/* Signal references (to controller/model API). */
void* ref__signal_value;
bool ref__convert_uint32; // the type of the void* signal_value
bool ref__convert_int32; // double otherwise.
HashMap signal_values;
struct {
/* Index supporting the signal_values hash. */
char** names;
uint32_t count;
uint32_t hash_code;
/* Map used by _this_ channel (contains all signals). */
SignalMap* map;
} index;
/* Bus properties. */
SimpleSet* model_register_set;
SimpleSet* model_ready_set;
uint32_t expected_model_count; // Don't start until count reached,
// could get more(?).
SimpleSet* model_register_set;
SimpleSet* model_ready_set;
uint32_t expected_model_count; // Don't start until count reached,
// could get more(?).
} Channel;


Expand Down
1 change: 1 addition & 0 deletions dse/modelc/adapter/adapter_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ DLL_PRIVATE SignalValue* _get_signal_value(
Channel* channel, const char* signal_name);
DLL_PRIVATE SignalValue* _get_signal_value_byindex(
Channel* channel, uint32_t index);
DLL_PRIVATE void _refresh_index(Channel* channel);


#endif // DSE_MODELC_ADAPTER_ADAPTER_PRIVATE_H_
3 changes: 2 additions & 1 deletion dse/modelc/adapter/simbus/adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ void simbus_adapter_init_channel(

/* Set the Signal UID's, if specified, otherwise they are generated
when processing SignalLookups. */
for (uint32_t si = 0; si < ch->signal_values_length; si++) {
_refresh_index(ch);
for (uint32_t si = 0; si < ch->index.count; si++) {
SignalValue* sv = _get_signal_value_byindex(ch, si);
sv->uid = simbus_generate_uid_hash(sv->name);
log_simbus(" [%u] uid=%u, name=%s", si, sv->uid, sv->name);
Expand Down
Loading

0 comments on commit fc9c9c6

Please sign in to comment.