Mercurial > pidgin
comparison src/blist.c @ 5247:60983a46700e
[gaim-migrate @ 5618]
(22:40:26) Paco-Paco: gaim_find_buddy was an O(n) search through the blist tree, this adds an auxilliary hash to bring that down to O(1)
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 28 Apr 2003 02:41:00 +0000 |
parents | 757d680f923d |
children | e131ab86ead7 |
comparison
equal
deleted
inserted
replaced
5246:e9452def017f | 5247:60983a46700e |
---|---|
63 if (!node) | 63 if (!node) |
64 return NULL; | 64 return NULL; |
65 return gaim_blist_get_last_sibling(node->child); | 65 return gaim_blist_get_last_sibling(node->child); |
66 } | 66 } |
67 | 67 |
68 struct _gaim_hbuddy { | |
69 char *name; | |
70 struct gaim_account *account; | |
71 }; | |
72 | |
73 static guint _gaim_blist_hbuddy_hash (struct _gaim_hbuddy *hb) | |
74 { | |
75 return g_str_hash(hb->name); | |
76 } | |
77 | |
78 static guint _gaim_blist_hbuddy_equal (struct _gaim_hbuddy *hb1, struct _gaim_hbuddy *hb2) | |
79 { | |
80 return ((!strcmp(hb1->name, hb2->name)) && hb1->account == hb2->account); | |
81 } | |
82 | |
68 /***************************************************************************** | 83 /***************************************************************************** |
69 * Public API functions * | 84 * Public API functions * |
70 *****************************************************************************/ | 85 *****************************************************************************/ |
71 | 86 |
72 struct gaim_buddy_list *gaim_blist_new() | 87 struct gaim_buddy_list *gaim_blist_new() |
73 { | 88 { |
74 struct gaim_buddy_list *gbl = g_new0(struct gaim_buddy_list, 1); | 89 struct gaim_buddy_list *gbl = g_new0(struct gaim_buddy_list, 1); |
75 | 90 |
76 gbl->ui_ops = gaim_get_blist_ui_ops(); | 91 gbl->ui_ops = gaim_get_blist_ui_ops(); |
92 | |
93 gbl->buddies = g_hash_table_new ((GHashFunc)_gaim_blist_hbuddy_hash, | |
94 (GEqualFunc)_gaim_blist_hbuddy_equal); | |
77 | 95 |
78 if (gbl->ui_ops != NULL && gbl->ui_ops->new_list != NULL) | 96 if (gbl->ui_ops != NULL && gbl->ui_ops->new_list != NULL) |
79 gbl->ui_ops->new_list(gbl); | 97 gbl->ui_ops->new_list(gbl); |
80 | 98 |
81 return gbl; | 99 return gbl; |
346 void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node) | 364 void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node) |
347 { | 365 { |
348 GaimBlistNode *n = node, *bnode = (GaimBlistNode*)buddy; | 366 GaimBlistNode *n = node, *bnode = (GaimBlistNode*)buddy; |
349 struct group *g = group; | 367 struct group *g = group; |
350 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; | 368 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; |
369 struct _gaim_hbuddy *hb; | |
351 gboolean save = FALSE; | 370 gboolean save = FALSE; |
352 | 371 |
353 if (!n) { | 372 if (!n) { |
354 if (!g) { | 373 if (!g) { |
355 g = gaim_group_new(_("Buddies")); | 374 g = gaim_group_new(_("Buddies")); |
394 ((GaimBlistNode*)buddy)->next = NULL; | 413 ((GaimBlistNode*)buddy)->next = NULL; |
395 ((GaimBlistNode*)buddy)->prev = NULL; | 414 ((GaimBlistNode*)buddy)->prev = NULL; |
396 ((GaimBlistNode*)buddy)->parent = (GaimBlistNode*)g; | 415 ((GaimBlistNode*)buddy)->parent = (GaimBlistNode*)g; |
397 } | 416 } |
398 | 417 |
418 hb = g_malloc(sizeof(struct _gaim_hbuddy)); | |
419 hb->name = g_strdup(normalize(buddy->name)); | |
420 hb->account = buddy->account; | |
421 | |
422 if (g_hash_table_lookup(gaimbuddylist->buddies, (gpointer)hb)) { | |
423 /* This guy already exists */ | |
424 g_free(hb->name); | |
425 g_free(hb); | |
426 } else { | |
427 g_hash_table_insert(gaimbuddylist->buddies, (gpointer)hb, (gpointer)buddy); | |
428 } | |
429 | |
399 if (ops) | 430 if (ops) |
400 ops->update(gaimbuddylist, (GaimBlistNode*)buddy); | 431 ops->update(gaimbuddylist, (GaimBlistNode*)buddy); |
401 if (save) | 432 if (save) |
402 gaim_blist_save(); | 433 gaim_blist_save(); |
403 } | 434 } |
479 { | 510 { |
480 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; | 511 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; |
481 | 512 |
482 GaimBlistNode *gnode, *node = (GaimBlistNode*)buddy; | 513 GaimBlistNode *gnode, *node = (GaimBlistNode*)buddy; |
483 struct group *group; | 514 struct group *group; |
515 struct _gaim_hbuddy hb, *key; | |
516 struct buddy *val; | |
484 | 517 |
485 gnode = node->parent; | 518 gnode = node->parent; |
486 group = (struct group *)gnode; | 519 group = (struct group *)gnode; |
487 | 520 |
488 if(gnode->child == node) | 521 if(gnode->child == node) |
489 gnode->child = node->next; | 522 gnode->child = node->next; |
490 if (node->prev) | 523 if (node->prev) |
491 node->prev->next = node->next; | 524 node->prev->next = node->next; |
492 if (node->next) | 525 if (node->next) |
493 node->next->prev = node->prev; | 526 node->next->prev = node->prev; |
527 | |
528 hb.name = normalize(buddy->name); | |
529 hb.account = buddy->account; | |
530 if (g_hash_table_lookup_extended(gaimbuddylist->buddies, &hb, (gpointer *)&key, (gpointer *)&val)) { | |
531 g_hash_table_remove(gaimbuddylist->buddies, &hb); | |
532 g_free(key->name); | |
533 g_free(key); | |
534 } | |
494 | 535 |
495 ops->remove(gaimbuddylist, node); | 536 ops->remove(gaimbuddylist, node); |
496 g_hash_table_destroy(buddy->settings); | 537 g_hash_table_destroy(buddy->settings); |
497 g_free(buddy->name); | 538 g_free(buddy->name); |
498 g_free(buddy->alias); | 539 g_free(buddy->alias); |
577 | 618 |
578 } | 619 } |
579 | 620 |
580 struct buddy *gaim_find_buddy(struct gaim_account *account, const char *name) | 621 struct buddy *gaim_find_buddy(struct gaim_account *account, const char *name) |
581 { | 622 { |
582 GaimBlistNode *group; | 623 struct buddy *buddy; |
583 GaimBlistNode *buddy; | 624 struct _gaim_hbuddy hb; |
584 char *norm_name = g_strdup(normalize(name)); | |
585 | 625 |
586 if (!gaimbuddylist) | 626 if (!gaimbuddylist) |
587 return NULL; | 627 return NULL; |
588 | 628 |
589 group = gaimbuddylist->root; | 629 hb.name = normalize(name); |
590 while (group) { | 630 hb.account = account; |
591 buddy = group->child; | 631 buddy = g_hash_table_lookup(gaimbuddylist->buddies, &hb); |
592 while (buddy) { | 632 |
593 if(GAIM_BLIST_NODE_IS_BUDDY(buddy)) { | 633 return buddy; |
594 if (!gaim_utf8_strcasecmp(normalize(((struct buddy*)buddy)->name), norm_name) && account == ((struct buddy*)buddy)->account) { | |
595 g_free(norm_name); | |
596 return (struct buddy*)buddy; | |
597 } | |
598 } | |
599 buddy = buddy->next; | |
600 } | |
601 group = group->next; | |
602 } | |
603 g_free(norm_name); | |
604 return NULL; | |
605 } | 634 } |
606 | 635 |
607 struct group *gaim_find_group(const char *name) | 636 struct group *gaim_find_group(const char *name) |
608 { | 637 { |
609 GaimBlistNode *node; | 638 GaimBlistNode *node; |