SPUG: wrapping MLDBM to allow prev/next

Showell30 at aol.com Showell30 at aol.com
Tue Mar 20 11:01:27 CST 2001


# Hello SPUG.  Surely I am reinventing some wheels here.
# Please comment.
#
#  Thanks,
#
#  Steve
#
# see documentation at __END__

package dbsteve;

use DB_File;
use strict;

sub new
{
    # pass in File
    my $class = shift;
    my $self = {};
    my $file =  $self->{File} = shift;

    $self->{Dirty} = 1; 

    my %table;
    tie (%table, 'MLDBM', $self->{File}, O_CREAT|O_RDWR, 0666, 
        $DB_BTREE) or die "Can't open DB.";
    $self->{Table} = \%table;

    _debug($self);

    return bless $self, $class;
}

sub store
{
    my ($self, $key, $value) = @_;
    $self->{Table}{$key} = $value;
    $self->{Dirty} = 1;
    $self->_setindex($key);
}

sub fetch
{
    my ($self, $key) = @_;
    return undef if not exists $self->{Table}{$key};
    $self->_setindex($key);
    return $self->{Table}{$key};
}

sub prev
{
    my ($self) = @_;
    $self->_clean();
    return (undef, undef) if $self->{CurrKey} <= 0;
    my $key = $self->{Keys}[--$self->{CurrKey}];
    return ($key, $self->{Table}{$key});
}

sub next
{
    my ($self) = @_;
    $self->_clean();
    return (undef, undef) if $self->{CurrKey} >= $#{$self->{Keys}};
    my $key = $self->{Keys}[++$self->{CurrKey}];
    return ($key, $self->{Table}{$key});
}

sub _clean
{
    my ($self) = @_;
    return if not $self->{Dirty};

    $self->{Dirty} = 0;
    $self->{Keys} = [keys %{$self->{Table}}];
    $self->{CurrKey} = 0;
}

sub _debug
{
    while (my($key, $data) = each(%{$_[0]->{Table}}))
    {
        print "$key\n", join(":", @$data), "\n";
    }
}

sub _setindex
{
    my ($self, $key) = @_;

    $self->_clean();

    for my $i (0..$#{$self->{Keys}})
    {
        if ($self->{Keys}[$i] eq $key)
        {
            $self->{CurrKey} = $i;
            last;
        }
    }
}

return 1;

__END__


=head1 DESCRIPTION

Here is what I needed in my database:

   1. Ability to store about 3000 records.
   2. Low performance inserts.
   3. High performance searching.
   4. High performance sequential access through the database (with 
      keys ordered).

This package wraps an MLDBM database that 
has a BTREE DB_File for its guts.  It augments the 
MLDBM/DB_File interface by allowing you to do 
previous and next from the middle of the database.

It removes the hash tie interface, partly due to 
non-virtuous laziness, but also partly to improve the 
clarity of the calling code.

Example usage:
   
    my $db = $steve->new("File.txt");

    $db->store($key, $value);

    $value = $db->fetch($key);
    # undef means not found 

    ($key, $value) = $db->next();
    ($key, $value) = $db->prev();

(This has been tested under Win98 only.)

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
  Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/





More information about the spug-list mailing list