Browse Source

use memoize to cache nick colours

Byron Jones 6 years ago
parent
commit
919f0c5046

+ 1 - 0
cpanfile

@@ -13,6 +13,7 @@ requires 'JSON::XS', '3.03';
 requires 'List::MoreUtils', '0.419';
 requires 'List::Util', '1.33';
 requires 'Memcached::libmemcached', '1.001801';
+requires 'Memoize::ExpireLRU', '0.56';
 requires 'Mojolicious', '7.65';
 requires 'Mojolicious::Plugin::AccessLog', '0.010';
 requires 'Net::DNS::Native', '0.15';

+ 1 - 1
dev-precommit

@@ -252,7 +252,7 @@ sub find_unused_imports {
 
     my @issues;
     foreach my $module (sort keys %modules) {
-        next if $input =~ /\b$module(?:->|::)/;
+        next if $input =~ /\b$module(?:->|::)/ || $input =~ /'$module'/;
         push @issues, "package $module is unused";
     }
     foreach my $import (sort keys %imports) {

+ 1 - 1
dev-server

@@ -52,7 +52,7 @@ if (!any { $_ eq '--no-cache' } @switches) {
 
 # web server
 my $morbo = Mojo::Server::Morbo->new();
-$morbo->backend->watch(['web/templates/', 'web/templates/layouts/', 'lib/LogBot']);
+$morbo->backend->watch(['web/templates/', 'web/templates/layouts/', 'lib/LogBot', 'lib/Logbot/Web']);
 $morbo->run('logbot-web');
 
 package Make;

+ 42 - 0
lib/LogBot/Web/Colour.pm

@@ -0,0 +1,42 @@
+package LogBot::Web::Colour;
+use local::lib;
+use v5.10;
+use strict;
+use warnings;
+
+use Digest::xxHash qw( xxhash32 );
+use Memoize qw( memoize );
+use Memoize::ExpireLRU ();
+
+our @EXPORT_OK = qw(
+    nick_hash nick_colour
+);
+use parent 'Exporter';
+
+sub nick_hash {
+    my ($nick) = @_;
+
+    $nick = lc($nick);
+    $nick =~ s/[`_]+$//;
+    $nick =~ s/\|.*$//;
+
+    return xxhash32($nick, 0);
+}
+
+sub nick_colour {
+    my ($hash) = @_;
+    $hash = $hash + 0;
+
+    my $h = $hash % 360;
+    my $l = $h >= 30 && $h <= 210 ? 30 : 50;
+    my $s = 20 + $hash % 80;
+
+    return 'hsl(' . $h . ',' . $s . '%,' . $l . '%)';
+}
+
+{
+    tie(my %cache => 'Memoize::ExpireLRU', CACHESIZE => 5_000);  ## no critic (Miscellanea::ProhibitTies)
+    memoize('nick_colour', [HASH => \%cache, SCALAR_CACHE => 'FAULT']);
+}
+
+1;

+ 2 - 44
lib/LogBot/Web/Util.pm

@@ -6,11 +6,11 @@ use warnings;
 
 use Date::Parse qw( str2time );
 use DateTime ();
-use Digest::xxHash qw( xxhash32 );
 use Encode qw ( decode );
 use File::Basename qw( basename );
 use LogBot::Database qw( dbh );
 use LogBot::Util qw( nick_is_bot normalise_channel time_to_ymd ymd_to_time );
+use LogBot::Web::Colour qw( nick_hash );
 use Module::Load qw( load );
 use Mojo::Path ();
 use Mojo::URL  ();
@@ -20,7 +20,6 @@ use URI::Find ();
 
 our @EXPORT_OK = qw(
     render_init
-    nick_hash nick_colour nick_colour_init
     rewrite_old_urls
     url_for_channel irc_host
     channel_from_param date_from_param
@@ -33,52 +32,11 @@ use parent 'Exporter';
 sub render_init {
     my ($path) = @_;
     foreach my $file (glob($path . '/lib/LogBot/Web/*.pm')) {
-        next if basename($file) eq 'Util.pm';
+        next if basename($file) =~ /^(?:Colour|Util)\.pm$/;
         load($file);
     }
 }
 
-sub nick_hash {
-    my ($nick) = @_;
-    $nick = lc($nick);
-    $nick =~ s/[`_]+$//;
-    $nick =~ s/\|.*$//;
-
-    return xxhash32($nick, 0);
-}
-
-my $nick_colour_cache = {};
-Readonly::Scalar my $MAX_NICK_CACHE_COUNT => 1_000;
-
-# don't let the cache grow above a specified size
-sub nick_colour_init {
-    my $count = scalar keys %{$nick_colour_cache};
-    return if $count < $MAX_NICK_CACHE_COUNT;
-    my @hashes = sort { $nick_colour_cache->{$a}->[0] <=> $nick_colour_cache->{$b}->[0] } keys %{$nick_colour_cache};
-    splice(@hashes, 0, $MAX_NICK_CACHE_COUNT);
-    foreach my $hash (@hashes) {
-        delete $nick_colour_cache->{$hash};
-    }
-}
-
-sub nick_colour {
-    my ($hash) = @_;
-
-    if (my $cached = $nick_colour_cache->{$hash}) {
-        return $cached->[1];
-    }
-    $hash = $hash + 0;
-
-    my $h = $hash % 360;
-    my $l = $h >= 30 && $h <= 210 ? 30 : 50;
-    my $s = 20 + $hash % 80;
-
-    my $colour = 'hsl(' . $h . ',' . $s . '%,' . $l . '%)';
-
-    $nick_colour_cache->{$hash} = [time(), $colour];
-    return $colour;
-}
-
 sub rewrite_old_urls {
     my ($c) = @_;
     my $network_channel = $c->req->query_params->param('c') // return;

+ 1 - 1
logbot-nightly

@@ -20,7 +20,7 @@ use List::Util qw( any );
 use LogBot::Config qw( find_config load_all_configs load_config reload_config save_config );
 use LogBot::Database qw( dbh replace_sql_placeholders );
 use LogBot::Util qw( file_for logbot_init nick_is_bot round spurt );
-use LogBot::Web::Util qw( nick_hash );
+use LogBot::Web::Colour qw( nick_hash );
 use Readonly;
 
 Readonly::Scalar my $ARCHIVE_TIME => 60 * 60 * 24 * (365 / 2);  # 6 months

+ 1 - 3
logbot-web

@@ -21,7 +21,7 @@ use IO::Compress::Gzip qw( gzip );
 use LogBot::Config qw( find_config load_all_configs load_config reload_config );
 use LogBot::MemCache ();
 use LogBot::Util qw( file_for file_time time_to_ymd );
-use LogBot::Web::Util qw( channel_from_param channel_topics linkify nick_colour_init render_init rewrite_old_urls );
+use LogBot::Web::Util qw( channel_from_param channel_topics linkify render_init rewrite_old_urls );
 use Mojo::ByteStream ();
 use Mojo::Log        ();
 use Mojo::Util qw( dumper );
@@ -96,8 +96,6 @@ under sub {
     # for client-side list cache
     my $topics_lastmod = file_time(file_for($config, 'topics_lastmod')) // 0;
 
-    nick_colour_init();
-
     $c->stash(
         config          => $config,
         networks        => $networks,

+ 2 - 1
web/templates/channel.html.ep

@@ -2,7 +2,8 @@
 
 % use DateTime ();
 % use LogBot::Util qw( time_to_datestr time_ago );
-% use LogBot::Web::Util qw( nick_colour url_for_channel );
+% use LogBot::Web::Colour qw( nick_colour );
+% use LogBot::Web::Util qw( url_for_channel );
 % use Mojo::Util qw( trim );
 
 %= cached $is_today ? '' : $channel . '.' . $date->ymd('') => begin

+ 2 - 1
web/templates/search.html.ep

@@ -2,7 +2,8 @@
 
 % use List::Util qw( any uniq );
 % use LogBot::Util qw( time_to_ymd time_to_datestr );
-% use LogBot::Web::Util qw( nick_colour url_for_channel );
+% use LogBot::Web::Colour qw( nick_colour );
+% use LogBot::Web::Util qw( url_for_channel );
 
 % my $last_channel = $ch eq '' ? $last_c : $ch;
 

+ 1 - 1
web/templates/stats_nicks.html.ep

@@ -1,7 +1,7 @@
 <table id="top-nicks">
 % use List::Util qw( uniq );
+% use LogBot::Web::Colour qw( nick_colour );
 % use LogBot::Util qw( commify );
-% use LogBot::Web::Util qw( nick_colour );
 
 <style>
 % foreach my $hash (uniq grep { $_ } map { $_->{hash} } @$nicks) {