[rt-users] Handling a ticket that contains MANY comments

Igor Melnichuk ami at portaone.com
Tue Apr 26 02:08:19 EDT 2011


Some time ago for this case I have gotten the following Perl optimization:
      small ticket (1-3 comments)  ~3-7% speed-up
      large ticket  ~38-39%  speed-up
      huge ticket   ~45-47%  speed-up

So, I got an average of 35% speed-up per ticket as they are usually large.
Main points - avoid needless iterations in grep/map cycles and avoid 
needless $Transaction->Id() calls (it was done using hashes).

Perhaps it will be helpful for someone

Base RT version: 3.8.4
Modified ShowHistory file is attached and here is the diff:

diff -u /usr/local/rt3/share/html/Ticket/Elements/ShowHistory 
/usr/local/rt3/local/html/Ticket/Elements/ShowHistory
--- /usr/local/rt3/share/html/Ticket/Elements/ShowHistory 2010-09-06 
10:31:37.000000000 +0300
+++ /usr/local/rt3/local/html/Ticket/Elements/ShowHistory 2011-04-12 
15:28:44.000000000 +0300
@@ -82,10 +82,31 @@

   <div id="ticket-history">
   <%perl>
-my @attachments = @{$Attachments->ItemsArrayRef()};
-my @attachment_content = @{$AttachmentContent->ItemsArrayRef()};
+my $attachments = \@{ $Attachments->ItemsArrayRef() };
+my $attachment_content = \@{ $AttachmentContent->ItemsArrayRef() };

-while ( my $Transaction = $Transactions->Next ) {
+my %attachments_hash = ();
+my %attachment_content_hash = ();
+
+for (my $i = 0; $i <= scalar(@{$attachments}); $i++) {
+       next unless ($attachments->[$i]);
+       my $attach_transactionId = $attachments->[$i]->TransactionId();
+       if ( $attachments_hash{ $attach_transactionId } ) {
+               my $j = scalar( @{$attachments_hash{ 
$attach_transactionId }} );
+               $attachments_hash{ $attach_transactionId }[$j] = 
$attachments->[$i];
+       } else {
+               $attachments_hash{ $attach_transactionId }[0] = 
$attachments->[$i];
+       }
+}
+
+for (my $i = 0; $i <= scalar(@{$attachment_content}); $i++) {
+       next unless ($attachment_content->[$i]);
+       my $attach_cont_transactionId = 
$attachment_content->[$i]->TransactionId();
+       $attachment_content_hash{ $attach_cont_transactionId }[0] = 
$attachment_content->[$i]->Id();
+       $attachment_content_hash{ $attach_cont_transactionId }[1] = 
$attachment_content->[$i];
+}
+
+while ( my $Transaction = $Transactions->Next() ) {
       my $skip = 0;
       $m->callback(
           %ARGS,
@@ -96,16 +117,17 @@
       next if $skip;

       $i++;
-
-    my @trans_attachments = grep { $_->TransactionId == 
$Transaction->Id } @attachments;
+    my $transaction_id = $Transaction->Id();
+
+       my @trans_attachments = @{ $attachments_hash{ $transaction_id } 
} if ($attachments_hash{ $transaction_id });

       my $trans_content = {};
-    grep { ($_->TransactionId == $Transaction->Id ) && 
($trans_content->{$_->Id} = $_)  } @attachment_content;
+    $trans_content->{ $attachment_content_hash{ $transaction_id }[0] } 
= $attachment_content_hash{ $transaction_id }[1];


       my $IsLastTransaction = 0;
       if ( $OldestFirst ) {
-        $IsLastTransaction = $Transactions->IsLast;
+        $IsLastTransaction = $Transactions->IsLast();
       } else {
           $IsLastTransaction = 1 if ( $i == 1 );
       }
@@ -128,6 +150,8 @@
   $m->flush_buffer();
   }

+%attachments_hash = ();
+%attachment_content_hash = ();
   </%perl>
   </div>
   % if ($ShowDisplayModes or $ShowTitle) {
@@ -138,13 +162,29 @@
   my $Transactions = new RT::Transactions($session{'CurrentUser'});
   if ($Tickets) {
       while (my $t = $Tickets->Next) {
-        $Transactions->LimitToTicket($t->id);
+        if ( $t->id == $Ticket->id ) {
+            #$Transactions->LimitToTicket($t->id);
+            my $trs = RT::Transactions->new( $session{'CurrentUser'} );
+            $trs->LimitToTicket( $t->id );
+            $trs->LimitToTicket($t->id);
+            while ( my $tr = $trs->Next ) {
+                $Transactions->Limit( FIELD => 'id', VALUE => $tr->id, 
ENTRYAGGREGATOR => 'OR' );
+            }
+        } else {
+            my $trs = RT::Transactions->new( $session{'CurrentUser'} );
+            $trs->LimitToTicket( $t->id );
+            $trs->Limit( FIELD => 'Type', VALUE => 'Create', 
ENTRYAGGREGATOR => 'OR' );
+            $trs->Limit( FIELD => 'Type', VALUE => 'Correspond', 
ENTRYAGGREGATOR => 'OR' );
+            #$trs->Limit( FIELD => 'Type', VALUE => 'EmailRecord', 
ENTRYAGGREGATOR => 'OR' );
+            while ( my $tr = $trs->Next ) {
+                $Transactions->Limit( FIELD => 'id', VALUE => $tr->id, 
ENTRYAGGREGATOR => 'OR' );
+            }
+        }
       }
   } else {
       $Transactions = $Ticket->Transactions;
   }

-
   my $OldestFirst = RT->Config->Get( 'OldestTransactionsFirst', 
$session{'CurrentUser'} );
   my $SortOrder = $OldestFirst? 'ASC': 'DESC';
   $Transactions->OrderByCols( { FIELD => 'Created',




-- 
Yours sincerely,

Igor Melnichuk
PortaOne, Inc.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ShowHistory.zip
Type: application/zip
Size: 2661 bytes
Desc: not available
URL: <http://lists.bestpractical.com/pipermail/rt-users/attachments/20110426/9621c23b/attachment.zip>


More information about the rt-users mailing list