Hi Denis,
> Hi Petteri,
>
> On 09/15/2010 02:25 AM, Petteri Tikander wrote:
> > ---
> > src/smsutil.c | 70
> > ++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed,
> > 55 insertions(+), 15 deletions(-)
> >
> > diff --git a/src/smsutil.c b/src/smsutil.c
> > index 26c7951..2d47289 100644
> > --- a/src/smsutil.c
> > +++ b/src/smsutil.c
> > @@ -2826,14 +2826,18 @@ gboolean status_report_assembly_report(struct
> > status_report_assembly *assembly, unsigned int offset =
> > status_report->status_report.mr / 32;
> > unsigned int bit = 1 << (status_report->status_report.mr % 32);
> > struct id_table_node *node = NULL;
> > - const char *straddr;
> > + const char *straddr, *sent_addr;
> > + struct sms_address addr;
> > GHashTable *id_table;
> > gpointer key, value;
> > gboolean delivered;
> > - GHashTableIter iter;
> > + GHashTableIter iter_addr, iter;
> > gboolean pending;
> > int i;
> > unsigned int msg_id;
> > + unsigned int n_digits;
> > + unsigned int len_sent_addr;
> > + unsigned int len_rec_addr;
> >
> > /* We ignore temporary or tempfinal status reports */
> > if (sr_st_to_delivered(status_report->status_report.st,
> > @@ -2841,20 +2845,54 @@ gboolean status_report_assembly_report(struct
> > status_report_assembly *assembly, return FALSE;
> >
> > straddr = sms_address_to_string(&status_report->status_report.raddr);
> > - id_table = g_hash_table_lookup(assembly->assembly_table, straddr);
> >
> > - /* key (receiver address) does not exist in assembly */
> > - if (id_table == NULL)
> > - return FALSE;
> > + g_hash_table_iter_init(&iter_addr, assembly->assembly_table);
> >
> > - g_hash_table_iter_init(&iter, id_table);
> > - while (g_hash_table_iter_next(&iter, &key, &value)) {
> > - node = value;
>
> So my thinking is that for efficiency purposes we should try the direct
> lookup first. We don't want to pay the penalty of walking the entire
> hash table every time for networks that are 'sane'. If that fails, fall
> back to the 'fuzzy' lookup. This would also make the code a bit easier
> to follow I think...
OK. Direct lookup would do this same and look nicer. But I think (but not
sure) that g_hash_table_lookup() does similar looping internally, as my
addition for while-looping address-tables. Well I was already taking
g_hash_table_lookup() back, but just making the code uglier when adding
'international to national'-logic. That's because of iterating msg-id nodes,
so solution lead to two node-iteration loops.
My idea was to find suitable address&Mr-pair. So if address matches but MR
doesn't, let's continue (while-loop inside while-loop).
Was your idea actually that this inefficency-problem in looping occurs actually
in this point: if for some reason in sane networks the address matches, but MR
doesn't, function continues looping although it shouldn't? And then it loops
the entire table. In 'insane'-networks this is OK, because function is not
comparing necessarily the whole address?
>
> > + /*
> > + * Go through all addresses. Each address can relate to
> > + * 1-n msg_ids.
> > + */
> > + while (g_hash_table_iter_next(&iter_addr, (gpointer) &sent_addr,
> > + (gpointer) &id_table)) {
> > + /*
> > + * Some networks can change address to international format,
> > + * although address is sent in the national format.
> > + * So notify this special case by checking only
> > + * last six digits. If address contains less than six digits,
> > + * compare only existing digits.
> > + */
> > + if ((straddr[0] == '+') && (sent_addr[0] != '+')) {
>
> In theory it could also be vice-versa...
OK. Let's also taking care of 'international to national'-case.
>
> > + len_sent_addr = strlen(sent_addr);
> > + len_rec_addr = strlen(straddr);
> > + n_digits = (len_sent_addr > 6) ? 6 : len_sent_addr;
> >
> > - if (node->mrs[offset] & bit)
> > - break;
> > + if (strcmp(&straddr[len_rec_addr - n_digits],
> > + &sent_addr[len_sent_addr - n_digits]))
>
> Perhaps we should simply start at the last position of both strings and
> compare in reverse. If the match is MIN(6, strlen(sent_addr))
> characters, then accept this as a 'fuzzy' match.
>
OK. Lets' compare single characters in the reverse order.
> > + continue;
> > + }
> > + /*
> > + * In other cases the whole number received in the status report
> > + * should match with the number originally sent.
> > + */
> > + else if (strcmp(straddr, sent_addr))
> > + continue;
> > +
> > + g_hash_table_iter_init(&iter, id_table);
> > + while (g_hash_table_iter_next(&iter, &key, &value)) {
> > + node = value;
> > +
> > + if (node->mrs[offset] & bit)
> > + break;
> >
> > - node = NULL;
> > + node = NULL;
> > + }
> > +
> > + /*
> > + * Received address with MR matched with one of the stored
> > + * addresses and MR, so no need to continue searching.
> > + */
> > + if (node)
> > + break;
> > }
> >
> > /* Unable to find a message reference belonging to this address */
> > @@ -2881,6 +2919,8 @@ gboolean status_report_assembly_report(struct
> > status_report_assembly *assembly,
> >
> > msg_id = *(unsigned int *) key;
> >
> > + sms_address_from_string(&addr, sent_addr);
> > +
> > if (pending == TRUE && node->deliverable == TRUE) {
> > /*
> > * More status reports expected, and already received
> > @@ -2888,7 +2928,7 @@ gboolean status_report_assembly_report(struct
> > status_report_assembly *assembly, */
> > sr_assembly_add_fragment_backup(
> > assembly->imsi, node,
> > - &status_report->status_report.raddr,
> > + &addr,
> > msg_id);
> >
> > return FALSE;
> > @@ -2901,14 +2941,14 @@ gboolean status_report_assembly_report(struct
> > status_report_assembly *assembly, *out_id = msg_id;
> >
> > sr_assembly_remove_fragment_backup(assembly->imsi,
> > - &status_report->status_report.raddr,
> > + &addr,
> > msg_id);
> >
> > g_hash_table_iter_remove(&iter);
> >
> > if (g_hash_table_size(id_table) == 0)
> > g_hash_table_remove(assembly->assembly_table,
> > - status_report->status_report.raddr.address);
> > + sent_addr);
> >
> > return TRUE;
> > }
>
> Otherwise it looks good.
>
> Regards,
> -Denis
>
Have a nice week end.
Br, Petteri
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono