various interconnected changes for ddsi_serdata
- topic-erased key-only serdata for use in tkmap - restoration of including key values in invalid samples - special handling of keyless topics - keyhash generation via streams - elimination of dynamically allocated buffers in keyhash - removal of the last vestiges of "serstate" Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
8e20ae547e
commit
9cab5e769c
19 changed files with 375 additions and 383 deletions
|
@ -90,7 +90,9 @@ DDS_EXPORT void dds_stream_write_uint64 (dds_stream_t * os, uint64_t val);
|
|||
DDS_EXPORT void dds_stream_write_float (dds_stream_t * os, float val);
|
||||
DDS_EXPORT void dds_stream_write_double (dds_stream_t * os, double val);
|
||||
DDS_EXPORT void dds_stream_write_string (dds_stream_t * os, const char * val);
|
||||
DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, uint8_t * buffer);
|
||||
DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const uint8_t * buffer);
|
||||
DDS_EXPORT void *dds_stream_address (dds_stream_t * s);
|
||||
DDS_EXPORT void *dds_stream_alignto (dds_stream_t * s, uint32_t a);
|
||||
|
||||
#define dds_stream_write_char(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
|
||||
#define dds_stream_write_int8(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
|
||||
|
|
|
@ -37,6 +37,7 @@ void dds_stream_from_serdata_default (dds_stream_t * s, const struct ddsi_serdat
|
|||
void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d);
|
||||
|
||||
void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic);
|
||||
void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic);
|
||||
void dds_stream_read_key
|
||||
(
|
||||
dds_stream_t * is,
|
||||
|
|
|
@ -36,7 +36,7 @@ struct tkmap * dds_tkmap_new (void);
|
|||
void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap *tkmap);
|
||||
void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk);
|
||||
uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct ddsi_serdata *serdata);
|
||||
_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample);
|
||||
_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample);
|
||||
_Check_return_ struct tkmap_instance * dds_tkmap_find(
|
||||
_In_ struct ddsi_serdata * sd,
|
||||
_In_ const bool rd,
|
||||
|
|
|
@ -285,7 +285,7 @@ dds_unregister_instance_ih_ts(
|
|||
map = gv.m_tkmap;
|
||||
topic = dds_instance_info((dds_entity*)wr);
|
||||
sample = dds_alloc (topic->m_descriptor->m_size);
|
||||
if (dds_tkmap_get_key (map, handle, sample)) {
|
||||
if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) {
|
||||
ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action);
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found");
|
||||
|
@ -383,7 +383,7 @@ dds_dispose_ih_ts(
|
|||
struct tkmap *map = gv.m_tkmap;
|
||||
const dds_topic *topic = dds_instance_info((dds_entity*)wr);
|
||||
void *sample = dds_alloc (topic->m_descriptor->m_size);
|
||||
if (dds_tkmap_get_key (map, handle, sample)) {
|
||||
if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) {
|
||||
ret = dds_dispose_impl(wr, sample, handle, timestamp);
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found");
|
||||
|
@ -455,7 +455,7 @@ dds_instance_get_key(
|
|||
}
|
||||
memset (data, 0, topic->m_descriptor->m_size);
|
||||
|
||||
if (dds_tkmap_get_key (map, inst, data)) {
|
||||
if (dds_tkmap_get_key (map, topic->m_stopic, inst, data)) {
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided entity is found");
|
||||
|
|
|
@ -20,94 +20,21 @@
|
|||
#ifndef NDEBUG
|
||||
static bool keyhash_is_reset(const dds_key_hash_t *kh)
|
||||
{
|
||||
static const char nullhash[sizeof(kh->m_hash)] = { 0 };
|
||||
return kh->m_flags == 0 && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0;
|
||||
return !kh->m_set;
|
||||
}
|
||||
#endif
|
||||
|
||||
void dds_key_md5 (dds_key_hash_t * kh)
|
||||
{
|
||||
md5_state_t md5st;
|
||||
md5_init (&md5st);
|
||||
md5_append (&md5st, (md5_byte_t*) kh->m_key_buff, kh->m_key_len);
|
||||
md5_finish (&md5st, (unsigned char *) kh->m_hash);
|
||||
}
|
||||
|
||||
/*
|
||||
dds_key_gen: Generates key and keyhash for a sample.
|
||||
See section 9.6.3.3 of DDSI spec.
|
||||
*/
|
||||
|
||||
void dds_key_gen
|
||||
(
|
||||
const dds_topic_descriptor_t * const desc,
|
||||
dds_key_hash_t * kh,
|
||||
const char * sample
|
||||
)
|
||||
static void dds_key_gen_stream (const dds_topic_descriptor_t * const desc, dds_stream_t *os, const char *sample)
|
||||
{
|
||||
const char * src;
|
||||
const uint32_t * op;
|
||||
uint32_t i;
|
||||
uint32_t len = 0;
|
||||
char * dst;
|
||||
|
||||
assert(keyhash_is_reset(kh));
|
||||
|
||||
if (desc->m_nkeys == 0)
|
||||
{
|
||||
kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH;
|
||||
kh->m_key_len = sizeof (kh->m_hash);
|
||||
return;
|
||||
}
|
||||
|
||||
kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET;
|
||||
|
||||
/* Select key buffer to use */
|
||||
|
||||
if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
kh->m_flags |= DDS_KEY_IS_HASH;
|
||||
kh->m_key_len = sizeof (kh->m_hash);
|
||||
dst = kh->m_hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate key length */
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
op = desc->m_ops + desc->m_keys[i].m_index;
|
||||
src = sample + op[1];
|
||||
|
||||
switch (DDS_OP_TYPE (*op))
|
||||
{
|
||||
case DDS_OP_VAL_1BY: len += 1; break;
|
||||
case DDS_OP_VAL_2BY: len += 2; break;
|
||||
case DDS_OP_VAL_4BY: len += 4; break;
|
||||
case DDS_OP_VAL_8BY: len += 8; break;
|
||||
case DDS_OP_VAL_STR:
|
||||
src = *((char**) src);
|
||||
/* FALLS THROUGH */
|
||||
case DDS_OP_VAL_BST:
|
||||
len += (uint32_t) (5 + strlen (src));
|
||||
break;
|
||||
case DDS_OP_VAL_ARR:
|
||||
len += op[2] * dds_op_size[DDS_OP_SUBTYPE (*op)];
|
||||
break;
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
kh->m_key_len = len;
|
||||
if (len > kh->m_key_buff_size)
|
||||
{
|
||||
kh->m_key_buff = dds_realloc_zero (kh->m_key_buff, len);
|
||||
kh->m_key_buff_size = len;
|
||||
}
|
||||
dst = kh->m_key_buff;
|
||||
}
|
||||
|
||||
/* Write keys to buffer (Big Endian CDR encoded with no padding) */
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
|
@ -119,29 +46,22 @@ void dds_key_gen
|
|||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
dds_stream_write_uint8 (os, *((const uint8_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_2BY:
|
||||
{
|
||||
uint16_t u16 = toBE2u (*((const uint16_t*) src));
|
||||
memcpy (dst, &u16, sizeof (u16));
|
||||
dst += sizeof (u16);
|
||||
dds_stream_write_uint16 (os, *((const uint16_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_4BY:
|
||||
{
|
||||
uint32_t u32 = toBE4u (*((const uint32_t*) src));
|
||||
memcpy (dst, &u32, sizeof (u32));
|
||||
dst += sizeof (u32);
|
||||
dds_stream_write_uint32 (os, *((const uint32_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
uint64_t u64 = toBE8u (*((const uint64_t*) src));
|
||||
memcpy (dst, &u64, sizeof (u64));
|
||||
dst += sizeof (u64);
|
||||
dds_stream_write_uint64 (os, *((const uint64_t *) src));
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
|
@ -151,35 +71,55 @@ void dds_key_gen
|
|||
/* FALLS THROUGH */
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
uint32_t u32;
|
||||
len = (uint32_t) (strlen (src) + 1);
|
||||
u32 = toBE4u (len);
|
||||
memcpy (dst, &u32, sizeof (u32));
|
||||
dst += sizeof (u32);
|
||||
memcpy (dst, src, len);
|
||||
dst += len;
|
||||
dds_stream_write_uint32 (os, len);
|
||||
dds_stream_write_buffer (os, len, (const uint8_t *) src);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_ARR:
|
||||
{
|
||||
uint32_t size = dds_op_size[DDS_OP_SUBTYPE (*op)];
|
||||
char *dst;
|
||||
len = size * op[2];
|
||||
memcpy (dst, src, len);
|
||||
dst = dds_stream_alignto (os, op[2]);
|
||||
dds_stream_write_buffer (os, len, (const uint8_t *) src);
|
||||
if (dds_stream_endian () && (size != 1u))
|
||||
{
|
||||
dds_stream_swap (dst, size, op[2]);
|
||||
}
|
||||
dst += len;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash is md5 of key */
|
||||
void dds_key_gen (const dds_topic_descriptor_t * const desc, dds_key_hash_t * kh, const char * sample)
|
||||
{
|
||||
assert(keyhash_is_reset(kh));
|
||||
|
||||
if ((kh->m_flags & DDS_KEY_IS_HASH) == 0)
|
||||
kh->m_set = 1;
|
||||
if (desc->m_nkeys == 0)
|
||||
kh->m_iskey = 1;
|
||||
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
dds_key_md5 (kh);
|
||||
dds_stream_t os;
|
||||
kh->m_iskey = 1;
|
||||
dds_stream_init(&os, 0);
|
||||
os.m_endian = 0;
|
||||
os.m_buffer.pv = kh->m_hash;
|
||||
os.m_size = 16;
|
||||
dds_key_gen_stream (desc, &os, sample);
|
||||
}
|
||||
else
|
||||
{
|
||||
dds_stream_t os;
|
||||
md5_state_t md5st;
|
||||
kh->m_iskey = 0;
|
||||
dds_stream_init(&os, 64);
|
||||
os.m_endian = 0;
|
||||
dds_key_gen_stream (desc, &os, sample);
|
||||
md5_init (&md5st);
|
||||
md5_append (&md5st, os.m_buffer.p8, os.m_index);
|
||||
md5_finish (&md5st, (unsigned char *) kh->m_hash);
|
||||
dds_stream_fini (&os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,11 +149,11 @@
|
|||
|
||||
static const status_cb_data_t dds_rhc_data_avail_cb_data = { DDS_DATA_AVAILABLE_STATUS, 0, 0, true };
|
||||
|
||||
/* FIXME: populate tkmap with key-only derived serdata, with timestamp
|
||||
set to invalid. An invalid timestamp is (logically) unordered with
|
||||
respect to valid timestamps, and that would mean BY_SOURCE order
|
||||
would be respected even when generating an invalid sample for an
|
||||
unregister message using the tkmap data. */
|
||||
/* FIXME: tkmap should perhaps retain data with timestamp set to invalid
|
||||
An invalid timestamp is (logically) unordered with respect to valid
|
||||
timestamps, and that would mean BY_SOURCE order could be respected
|
||||
even when generating an invalid sample for an unregister message using
|
||||
the tkmap data. */
|
||||
|
||||
/******************************
|
||||
****** LIVE WRITERS ******
|
||||
|
@ -1632,12 +1632,7 @@ static int dds_rhc_read_w_qminv
|
|||
{
|
||||
bool trigger_waitsets = false;
|
||||
uint32_t n = 0;
|
||||
#if 0
|
||||
const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type;
|
||||
#else /* FIXME: hack hack -- deserialize_into */
|
||||
const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic;
|
||||
const struct dds_topic_descriptor * desc = sertopic_def->type;
|
||||
#endif
|
||||
const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
|
@ -1707,7 +1702,7 @@ static int dds_rhc_read_w_qminv
|
|||
if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0)
|
||||
{
|
||||
set_sample_info_invsample (info_seq + n, inst);
|
||||
ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0);
|
||||
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
|
||||
if (!inst->inv_isread)
|
||||
{
|
||||
inst->inv_isread = 1;
|
||||
|
@ -1765,12 +1760,7 @@ static int dds_rhc_take_w_qminv
|
|||
bool trigger_waitsets = false;
|
||||
uint64_t iid;
|
||||
uint32_t n = 0;
|
||||
#if 0
|
||||
const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type;
|
||||
#else /* FIXME: hack hack -- deserialize_into */
|
||||
const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic;
|
||||
const struct dds_topic_descriptor * desc = sertopic_def->type;
|
||||
#endif
|
||||
const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
|
@ -1859,7 +1849,7 @@ static int dds_rhc_take_w_qminv
|
|||
if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0)
|
||||
{
|
||||
set_sample_info_invsample (info_seq + n, inst);
|
||||
ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0);
|
||||
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
|
||||
inst_clear_invsample (rhc, inst);
|
||||
++n;
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
#include "dds__key.h"
|
||||
#include "dds__alloc.h"
|
||||
#include "os/os.h"
|
||||
#include "ddsi/q_md5.h"
|
||||
|
||||
//#define OP_DEBUG_READ 1
|
||||
//#define OP_DEBUG_WRITE 1
|
||||
//#define OP_DEBUG_KEY 1
|
||||
|
||||
/*
|
||||
#define OP_DEBUG_READ 1
|
||||
#define OP_DEBUG_WRITE 1
|
||||
#define OP_DEBUG_KEY 1
|
||||
*/
|
||||
|
||||
#if defined OP_DEBUG_WRITE || defined OP_DEBUG_READ || defined OP_DEBUG_KEY
|
||||
static const char * stream_op_type[11] =
|
||||
|
@ -452,11 +452,22 @@ void dds_stream_write_string (dds_stream_t * os, const char * val)
|
|||
}
|
||||
}
|
||||
|
||||
void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, uint8_t * buffer)
|
||||
void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const uint8_t * buffer)
|
||||
{
|
||||
DDS_OS_PUT_BYTES (os, buffer, len);
|
||||
}
|
||||
|
||||
void *dds_stream_address (dds_stream_t * s)
|
||||
{
|
||||
return DDS_CDR_ADDRESS(s, void);
|
||||
}
|
||||
|
||||
void *dds_stream_alignto (dds_stream_t * s, uint32_t a)
|
||||
{
|
||||
DDS_CDR_ALIGNTO (s, a);
|
||||
return DDS_CDR_ADDRESS (s, void);
|
||||
}
|
||||
|
||||
static void dds_stream_write
|
||||
(
|
||||
dds_stream_t * os,
|
||||
|
@ -1178,7 +1189,8 @@ void dds_stream_from_serdata_default (_Out_ dds_stream_t * s, _In_ const struct
|
|||
s->m_buffer.p8 = (uint8_t*) d;
|
||||
s->m_index = (uint32_t) offsetof (struct ddsi_serdata_default, data);
|
||||
s->m_size = d->size + s->m_index;
|
||||
s->m_endian = (d->bswap) ? (! DDS_ENDIAN) : DDS_ENDIAN;
|
||||
assert (d->hdr.identifier == CDR_LE || d->hdr.identifier == CDR_BE);
|
||||
s->m_endian = (d->hdr.identifier == CDR_LE);
|
||||
}
|
||||
|
||||
void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d)
|
||||
|
@ -1191,7 +1203,7 @@ void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_de
|
|||
|
||||
(*d) = s->m_buffer.pv;
|
||||
(*d)->pos = (s->m_index - (uint32_t)offsetof (struct ddsi_serdata_default, data));
|
||||
(*d)->size = (s->m_size - (uint32_t)offsetof(struct ddsi_serdata_default, data));
|
||||
(*d)->size = (s->m_size - (uint32_t)offsetof (struct ddsi_serdata_default, data));
|
||||
}
|
||||
|
||||
void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic)
|
||||
|
@ -1250,7 +1262,7 @@ void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct
|
|||
static uint32_t dds_stream_get_keyhash
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * dst,
|
||||
dds_stream_t * os,
|
||||
const uint32_t * ops,
|
||||
const bool just_key
|
||||
)
|
||||
|
@ -1261,9 +1273,9 @@ static uint32_t dds_stream_get_keyhash
|
|||
uint32_t subtype;
|
||||
uint32_t num;
|
||||
uint32_t len;
|
||||
const uint32_t origin = os->m_index;
|
||||
bool is_key;
|
||||
bool have_data;
|
||||
const char * origin = dst;
|
||||
|
||||
while ((op = *ops) != DDS_OP_RTS)
|
||||
{
|
||||
|
@ -1272,7 +1284,7 @@ static uint32_t dds_stream_get_keyhash
|
|||
case DDS_OP_ADR:
|
||||
{
|
||||
type = DDS_OP_TYPE (op);
|
||||
is_key = (op & DDS_OP_FLAG_KEY) && (dst != NULL);
|
||||
is_key = (op & DDS_OP_FLAG_KEY) && (os != NULL);
|
||||
have_data = is_key || !just_key;
|
||||
ops += 2;
|
||||
if (type <= DDS_OP_VAL_8BY)
|
||||
|
@ -1305,43 +1317,29 @@ static uint32_t dds_stream_get_keyhash
|
|||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
{
|
||||
*dst++ = (char) DDS_IS_GET1 (is);
|
||||
uint8_t v = DDS_IS_GET1 (is);
|
||||
DDS_OS_PUT1 (os, v);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_2BY:
|
||||
{
|
||||
uint16_t u16 = *DDS_CDR_ADDRESS (is, uint16_t);
|
||||
if (is->m_endian)
|
||||
{
|
||||
u16 = DDS_SWAP16 (u16);
|
||||
}
|
||||
memcpy (dst, &u16, sizeof (u16));
|
||||
is->m_index += 2;
|
||||
dst += 2;
|
||||
uint16_t v;
|
||||
DDS_IS_GET2 (is, v);
|
||||
DDS_OS_PUT2 (os, v);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_4BY:
|
||||
{
|
||||
uint32_t u32 = *DDS_CDR_ADDRESS (is, uint32_t);
|
||||
if (is->m_endian)
|
||||
{
|
||||
u32 = DDS_SWAP32 (u32);
|
||||
}
|
||||
memcpy (dst, &u32, sizeof (u32));
|
||||
is->m_index += 4;
|
||||
dst += 4;
|
||||
uint32_t v;
|
||||
DDS_IS_GET4 (is, v, uint32_t);
|
||||
DDS_OS_PUT4 (os, v, uint32_t);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
uint64_t u64 = *DDS_CDR_ADDRESS (is, uint64_t);
|
||||
if (is->m_endian)
|
||||
{
|
||||
u64 = DDS_SWAP64 (u64);
|
||||
}
|
||||
memcpy (dst, &u64, sizeof (u64));
|
||||
is->m_index += 8;
|
||||
dst += 8;
|
||||
uint64_t v;
|
||||
DDS_IS_GET8 (is, v, uint64_t);
|
||||
DDS_OS_PUT8 (os, v, uint64_t);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
|
@ -1352,11 +1350,8 @@ static uint32_t dds_stream_get_keyhash
|
|||
len = dds_stream_read_uint32 (is);
|
||||
if (is_key)
|
||||
{
|
||||
uint32_t be32 = toBE4u (len);
|
||||
memcpy (dst, &be32, 4);
|
||||
dst += 4;
|
||||
memcpy (dst, DDS_CDR_ADDRESS (is, void), len);
|
||||
dst += len;
|
||||
DDS_OS_PUT4 (os, len, uint32_t);
|
||||
DDS_OS_PUT_BYTES(os, DDS_CDR_ADDRESS (is, void), len);
|
||||
#ifdef OP_DEBUG_KEY
|
||||
TRACE (("K-ADR: String/BString (%d)\n", len));
|
||||
#endif
|
||||
|
@ -1443,8 +1438,11 @@ static uint32_t dds_stream_get_keyhash
|
|||
align = dds_op_size[subtype];
|
||||
if (is_key)
|
||||
{
|
||||
char *dst;
|
||||
DDS_CDR_ALIGNTO (os, align);
|
||||
dst = DDS_CDR_ADDRESS(os, char);
|
||||
dds_stream_read_fixed_buffer (is, dst, num, align, is->m_endian);
|
||||
dst += num * align;
|
||||
os->m_index += num * align;
|
||||
}
|
||||
is->m_index += num * align;
|
||||
}
|
||||
|
@ -1563,21 +1561,40 @@ static uint32_t dds_stream_get_keyhash
|
|||
}
|
||||
case DDS_OP_JSR: /* Implies nested type */
|
||||
{
|
||||
dst += dds_stream_get_keyhash (is, dst, ops + DDS_OP_JUMP (op), just_key);
|
||||
dds_stream_get_keyhash (is, os, ops + DDS_OP_JUMP (op), just_key);
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
return (uint32_t) (dst - origin);
|
||||
return os->m_index - origin;
|
||||
}
|
||||
|
||||
void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic)
|
||||
{
|
||||
const struct dds_topic_descriptor *desc = (const struct dds_topic_descriptor *) topic->type;
|
||||
uint32_t nbytes;
|
||||
os->m_endian = 0;
|
||||
if (os->m_size < is->m_size)
|
||||
{
|
||||
os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, is->m_size);
|
||||
os->m_size = is->m_size;
|
||||
}
|
||||
nbytes = dds_stream_get_keyhash (is, os, desc->m_ops, false);
|
||||
os->m_index += nbytes;
|
||||
if (os->m_index < os->m_size)
|
||||
{
|
||||
os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, os->m_index);
|
||||
os->m_size = os->m_index;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static bool keyhash_is_reset(const dds_key_hash_t *kh)
|
||||
{
|
||||
static const char nullhash[sizeof(kh->m_hash)] = { 0 };
|
||||
return kh->m_flags == 0 && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0;
|
||||
return !kh->m_set && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1589,44 +1606,35 @@ void dds_stream_read_keyhash
|
|||
const bool just_key
|
||||
)
|
||||
{
|
||||
char * dst;
|
||||
|
||||
assert (keyhash_is_reset(kh));
|
||||
|
||||
kh->m_set = 1;
|
||||
if (desc->m_nkeys == 0)
|
||||
kh->m_iskey = 1;
|
||||
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Select key buffer to use */
|
||||
|
||||
kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET;
|
||||
if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
kh->m_flags |= DDS_KEY_IS_HASH;
|
||||
dst = kh->m_hash;
|
||||
dds_stream_t os;
|
||||
uint32_t ncheck;
|
||||
kh->m_iskey = 1;
|
||||
dds_stream_init(&os, 0);
|
||||
os.m_buffer.pv = kh->m_hash;
|
||||
os.m_size = 16;
|
||||
os.m_endian = 0;
|
||||
ncheck = dds_stream_get_keyhash (is, &os, desc->m_ops, just_key);
|
||||
assert(ncheck <= 16);
|
||||
(void)ncheck;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is->m_size > kh->m_key_buff_size)
|
||||
{
|
||||
kh->m_key_buff = dds_realloc (kh->m_key_buff, is->m_size);
|
||||
kh->m_key_buff_size = (uint32_t) is->m_size;
|
||||
}
|
||||
dst = kh->m_key_buff;
|
||||
}
|
||||
kh->m_key_len = dds_stream_get_keyhash (is, dst, desc->m_ops, just_key);
|
||||
|
||||
if (kh->m_flags & DDS_KEY_IS_HASH)
|
||||
{
|
||||
assert (kh->m_key_len <= 16);
|
||||
kh->m_key_len = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hash is md5 of key */
|
||||
dds_key_md5 (kh);
|
||||
dds_stream_t os;
|
||||
md5_state_t md5st;
|
||||
kh->m_iskey = 0;
|
||||
dds_stream_init (&os, 0);
|
||||
os.m_endian = 0;
|
||||
dds_stream_get_keyhash (is, &os, desc->m_ops, just_key);
|
||||
md5_init (&md5st);
|
||||
md5_append (&md5st, os.m_buffer.p8, os.m_index);
|
||||
md5_finish (&md5st, (unsigned char *) kh->m_hash);
|
||||
dds_stream_fini (&os);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct ddsi_serda
|
|||
|
||||
typedef struct
|
||||
{
|
||||
const struct ddsi_sertopic *topic;
|
||||
uint64_t m_iid;
|
||||
void * m_sample;
|
||||
bool m_ret;
|
||||
|
@ -130,15 +131,15 @@ static void dds_tkmap_get_key_fn (void * vtk, void * varg)
|
|||
tkmap_get_key_arg * arg = (tkmap_get_key_arg*) varg;
|
||||
if (tk->m_iid == arg->m_iid)
|
||||
{
|
||||
ddsi_serdata_to_sample (tk->m_sample, arg->m_sample, 0, 0);
|
||||
ddsi_serdata_topicless_to_sample (arg->topic, tk->m_sample, arg->m_sample, 0, 0);
|
||||
arg->m_ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample)
|
||||
bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample)
|
||||
{
|
||||
tkmap_get_key_arg arg = { iid, sample, false };
|
||||
tkmap_get_key_arg arg = { topic, iid, sample, false };
|
||||
os_mutexLock (&map->m_lock);
|
||||
ut_chhEnumUnsafe (map->m_hh, dds_tkmap_get_key_fn, &arg);
|
||||
os_mutexUnlock (&map->m_lock);
|
||||
|
@ -192,12 +193,7 @@ struct tkmap_instance * dds_tkmap_find(
|
|||
struct tkmap_instance * tk;
|
||||
struct tkmap * map = gv.m_tkmap;
|
||||
|
||||
/* FIXME: check this */
|
||||
#if 0
|
||||
assert(sd->v.keyhash.m_flags & DDS_KEY_HASH_SET);
|
||||
#endif
|
||||
dummy.m_sample = sd;
|
||||
|
||||
retry:
|
||||
if ((tk = ut_chhLookup(map->m_hh, &dummy)) != NULL)
|
||||
{
|
||||
|
@ -223,7 +219,7 @@ retry:
|
|||
if ((tk = dds_alloc (sizeof (*tk))) == NULL)
|
||||
return NULL;
|
||||
|
||||
tk->m_sample = ddsi_serdata_ref (sd);
|
||||
tk->m_sample = ddsi_serdata_to_topicless (sd);
|
||||
tk->m_map = map;
|
||||
os_atomic_st32 (&tk->m_refc, 1);
|
||||
tk->m_iid = dds_iid_gen ();
|
||||
|
@ -238,7 +234,7 @@ retry:
|
|||
|
||||
if (tk && rd)
|
||||
{
|
||||
TRACE (("tk=%p iid=%"PRIx64"", &tk, tk->m_iid));
|
||||
TRACE (("tk=%p iid=%"PRIx64" ", &tk, tk->m_iid));
|
||||
}
|
||||
return tk;
|
||||
}
|
||||
|
@ -247,13 +243,6 @@ _Check_return_
|
|||
struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd)
|
||||
{
|
||||
assert (vtime_awake_p (lookup_thread_state ()->vtime));
|
||||
#if 0
|
||||
/* Topic might have been deleted -- FIXME: no way the topic may be deleted when there're still users out there */
|
||||
if (sd->v.st->topic == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return dds_tkmap_find (sd, true, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -424,7 +424,8 @@ dds_create_topic(
|
|||
st->c.typename = dds_alloc (strlen (typename) + 1);
|
||||
strcpy (st->c.typename, typename);
|
||||
st->c.ops = &ddsi_sertopic_ops_default;
|
||||
st->c.serdata_ops = &ddsi_serdata_ops_cdr;
|
||||
st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey;
|
||||
st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops);
|
||||
st->native_encoding_identifier = (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE);
|
||||
|
||||
st->type = (void*) desc;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue