From 3d952f41c8d90b5c217616fb060697f93fb9db07 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 8 Nov 2010 22:16:57 -0800 Subject: Fix a bug in the way that we add tags that causes it to be really slow when adding a tag to lots of items. Tag_Model::save() would call item_related_update for every tag related to an item upon save which is an O(N!) operation. Fixes ticket #1412. --- modules/tag/helpers/tag.php | 1 + 1 file changed, 1 insertion(+) (limited to 'modules/tag/helpers') diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index 14d27c94..79e74385 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -126,6 +126,7 @@ class tag_Core { ->delete("items_tags") ->where("item_id", "=", $item->id) ->execute(); + module::event("item_related_update", $item); } /** -- cgit v1.2.3 From 7efa9a5b87eaa8fe86972376af8c58dc29c44392 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:01:29 -0800 Subject: Fix two issues with item deletion: 1) We're compacting tags on every deletion which is slow. Since we delete albums in batch, we should just do one tag compaction at the end. Fixes #1487. 2) Issue introduced in 3d952f41c8d90b5c217616fb060697f93fb9db07 where we trigger an item_related_update in tag::clear_all(). Since tag::clear_all() is called when we delete an item, this causes the search module to attempt to index a deleted item. Move that triggering upstream. --- modules/tag/helpers/tag.php | 1 - modules/tag/helpers/tag_event.php | 11 +++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'modules/tag/helpers') diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index 79e74385..14d27c94 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -126,7 +126,6 @@ class tag_Core { ->delete("items_tags") ->where("item_id", "=", $item->id) ->execute(); - module::event("item_related_update", $item); } /** diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php index 0cc2170c..829089c4 100644 --- a/modules/tag/helpers/tag_event.php +++ b/modules/tag/helpers/tag_event.php @@ -62,6 +62,12 @@ class tag_event_Core { static function item_deleted($item) { tag::clear_all($item); + if (!batch::in_progress()) { + tag::compact(); + } + } + + static function batch_complete() { tag::compact(); } @@ -88,6 +94,7 @@ class tag_event_Core { tag::add($item, trim($tag_name)); } } + module::event("item_related_update", $item); tag::compact(); } @@ -109,7 +116,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + $group = $form->add_photos; $group->input("tags") ->label(t("Add tags to all uploaded files")) @@ -132,7 +139,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + foreach (explode(",", $form->add_photos->tags->value) as $tag_name) { $tag_name = trim($tag_name); if ($tag_name) { -- cgit v1.2.3 From d49a6dcc995d0c0073b3173d81cac7f3eb6ee30f Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:45:30 -0800 Subject: Create a new task to resync tag task counts and delete tags that have no associated items. --- modules/tag/helpers/tag_task.php | 97 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 modules/tag/helpers/tag_task.php (limited to 'modules/tag/helpers') diff --git a/modules/tag/helpers/tag_task.php b/modules/tag/helpers/tag_task.php new file mode 100644 index 00000000..087c85de --- /dev/null +++ b/modules/tag/helpers/tag_task.php @@ -0,0 +1,97 @@ +callback("tag_task::clean_up_tags") + ->name(t("Clean up tags")) + ->description(t("Correct tag counts and remove tags with no items")) + ->severity(log::SUCCESS); + return $tasks; + } + + /** + * Fix up tag counts and delete any tags that have no associated items. + * @param Task_Model the task + */ + static function clean_up_tags($task) { + $errors = array(); + try { + $start = microtime(true); + $last_tag_id = $task->get("last_tag_id", null); + $current = 0; + $total = 0; + + switch ($task->get("mode", "init")) { + case "init": + $task->set("total", ORM::factory("tag")->count_all()); + $task->set("mode", "clean_up_tags"); + $task->set("completed", 0); + $task->set("last_tag_id", 0); + + case "clean_up_tags": + $completed = $task->get("completed"); + $total = $task->get("total"); + $last_tag_id = $task->get("last_tag_id"); + $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(); + Kohana_Log::add("error",print_r(Database::instance()->last_query(),1)); + while ($current < $total && microtime(true) - $start < 1 && $tag = $tags->current()) { + $last_tag_id = $tag->id; + $real_count = $tag->items_count(); + if ($tag->count != $real_count) { + $tag->count = $real_count; + if ($tag->count) { + $task->log( + "Fixing count for tag {$tag->name} (id: {$tag->id}, new count: {$tag->count})"); + $tag->save(); + } else { + $task->log("Deleting empty tag {$tag->name} ({$tag->id})"); + $tag->delete(); + } + } + + $completed++; + $tags->next(); + } + $task->percent_complete = $completed / $total * 100; + $task->set("completed", $completed); + $task->set("last_tag_id", $last_tag_id); + } + + $task->status = t2("Examined %count tag", "Examined %count tags", $completed); + + if ($completed == $total) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } + } catch (Exception $e) { + Kohana_Log::add("error",(string)$e); + $task->done = true; + $task->state = "error"; + $task->status = $e->getMessage(); + $errors[] = (string)$e; + } + if ($errors) { + $task->log($errors); + } + } +} \ No newline at end of file -- cgit v1.2.3 From add586bbb129280badb484ae0fdaaa10372e4dc7 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:53:30 -0800 Subject: Create a task to clean up tag counts and delete tag with no associated items. Fixes #1488. --- modules/tag/helpers/tag_task.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/tag/helpers') diff --git a/modules/tag/helpers/tag_task.php b/modules/tag/helpers/tag_task.php index 087c85de..7bf50546 100644 --- a/modules/tag/helpers/tag_task.php +++ b/modules/tag/helpers/tag_task.php @@ -51,7 +51,7 @@ class tag_task_Core { $completed = $task->get("completed"); $total = $task->get("total"); $last_tag_id = $task->get("last_tag_id"); - $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(); + $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(25); Kohana_Log::add("error",print_r(Database::instance()->last_query(),1)); while ($current < $total && microtime(true) - $start < 1 && $tag = $tags->current()) { $last_tag_id = $tag->id; -- cgit v1.2.3