blob: fffa9e58b46dce5c8e93db7f1b29b9c3879562b3 [file] [log] [blame]
Marc Kupietzbf9bac02022-04-11 21:16:47 +02001use utf8;
2package IDS::DeReKoVecs::Read;
Marc Kupietz3576c622023-11-05 08:51:58 +01003use LWP::Simple;
Marc Kupietzbf9bac02022-04-11 21:16:47 +02004use strict;
5use warnings;
6use Config;
7
8my $src_file = undef;
9
10our $mergedEnd=0;
Marc Kupietzbf9bac02022-04-11 21:16:47 +020011our $opt_p = 5676;
12our $opt_C;
13
Marc Kupietzaf436142026-07-30 14:40:10 +090014# Cached values are large (a classic collocator profile is tens to hundreds of
15# kilobytes of JSON), so the caches are size limited. Without a limit a long
16# running worker accumulates one entry per queried word until the box runs out
17# of memory. Defaults can be overridden via configure_cache().
18our $CC_CACHE_MAX_KEYS = 200; # classic collocators
19our $SP_CACHE_MAX_KEYS = 200; # similar profiles
20
Marc Kupietzbf9bac02022-04-11 21:16:47 +020021BEGIN {
22 $src_file = __FILE__;
23 $src_file =~ s/Read.pm/derekovecs-server.c/;
24}
25
Marc Kupietzf6046912024-12-03 17:21:57 +010026use Inline C => "$src_file" => CLEAN_AFTER_BUILD => 0, BUILD_NOISY => 1, ccflags => $Config{ccflags} . "-Wall -Wno-unused-result -O4 -mno-avx2 -I/usr/local/include", libs => "-L/usr/local/lib64 -L/usr/local/lib -lcollocatordb";
Marc Kupietzbf9bac02022-04-11 21:16:47 +020027#use Inline C => Config => BUILD_NOISY => 1, CFLAGS => $Config{cflags}." -O4 -mtune k9";
28#use Inline C => Config => CLEAN_AFTER_BUILD => 0, ccflags => $Config{ccflags}." -Ofast -march k8 -mtune k8 ";
29
30use Mojo::JSON qw(decode_json encode_json to_json);
Marc Kupietzaf436142026-07-30 14:40:10 +090031use Mojo::Cache;
Marc Kupietzbf9bac02022-04-11 21:16:47 +020032use Exporter qw(import);
33
Marc Kupietzaf436142026-07-30 14:40:10 +090034our @EXPORT = qw(init_net load_sprofiles getVocabSize getDowntimeCalendar getCollocationAssociation getClassicCollocatorsCached getSimilarProfiles getSimilarProfilesCached getBiggestMergedDifferences filter_garbage get_neighbours getWordNumber dump_vecs dump_for_numpy cos_similarity_as_json get_version getPosWiseW2VCollocators configure_cache cache_stats);
35
36my $cccache = Mojo::Cache->new(max_keys => $CC_CACHE_MAX_KEYS); # classic collocator cache
37my $spcache = Mojo::Cache->new(max_keys => $SP_CACHE_MAX_KEYS); # similar profile cache
38
39# Adjust the caches at startup, e.g.
40# configure_cache(collocators_max_keys => 500, no_cache => 1)
41# A max_keys value <= 0 disables the respective cache. Setting a limit starts
42# from an empty cache, so that a lowered limit takes effect immediately.
43sub configure_cache {
44 my (%opt) = @_;
45 $opt_C = $opt{no_cache} if defined $opt{no_cache};
46 $cccache = Mojo::Cache->new(max_keys => $opt{collocators_max_keys})
47 if defined $opt{collocators_max_keys};
48 $spcache = Mojo::Cache->new(max_keys => $opt{profiles_max_keys})
49 if defined $opt{profiles_max_keys};
50 return;
51}
52
53sub cache_stats {
54 return {
55 collocators => {
56 keys => scalar keys %{$cccache->{cache} || {}},
57 max_keys => $cccache->max_keys
58 },
59 profiles => {
60 keys => scalar keys %{$spcache->{cache} || {}},
61 max_keys => $spcache->max_keys
62 }
63 };
64}
Marc Kupietzbf9bac02022-04-11 21:16:47 +020065
Marc Kupietz3576c622023-11-05 08:51:58 +010066sub getDowntimeCalendar {
67 my ($url) = @_;
68 if ($url =~ m/^\s*$/) {
69 return "";
70 }
71 my $calendar = LWP::Simple::get($url);
72 return $calendar;
73}
Marc Kupietzbf9bac02022-04-11 21:16:47 +020074
75sub getCollocationAssociation {
76 my ($c, $word, $collocate) = @_;
77 return getCollocationScores($word, $collocate)
78}
79
80sub getClassicCollocatorsCached {
Marc Kupietz3eeec652024-11-18 18:30:04 +010081 my ($c, $word, $compare_to) = @_;
Marc Kupietzbf9bac02022-04-11 21:16:47 +020082 my $s2 = "";
83 if($word > $mergedEnd) {
84 $word-=$mergedEnd;
85 }
86
Marc Kupietz3eeec652024-11-18 18:30:04 +010087 my $pipe;
88 if($compare_to ne "") {
89 $c->app->log->info("comparing syn neighbours to: $compare_to/getClassicCollocators?w=$word");
90 open $pipe, "lwp-request $compare_to/getClassicCollocators?w=$word |";
Marc Kupietzbf9bac02022-04-11 21:16:47 +020091 }
Marc Kupietz3eeec652024-11-18 18:30:04 +010092
Marc Kupietzaf436142026-07-30 14:40:10 +090093 my $collocators = $opt_C ? undef : $cccache->get($word);
94 if(!defined $collocators) {
Marc Kupietzbf9bac02022-04-11 21:16:47 +020095 $c->app->log->info("Getting classic collocates of $word.");
Marc Kupietzaf436142026-07-30 14:40:10 +090096 $collocators = getClassicCollocators($word);
97 $collocators =~ s/:(-?)(nan|inf)/:"${1}${2}"/g;
98 $collocators =~ s/"""/"\\""/g;
99 $cccache->set($word => $collocators) unless $opt_C;
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200100 } else {
101 $c->app->log->info("Getting classic collocates for $word from cache.");
102 }
Marc Kupietz3eeec652024-11-18 18:30:04 +0100103
104 if(defined($pipe)) {
105 while(<$pipe>) {
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200106 $s2 .= $_;
107 }
Marc Kupietz3eeec652024-11-18 18:30:04 +0100108 close($pipe);
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200109 }
110
111 if(length($s2) > 2000) {
Marc Kupietzaf436142026-07-30 14:40:10 +0900112 my $d1 = decode_json($collocators);
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200113 my $d2 = decode_json($s2);
114 my %d2ld;
115 my $minLd = 14;
116 foreach my $i (@{$d2->{collocates}}) {
117 $d2ld{$i->{word}}=$i->{ld};
118 $minLd=$i->{ld} if($i->{ld} < $minLd);
119 }
120 foreach my $i (@{$d1->{collocates}}) {
121 my $w = $i->{word};
122 $i->{delta} = $i->{ld} - (defined $d2ld{$w} ? $d2ld{$w} : $minLd-0.1);
123 }
124 return(encode_json($d1));
125 } else {
Marc Kupietzaf436142026-07-30 14:40:10 +0900126 my $d1 = decode_json($collocators);
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200127 foreach my $i (@{$d1->{collocates}}) {
128 $i->{delta} = 0;
129 }
130 return(encode_json($d1));
131 }
132}
133
134sub getSimilarProfilesCached {
135 my ($c, $word) = @_;
Marc Kupietzaf436142026-07-30 14:40:10 +0900136 my $profiles = $opt_C ? undef : $spcache->get($word);
137 if(!defined $profiles) {
138 $profiles = getSimilarProfiles($word);
139 $spcache->set($word => $profiles) unless $opt_C;
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200140 } else {
141 $c->app->log->info("Getting similar profiles for $word from cache:");
142 }
Marc Kupietzaf436142026-07-30 14:40:10 +0900143 return $profiles;
Marc Kupietzbf9bac02022-04-11 21:16:47 +0200144}
145
146return 1;