Commit 87595f05 authored by Graham McVicker's avatar Graham McVicker
Browse files

Made global seq_region cache non-global. Global cache for all dbs + mod_perl...

Made global seq_region cache non-global.  Global cache for all dbs + mod_perl = very mysterious web bug.
parent c461e0c8
......@@ -3,7 +3,7 @@
# Ensembl module for Bio::EnsEMBL::DBSQL::AssemblyMapperAdaptor
#
#
# Copyright EnsEMBL
# Copyright Ensembl
#
# You may distribute this module under the same terms as perl itself
......@@ -45,12 +45,13 @@ This is used to retrieve mappers between any two coordinate systems whose
makeup is described by the assembly table. Currently one step (explicit) and
two step (implicit) pairwise mapping is supported. In one-step mapping
an explicit relationship between the coordinate systems is defined in the
assembly table. In two-step 'chained' mapping no explicit mapping is present
but the coordinate systems must share a common mapping to an intermediate
assembly table. In two-step 'chained' mapping no explicit mapping is present
but the coordinate systems must share a common mapping to an intermediate
coordinate system.
=head1 CONTACT
This module is part of the Ensembl project: www.ensembl.org
Post general queries to B<ensembl-dev@ebi.ac.uk>
=head1 METHODS
......@@ -100,6 +101,12 @@ sub new {
$self->{'_asm_mapper_cache'} = {};
# use a shared cache (for this database) that contains info about
# seq regions
my $seq_region_cache = $self->db->get_SeqRegionCache();
$self->{'sr_name_cache'} = $seq_region_cache->{'name_cache'};
$self->{'sr_id_cache'} = $seq_region_cache->{'id_cache'};
return $self;
}
......@@ -175,18 +182,18 @@ sub fetch_by_CoordSystems {
if(@mapping_path == 2) {
#1 step regular mapping
$asm_mapper = Bio::EnsEMBL::AssemblyMapper->new($self, @mapping_path);
#$asm_mapper = Bio::EnsEMBL::AssemblyMapper->new($self, @mapping_path);
# If you want multiple pieces on two seqRegions to map to each other
# uncomment following. AssemblyMapper assumes only one mapped piece per contig
# $asm_mapper = Bio::EnsEMBL::ChainedAssemblyMapper->new( $self, $mapping_path[0], undef, $mapping_path[1] );
$asm_mapper = Bio::EnsEMBL::ChainedAssemblyMapper->new( $self, $mapping_path[0], undef, $mapping_path[1] );
$self->{'_asm_mapper_cache'}->{$key} = $asm_mapper;
return $asm_mapper;
}
if(@mapping_path == 3) {
#two step chained mapping
$asm_mapper = Bio::EnsEMBL::ChainedAssemblyMapper->new($self,@mapping_path);
$asm_mapper = Bio::EnsEMBL::ChainedAssemblyMapper->new($self,@mapping_path);
#in multi-step mapping it is possible get requests with the
#coordinate system ordering reversed since both mappings directions
#cache on both orderings just in case
......@@ -252,7 +259,6 @@ sub register_assembled {
my @chunk_regions;
#determine span of chunks
#bitwise shift right is fast and easy integer division
my($start_chunk, $end_chunk);
......@@ -351,12 +357,12 @@ sub register_assembled {
$asm_seq_region, $asm_start, $asm_end,
$ori,
$cmp_seq_region, $cmp_start, $cmp_end);
my $arr = [ $cmp_seq_region_id, $cmp_seq_region, $cmp_cs_id, $cmp_seq_region_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$cmp_seq_region:$cmp_cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$cmp_seq_region_id"} =
$arr;
my $arr = [ $cmp_seq_region_id, $cmp_seq_region,
$cmp_cs_id, $cmp_seq_region_length ];
$self->{'sr_name_cache'}->{"$cmp_seq_region:$cmp_cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$cmp_seq_region_id"} = $arr;
}
}
......@@ -373,7 +379,7 @@ sub _seq_region_name_to_id {
($sr_name && $cs_id) || throw('seq_region_name and coord_system_id args ' .
'are required');
my $arr = $Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$sr_name:$cs_id"};
my $arr = $self->{'sr_name_cache'}->{"$sr_name:$cs_id"};
if( $arr ) {
return $arr->[0];
}
......@@ -397,11 +403,9 @@ sub _seq_region_name_to_id {
$sth->finish();
$arr = [ $sr_id, $sr_name, $cs_id, $sr_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$sr_name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$sr_id"} =
$arr;
$self->{'sr_name_cache'}->{"$sr_name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$sr_id"} = $arr;
return $sr_id;
}
......@@ -477,12 +481,11 @@ sub register_component {
my ($asm_start, $asm_end, $asm_seq_region_id, $asm_seq_region, $asm_seq_region_length) =
$sth->fetchrow_array();
my $arr = [ $asm_seq_region_id, $asm_seq_region, $asm_cs_id, $asm_seq_region_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$asm_seq_region:$asm_cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$asm_seq_region_id"} =
$arr;
my $arr = [ $asm_seq_region_id, $asm_seq_region,
$asm_cs_id, $asm_seq_region_length ];
$self->{'sr_name_cache'}->{"$asm_seq_region:$asm_cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$asm_seq_region_id"} = $arr;
$sth->finish();
......@@ -701,12 +704,11 @@ sub register_chained {
}
#update sr_name cache
my $arr = [ $mid_seq_region_id, $mid_seq_region, $mid_cs_id, $mid_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$mid_seq_region:$mid_cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$mid_seq_region_id"} =
$arr;
my $arr = [ $mid_seq_region_id, $mid_seq_region,
$mid_cs_id, $mid_length ];
$self->{'sr_name_cache'}->{"$mid_seq_region:$mid_cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$mid_seq_region_id"} = $arr;
push @mid_ranges,[$mid_seq_region_id,$mid_seq_region,
$mid_start,$mid_end];
......@@ -785,12 +787,10 @@ sub register_chained {
);
#update sr_name cache
my $arr = [ $end_seq_region_id, $end_seq_region, $end_cs_id, $end_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$end_seq_region:$end_cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$end_seq_region_id"} =
$arr;
my $arr = [ $end_seq_region_id,$end_seq_region,$end_cs_id,$end_length ];
$self->{'sr_name_cache'}->{"$end_seq_region:$end_cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$end_seq_region_id"} = $arr;
#register this region on the end coord system
$end_registry->check_and_register($end_seq_region, $end_start, $end_end);
......@@ -906,7 +906,7 @@ sub seq_regions_to_ids {
my @out;
foreach my $sr (@$seq_regions) {
my $arr = $Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$sr:$cs_id"};
my $arr = $self->{'sr_name_cache'}->{"$sr:$cs_id"};
if( $arr ) {
push( @out, $arr->[0] );
} else {
......
......@@ -45,6 +45,7 @@ use strict;
use Bio::EnsEMBL::DBSQL::DBConnection;
use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor;
use Bio::EnsEMBL::Utils::SeqRegionCache;
use Bio::EnsEMBL::Utils::Exception qw(throw warning deprecate);
use Bio::EnsEMBL::Utils::Argument qw(rearrange);
......@@ -1117,7 +1118,7 @@ sub add_ExternalFeatureFactory{
=cut
sub get_adaptor() {
sub get_adaptor {
my ($self, $canonical_name, @other_args) = @_;
if ($self->isa('Bio::EnsEMBL::Container')) {
......@@ -1157,7 +1158,7 @@ sub get_adaptor() {
=cut
sub set_adaptor() {
sub set_adaptor {
my ($self, $canonical_name, $new_object) = @_;
if ($self->isa('Bio::EnsEMBL::Container')) {
......@@ -1197,7 +1198,7 @@ sub set_adaptor() {
=cut
sub get_GenericFeatureAdaptors() {
sub get_GenericFeatureAdaptors {
my ($self, @names) = @_;
......@@ -1232,7 +1233,7 @@ sub get_GenericFeatureAdaptors() {
=cut
sub add_GenericFeatureAdaptor() {
sub add_GenericFeatureAdaptor {
my ($self, $name, $adaptor_obj) = @_;
# check that $adaptor is an object that subclasses BaseFeatureAdaptor
......@@ -1247,6 +1248,33 @@ sub add_GenericFeatureAdaptor() {
=head2 get_SeqRegionCache
Arg [1] : none
Example : my $srcache = $dba->get_SeqRegionCache();
Description: Retrieves a seq_region cache for this database
Returntype : Bio::EnsEMBL::Utils::SeqRegionCache
Exceptions : none
Caller : SliceAdaptor, AssemblyMapperAdaptor
=cut
sub get_SeqRegionCache {
my $self = shift;
# use the cache from the database where seq_regions are stored
if($self != $self->dnadb()) {
return $self->dnadb()->get_SeqRegionCache();
}
if(!$self->{'seq_region_cache'}) {
$self->{'seq_region_cache'} = Bio::EnsEMBL::Utils::SeqRegionCache->new();
}
return $self->{'seq_region_cache'};
}
#########################
# sub DEPRECATED METHODS
#########################
......
......@@ -94,8 +94,6 @@ use Bio::EnsEMBL::Slice;
use Bio::EnsEMBL::Mapper;
use Bio::EnsEMBL::Utils::Exception qw(throw deprecate warning);
use Bio::EnsEMBL::Utils::Cache; #CPAN LRU cache
use Bio::EnsEMBL::Utils::SeqRegionCache;
@ISA = ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
......@@ -107,6 +105,12 @@ sub new {
my $self = $class->SUPER::new(@_);
# use a cache which is shared and also used by the assembly
# mapper adaptor
my $seq_region_cache = $self->db->get_SeqRegionCache();
$self->{'sr_name_cache'} = $seq_region_cache->{'name_cache'};
$self->{'sr_id_cache'} = $seq_region_cache->{'id_cache'};
return $self;
}
......@@ -223,7 +227,7 @@ sub fetch_by_region {
my $length;
my $arr;
if( $key ) {
$arr = $Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{$key};
$arr = $self->{'sr_name_cache'}->{$key};
}
if( $arr ) {
......@@ -261,10 +265,8 @@ sub fetch_by_region {
# cache values for future reference
my $arr = [ $id, $tmp_name, $cs_id, $tmp_length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$tmp_name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$id"} =
$arr;
$self->{'sr_name_cache'}->{"$tmp_name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$id"} = $arr;
my $tmp_ver = substr($tmp_name, $prefix_len);
......@@ -292,13 +294,11 @@ sub fetch_by_region {
my ($id, $cs_id);
($seq_region_name, $id, $length, $cs_id) = $sth->fetchrow_array();
$sth->finish();
# cahce to speed up for future queries
my $arr = [ $id, $seq_region_name, $cs_id, $length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$seq_region_name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$id"} =
$arr;
$self->{'sr_name_cache'}->{"$seq_region_name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$id"} = $arr;
$cs = $csa->fetch_by_dbID( $cs_id );
}
......@@ -385,7 +385,7 @@ sub fetch_by_name {
sub fetch_by_seq_region_id {
my ($self, $seq_region_id) = @_;
my $arr = $Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{ $seq_region_id };
my $arr = $self->{'sr_id_cache'}->{ $seq_region_id };
my ($name, $length, $cs);
if( $arr ) {
......@@ -409,11 +409,9 @@ sub fetch_by_seq_region_id {
#cache results to speed up repeated queries
my $arr = [ $seq_region_id, $name, $cs_id, $length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$seq_region_id"} =
$arr;
$self->{'sr_name_cache'}->{"$name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$seq_region_id"} = $arr;
}
return Bio::EnsEMBL::Slice->new(-COORD_SYSTEM => $cs,
......@@ -453,7 +451,7 @@ sub get_seq_region_id {
my $seq_region_name = $slice->seq_region_name();
my $key = $seq_region_name.":".$slice->coord_system->dbID();
my $arr = $Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$key"};
my $arr = $self->{'sr_name_cache'}->{"$key"};
if( $arr ) {
return $arr->[0];
......@@ -480,12 +478,10 @@ sub get_seq_region_id {
#cache information for future requests
$arr = [ $seq_region_id, $seq_region_name, $cs_id, $length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$seq_region_name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$seq_region_id"} =
$arr;
$self->{'sr_name_cache'}->{"$seq_region_name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$seq_region_id"} = $arr;
return $seq_region_id;
}
......@@ -610,11 +606,9 @@ sub fetch_all {
#we know we have filled it up
if($cache_count < $Bio::EnsEMBL::Utils::SeqRegionCache::SEQ_REGION_CACHE_SIZE) {
my $arr = [ $seq_region_id, $name, $cs_id, $length ];
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_name_cache{"$name:$cs_id"} =
$arr;
$Bio::EnsEMBL::Utils::SeqRegionCache::sr_id_cache{"$seq_region_id"} =
$arr;
$self->{'sr_name_cache'}->{"$name:$cs_id"} = $arr;
$self->{'sr_id_cache'}->{"$seq_region_id"} = $arr;
$cache_count++;
}
......
#
# Ensembl module for Bio::EnsEMBL::Utils::SeqRegionCache
#
# Copyright (c) 2004 Ensembl
#
# You may distribute this module under the same terms as perl itself
=head1 NAME
Bio::EnsEMBL::Utils::SeqRegionCache - A shared LRU cache of information about
seq_regions
=head1 SYNOPSIS
use Bio::EnsEMBL::DBSQL::DBAdaptor;
$db = Bio::EnsEMBL::DBSQL::DBAdaptor->new(...);
$seq_region_cache = $db->get_SeqRegionCache();
$key = "$seq_region_name:$coord_system_id";
$array = $seq_region_cache->{$key};
if($array) {
$name = $array->[1];
$length = $array->[3];
} else {
# cache miss, get the info from the database
...
# cache the retrieved information
$seq_region_cache->{$key} = [$seq_region_id, $seq_region_name,
$coord_system_id, $seq_region_length];
}
=head1 DESCRIPTION
This module is simply a convenient place to put a cache of sequence
region information which is shared by several adaptors for a given database.
=head1 CONTACT
This module is part of the Ensembl project http://www.ensembl.org
For more information email <ensembl-dev@ebi.ac.uk>
=head1 METHODS
=cut
use strict;
use Bio::EnsEMBL::Utils::Cache;
package Bio::EnsEMBL::Utils::SeqRegionCache;
our $SEQ_REGION_CACHE_SIZE = 4000;
our %sr_id_cache;
our %sr_name_cache;
tie(%sr_name_cache, 'Bio::EnsEMBL::Utils::Cache', $SEQ_REGION_CACHE_SIZE);
tie(%sr_id_cache, 'Bio::EnsEMBL::Utils::Cache', $SEQ_REGION_CACHE_SIZE);
sub new {
my $class = shift;
my %id_cache;
my %name_cache;
#
# the items to cache should be listrefs to
# [ sr_id, sr_name, cs_id, sr_length ]
#
# The name cache key is "sr_name:cs_id"
# The id cache is keyed on "sr_id"
#
tie(%name_cache, 'Bio::EnsEMBL::Utils::Cache', $SEQ_REGION_CACHE_SIZE);
tie(%id_cache, 'Bio::EnsEMBL::Utils::Cache', $SEQ_REGION_CACHE_SIZE);
return bless {'name_cache' => \%name_cache,
'id_cache' => \%id_cache}, $class;
}
1;
#
# the items to cache should be listrefs to
# [ sr_id, sr_name, cs_id, sr_length ]
#
# The name cache key is "sr_name:cs_id"
# The id cache is keyed on "sr_id"
#
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment