<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#                              -*- Mode: Perl -*- 
# Cache.pm -- 
# Author          : Ulrich Pfeifer
# Created On      : Mon May 13 11:14:06 1996
# Last Modified By: Ulrich Pfeifer
# Last Modified On: Sun Apr  3 11:43:04 2005
# Language        : CPerl
# Update Count    : 17
# Status          : Unknown, Use with caution!

package Text::German::Cache;

sub new {
  my $type = shift;
  my $self = {};
  my %para = @_;

  $self-&gt;{Function} = $para{Function} || \&amp;Text::German::reduce;
  $self-&gt;{Hold}     = $para{Hold}     || 100;
  $self-&gt;{Gc}       = $para{Gc}       || 2 * $self-&gt;{Hold};
  $self-&gt;{Verbose}  = $para{Verbose}  || 0;
  $self-&gt;{Entries}  = 0;
  $self-&gt;{Contents} = {};
  $self-&gt;{Hit}      = {};
  $self-&gt;{Hits}     = 0;
  $self-&gt;{Misses}   = 0;
  bless $self, ref($type) || $type;
}

sub get {
  my $self = shift;
  my $key  = shift;

  if (defined $self-&gt;{Contents}-&gt;{$key}) {
    $self-&gt;{Hits}++;
    $self-&gt;{Hit}-&gt;{$key}++;
  } else {
    $self-&gt;{Misses}++;
    $self-&gt;{Entries}++;
    if ($self-&gt;{Entries} &gt;= $self-&gt;{Gc}) {
      $self-&gt;gc;
    }
    $self-&gt;{Contents}-&gt;{$key} = &amp;{$self-&gt;{Function}}($key);
  }
  $self-&gt;{Contents}-&gt;{$key};
}

sub gc {
  my $self = shift;
  my %rank;
  my $rank;
  
  if ($self-&gt;{Verbose}) {
    printf (STDERR "Cache: enter garbadge collect %d\n", $self-&gt;{Entries});
  }
  for (keys %{$self-&gt;{Contents}}) {
    push @{$rank{$self-&gt;{Hit}-&gt;{$_}}}, $_;
  }
  for $rank (sort {$a &lt;=&gt; $b} keys %rank) {
    for (@{$rank{$rank}}) {
      if ($self-&gt;{Verbose}) {
        printf (STDERR "Cache: deleting $_(%d)\n", $rank+1);
      }
       delete $self-&gt;{Contents}-&gt;{$_};
       delete $self-&gt;{Hit}-&gt;{$_};
       $self-&gt;{Entries}--;
     }
    # We delete a complete rank. this is more than we must do ..
    last if $self-&gt;{Entries} &lt;= $self-&gt;{Hold};
  }
  if ($self-&gt;{Verbose}) {
    printf (STDERR "Cache: leave garbadge collect %d\n", $self-&gt;{Entries});
  }
}

sub DESTROY {
  my $self = shift;

  if ($self-&gt;{Verbose}) {
    printf (STDERR "\nCache Hits: %d\tMisses: %d\n", $self-&gt;{Hits}, $self-&gt;{Misses});
  }
}

1;
</pre></body></html>