Re: mod_perl and global %Live_Objects not being initialized

[prev] [thread] [next] [Date index for 2005/02/14]

From: Tim Bunce
Subject: Re: mod_perl and global %Live_Objects not being initialized
Date: 11:18 on 14 Feb 2005
I've not had time to persue this. Would anyone (Perrin?) like to
finish it up?

Tim.

On Fri, Nov 19, 2004 at 01:47:38PM +0000, Tim Bunce wrote:
> On Wed, Nov 17, 2004 at 04:52:06PM +0000, Tony Bowden wrote:
> > On Wed, Nov 17, 2004 at 03:42:11PM +0000, Tim Bunce wrote:
> 
> I've appended a draft patch. Let me know if you're happy with the
> general direction and I'll polish it up with docs and tests etc.
> 
> Key points are:
> 
> 1. The 'live object index' concept is better encapsulated now.
> 2. The %Live_Object hash is now two-level ($class as first level).
> 3. A class can ask for access to its live object index (for dumping/debugging)
> 4. The _live_object_fetch() method called by _init() can now
>    be overridden to implement a wider variety of policies,
>    including full caching, LRU, age-based etc etc.
> 
> Tim.
> 
> diff -u -r Class-DBI-0.96_50/lib/Class/DBI.pm Class-DBI-0.96_50-liveobj/lib/Class/DBI.pm
> --- Class-DBI-0.96_50/lib/Class/DBI.pm	Wed Nov 17 11:41:13 2004
> +++ Class-DBI-0.96_50-liveobj/lib/Class/DBI.pm	Fri Nov 19 13:26:51 2004
> @@ -23,14 +23,11 @@
>  use vars qw($Weaken_Is_Available);
>  
>  BEGIN {
> -	$Weaken_Is_Available = 1;
> -	eval {
> +	$Weaken_Is_Available = eval {
>  		require Scalar::Util;
>  		import Scalar::Util qw(weaken);
> +		1;
>  	};
> -	if ($@) {
> -		$Weaken_Is_Available = 0;
> -	}
>  }
>  
>  use overload
> @@ -499,37 +496,45 @@
>  }
>  
>  #----------------------------------------------------------------------
> -# Live Object Index (using weak refs if available)
> +# Object creation
>  #----------------------------------------------------------------------
>  
> -my %Live_Objects;
> -my $Init_Count = 0;
> -
>  sub _init {
> -	my $class = shift;
> -	my $data  = shift || {};
> -	my $key   = $class->_live_object_key($data);
> -	return $Live_Objects{$key} || $class->_fresh_init($key => $data);
> +	my ($class, $data) = @_;
> +	# give index/caching mechanism being used by this class the
> +	# responsibility to get the object so it can, for example,
> +	# use a) no index, b) standard weakref based index (the default),
> +	# c) non-weakref based "cache" (including LRU or age limited) etc.
> +	return $class->_live_object_fetch($data || {}, 1);
>  }
>  
>  sub _fresh_init {
> -	my ($class, $key, $data) = @_;
> +	my ($class, $data) = @_;
>  	my $obj = bless {}, $class;
>  	$obj->_attribute_store(%$data);
> -
> -	# don't store it unless all keys are present
> -	if ($key && $Weaken_Is_Available) {
> -		weaken($Live_Objects{$key} = $obj);
> -
> -		# time to clean up your room?
> -		$class->purge_dead_from_object_index
> -			if ++$Init_Count % $class->purge_object_index_every == 0;
> -	}
>  	return $obj;
>  }
>  
> +#----------------------------------------------------------------------
> +# Live Object Index (using weak refs if available)
> +#----------------------------------------------------------------------
> +
> +my %Live_Objects;
> +my $_live_object_store_count = 0;
> +
> +sub _live_object_index {
> +	my ($self) = @_;
> +	my $class  = ref($self) || $self;
> +	return \%Live_Objects if $class eq "Class::DBI";
> +	return $Live_Objects{$class};
> +}
> +
>  sub _live_object_key {
>  	my ($me, $data) = @_;
> +	# Return key to use for this object in the live object index.
> +	# Key string must uniquely and permenantly identify the object.
> +	# Return empty string if object doesn't have full indentity yet.
> +	# Subclass can use "sub _live_object_key { '' }" to disable.
>  	my $class   = ref($me) || $me;
>  	my @primary = $class->primary_columns;
>  
> @@ -540,18 +545,44 @@
>  	return join "\030", $class, map $_ . "\032" . $data->{$_}, sort @primary;
>  }
>  
> +sub _live_object_store {
> +	my ($self, $key) = @_;
> +	return unless $key && $Weaken_Is_Available;
> +	my $class = ref $self;
> +	weaken($Live_Objects{$class}{$key} = $self);
> +	# time to clean up your room?
> +	$class->purge_dead_from_object_index
> +		if ++$_live_object_store_count % $class->purge_object_index_every == 0;
> +}
> +
> +sub _live_object_fetch {
> +	my ($class, $data, $vivify) = @_;
> +	my $key = $class->_live_object_key($data);
> +	my $obj = $Live_Objects{$class}{$key};
> +	return $obj if $obj or !$vivify;
> +	$obj = $class->_fresh_init($data);
> +	$obj->_live_object_store($key);
> +	return $obj;
> +}
> +
>  sub purge_dead_from_object_index {
> -	delete @Live_Objects{ grep !defined $Live_Objects{$_}, keys %Live_Objects };
> +	while ( my ($class, $lo) = each %Live_Objects ) {
> +		my @dead_keys = grep {!defined $lo->{$_} } keys %$lo;
> +		delete @{$lo}{ @dead_keys };
> +	}
>  }
>  
>  sub remove_from_object_index {
>  	my $self    = shift;
> -	my $obj_key = $self->_live_object_key($self->{_DATA});
> -	delete $Live_Objects{$obj_key};
> +	my $class   = ref $self or return;
> +	my $obj_key = $class->_live_object_key($self->{_DATA});
> +	delete $Live_Objects{$class}{$obj_key};
>  }
>  
>  sub clear_object_index {
> -	%Live_Objects = ();
> +	my $lo = shift->_live_object_index(@_)
> +		or return;
> +	%$lo = ();
>  }
>  
>  sub _prepopulate_id {

(message missing)

Re: mod_perl and global %Live_Objects not being initialized
Tim Bunce 11:18 on 14 Feb 2005

Re: mod_perl and global %Live_Objects not being initialized
=?ISO-8859-1?Q?Ask_Bj=F8rn_Hansen?= 03:02 on 19 Nov 2004

Generated at 17:31 on 15 Feb 2005 by mariachi v0.52