return $hr->{$id};
}
+# Like getFireHose, but does the lookup by globjid (which is unique).
+#
+# One way to implement this would be to store complete hose data with
+# each globjid, the advantage being half as many memcached requests
+# and thus half the latency. I wouldn't mind paying most of the price
+# for this: extra memcached RAM, and extra network bandwidth in some
+# cases. But that would also interleave hose item cache expiration
+# times, which could lead to confusing bugs. To avoid that, I'm
+# willing to pay the price of extra latency.
+#
+# So instead this does a lookup from globjid to id (which is cached),
+# and wraps that conversion about a getFireHoseMulti call.
+#
+# The option id_only skips the step of retrieving the actual firehose
+# data and returns a hashref (or values of hashrefs) with only the
+# id field populated.
+
+sub getFireHoseByGlobjid {
+ my($self, $globjid, $options) = @_;
+ my $hr = $self->getFireHoseByGlobjidMulti([$globjid], $options);
+ return $hr->{$globjid};
+}
+
+sub getFireHoseByGlobjidMulti {
+ my($self, $globjid_ar, $options) = @_;
+ my $ret_hr = { };
+
+ # First, convert the globjids to ids.
+
+ #my $exptime = 86400;
+ #my $globjid_to_id_hr = { };
+
+ #my $mcd_hr = { };
+ #my $mcd = $self->getMCD();
+ #my $mcdkey;
+ #if ($mcd && !$options->{memcached_no_read}) {
+ # $mcdkey = "$self->{_mcd_keyprefix}:gl2id" if $mcd;
+ # my @keylist = ( map { "$mcdkey:$_" } @$globjid_ar );
+ # my $mcdkey_hr = $mcd->get_multi(@keylist);
+ # for my $k (keys %$mcdkey_hr) {
+ # my($id) = $k =~ /^\Q$mcdkey:\E(\d+)$/;
+ # next unless $id;
+ # $mcd_hr->{$id} = $mcdkey_hr->{$k};
+ # }
+ #}
+
+ my $answer_hr = { };
+ my @remaining_ids = ( grep { !defined($mcd_hr->{$_}) } @$globjid_ar );
+ my $splice_count = 2000;
+ while (@remaining_ids) {
+ my @globjid_chunk = splice @remaining_ids, 0, $splice_count;
+ my $globjid_str = join(',', @globjid_chunk);
+ my $more_hr = $self->sqlSelectAllKeyValue(
+ 'globjid, id',
+ 'firehose',
+ "globjid IN ($globjid_str)");
+ # XXX faster, or slower, than iterating over $more_hr?
+ $answer_hr = {( %$answer_hr, %$more_hr )};
+ }
+
+ #if ($mcd && %$answer_hr && !$options->{memcached_no_write}) {
+ # for my $globjid (keys %$answer_hr) {
+ # $mcd->set("$mcdkey:$globjid", $answer_hr->{$globjid}, $exptime);
+ # }
+ #}
+
+ $globjid_to_id_hr = {( %$mcd_hr, %$answer_hr )};
+
+ # If only the ids are desired, we can return those now.
+ if ($options->{id_only}) {
+ return $globjid_to_id_hr;
+ }
+
+ # Now that the globjids have been converted to ids, call
+ # getFireHoseMulti.
+
+ my @ids = grep { $_ } map { $globjid_to_id_hr->{$_} } @$globjid_ar;
+ my $firehose_hr = $self->getFireHoseMulti(\@ids, $options);
+ use Data::Dumper; print STDERR scalar(gmtime) . " $$ gFHM returned non-hashref from '@ids' options: " . Dumper($options) if ref($firehose_hr) ne 'HASH';
+
+ # Then convert the keys in the answer back to globjids.
+ for my $id (keys %$firehose_hr) {
+ if (ref($firehose_hr->{$id}) ne 'HASH') {
+ my $opt_str = Dumper($options); $opt_str =~ s/\s+/ /g;
+ my $fh_str = Dumper($firehose_hr); $fh_str =~ s/\s+/ /g;
+ print STDERR scalar(gmtime) . " $$ gFHM returned non-hashref-hashref for '$id' from '@ids' options '$opt_str' fh '$fh_str'\n";
+ next;
+ }
+ $ret_hr->{ $firehose_hr->{$id}{globjid} } = $firehose_hr->{$id};
+ }
+ return $ret_hr;
+}
+
+sub getFireHoseIdFromGlobjid {
+ my($self, $globjid) = @_;
+ return $self->getFireHoseByGlobjid($globjid, { id_only => 1 });
+}
+
+sub getFireHoseIdFromUrl {
+ my($self, $url) = @_;
+ if ($url) {
+ my $fudgedurl = fudgeurl($url);
+ if ($fudgedurl) {
+ my $url_id = $self->getUrlIfExists($fudgedurl);
+ if ($url_id) {
+ return $self->getPrimaryFireHoseItemByUrl($url_id);
+ }
+ }
+ }
+ return 0;
+}
+
sub setTopicsRenderedBySkidForItem {
my($self, $id, $primaryskid) = @_;
#my $constants = getCurrentStatic();
$db->setFireHose($id, { nexuslist => " $nexus " });
}
+sub setTopicsRenderedForStory {
+ my($self, $stoid, $tids) = @_;
+ my $the_tids = [ @$tids ]; # Copy tids so any changes we make don't affect the caller
+ #my $constants = getCurrentStatic();
+ my $globjs = $self->new_instance_of('Globjs');
+ my $slash_db = $self->new_instance_of('SlashDB');
+
+ my $story = $slash_db->getStory($stoid, "", 1);
+ if ($story) {
+ my $globjid = $globjs->getGlobjidCreate("stories", $story->{stoid});
+ my $id = $self->getFireHoseIdFromGlobjid($globjid);
+ my @nexus_topics;
+ if ($id) {
+ $slash_db->sqlDelete("firehose_topics_rendered", "id = $id");
+ foreach (@$the_tids) {
+ $slash_db->sqlInsert("firehose_topics_rendered", { id => $id, tid => $_});
+ }
+ my $tree = $slash_db->getTopicTree();
+ @nexus_topics = grep { $tree->{$_}->{nexus} } @$the_tids;
+ my $nexus_list = join ' ', @nexus_topics;
+ $nexus_list = " $nexus_list ";
+ $self->setFireHose($id, { nexuslist => $nexus_list });
+ }
+ }
+}
+
1;