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;