All,
I built this a while ago because I wanted to better understand how an associative database works. Also, a product we're using where I work isn't available for anything but Windows, so I figured something cross-platform would be nice.
Anyway, this is a start. It's basically an in-memory database with the ability to store a snapshot of the data to disk. It seems to run very fast for small data sets, but I can see it slowing down severely for larger sets.
I'm posting it here today because I simply don't have the time to continue to develop it. Also, I didn't want this to just disappear, so I figured there may be an adventurous monk or two that can use this. I know it's not perfect, but I think it's a good start.
package AssocDB; use Data::Dumper; use Storable qw{freeze thaw store retrieve}; # Constructor sub new { my $self = {}; $self->{'entityhash'} = {}; $self->{'entityarray'} = (); $self->{'relationshiphash'} = {}; $self->{'predicatearray'} = (); $self->{'entitypool'} = (); bless($self, 'AssocDB'); } # Function to insert an entity into the database. # {{{ sub insertEntity { my $this = shift; my $entity = shift; if (@{$this->{'entitypool'}}) { my $newIndex = pop(@{$this->{'entitypool'}}); @{$this->{'entityarray'}}[$newIndex] = $entity; if (!exists($this->{'entityhash'}->{$entity})) { $this->{'entityhash'}->{$entity} = (); } push(@{$this->{'entityhash'}->{$entity}}, $newIndex + 1); } else { push(@{$this->{'entityarray'}}, $entity); my $length = @{$this->{'entityarray'}}; if (!exists($this->{'entityhash'}->{$entity})) { $this->{'entityhash'}->{$entity} = (); } push(@{$this->{'entityhash'}->{$entity}}, $length); } } # }}} # Function to insert a predicate into the database. # {{{ sub insertPredicate { my $this = shift; my $entity = shift; if (@{$this->{'entitypool'}}) { my $newIndex = pop(@{$this->{'entitypool'}}); @{$this->{'entityarray'}}[$newIndex] = $entity; if (!exists($this->{'entityhash'}->{$entity})) { $this->{'entityhash'}->{$entity} = (); } push(@{$this->{'entityhash'}->{$entity}}, $newIndex + 1); push(@{$this->{'predicatearray'}}, $newIndex + 1); } else { push(@{$this->{'entityarray'}}, $entity); my $length = @{$this->{'entityarray'}}; if (!exists($this->{'entityhash'}->{$entity})) { $this->{'entityhash'}->{$entity} = (); } push(@{$this->{'entityhash'}->{$entity}}, $length); push(@{$this->{'predicatearray'}}, $length); } } # }}} # Function to insert a relationship into the database. # {{{ sub insertRelationship { my $this = shift; my $subject = shift; my $predicate = shift; my $object = shift; my $key = qq{$subject:$predicate:$object}; $this->{'relationshiphash'}->{$key} = 1; } # }}} # Function to delete an entity from the database. # {{{ sub deleteEntityById { my $this = shift; my $entityId = shift; my @resultArray = grep { m{\d+:\d+:$entityId}xms } keys %{$this->{'relationshiphash'}}; return 0 if @resultArray; @resultArray = grep { m{$entityId}xms } @{$this->{'predicatearray' +}}; return 0 if @resultArray; my $entity = $this->{'entityarray'}->[$entityId - 1]; $this->{'entityarray'}->[$entityId - 1] = ''; push(@{$this->{'entitypool'}}, $entityId - 1); my @tempArray = @{$this->{'entityhash'}->{$entity}}; for (my $index; $index < @tempArray; $index++) { if ($tempArray[$index] == $entityId) { splice(@{$this->{'entityhash'}->{$entity}}, $index, 1); } } foreach my $index (keys %{$this->{'relationshiphash'}}) { delete($this->{'relationshiphash'}->{$index}) if $index =~ m{$entityId:\d+:\d+}xms; } delete($this->{'entityhash'}->{$entity}) if scalar @{$this->{'entityhash'}->{$entity}} == 0; return 1; } # }}} # Function to delete an predicate from the database. # {{{ sub deletePredicateById { my $this = shift; my $entityId = shift; my @resultArray = grep { m{\d+:$entityId:\d+}xms } keys %{$this->{'relationshiphash'}}; return 0 if @resultArray; my $entity = $this->{'entityarray'}->[$entityId - 1]; $this->{'entityarray'}->[$entityId - 1] = ''; push(@{$this->{'entitypool'}}, $entityId - 1); my @tempArray = @{$this->{'entityhash'}->{$entity}}; for (my $index; $index < @tempArray; $index++) { if ($tempArray[$index] == $entityId) { splice(@{$this->{'entityhash'}->{$entity}}, $index, 1); } } @tempArray = @{$this->{'predicatearray'}}; for (my $index; $index < @tempArray; $index++) { if ($tempArray[$index] == $entityId) { splice(@{$this->{'predicatearray'}}, $index, 1); } } delete($this->{'entityhash'}->{$entity}) if scalar @{$this->{'entityhash'}->{$entity}} == 0; return 1; } # }}} # Function to delete an relationship from the database. # {{{ sub deleteRelationship { my $this = shift; my $subject = shift; my $predicate = shift; my $object = shift; my $key = qq{$subject:$predicate:$object}; delete($this->{'relationshiphash'}->{$key}); } # }}} # Function to get an entity from the database using the name. # {{{ sub getEntityByName { my $this = shift; my $entity = shift; return @{$this->{'entityhash'}->{$entity}}; } # }}} # Function to get an entity from the database using the ID. # {{{ sub getEntityById { my $this = shift; my $entity = shift; return $this->{'entityarray'}->[$entity]; } # }}} # Function to get the predicates from the database. # {{{ sub getPredicates { my $this = shift; my @tempArray = @{$this->{'predicatearray'}}; my @resultArray = map { $_ . ':' . $this->{'entityarray'}->[$_ - 1 +] } @tempArray; return @resultArray; } # }}} # Function to get all relationships an entity is the Subject of. # {{{ sub getSubjectRel { my $this = shift; my $entityId = shift; my @resultArray = grep { m{$entityId:\d+:\d+}xms } keys %{$this->{'relationshiphash'}}; return @resultArray; } # }}} # Function to get all relationships an entity is the Object of. # {{{ sub getObjectRel { my $this = shift; my $entityId = shift; my @resultArray = grep { m{\d+:\d+:$entityId}xms } keys %{$this->{'relationshiphash'}}; return @resultArray; } # }}} # Function to write the data to disk using Storable. # {{{ sub storeData { my $this = shift; my $filename = shift;; my %dataHash; $dataHash{'entityhash'} = freeze($this->{'entityhash'}); $dataHash{'entityarray'} = freeze($this->{'entityarray'}); $dataHash{'relationshiphash'} = freeze($this->{'relationshiphash'}); $dataHash{'predicatearray'} = freeze($this->{'predicatearray'}); $dataHash{'entitypool'} = freeze($this->{'entitypool'}); store($this, $filename); } # }}} # Function to load the data from a file. # {{{ sub loadData { my $this = shift; my $filename = shift;; my $temp = retrieve($filename); $this->{'entityhash'} = $temp->{'entityhash'}; $this->{'relationshiphash'} = $temp->{'relationshiphash'}; $this->{'entityarray'} = $temp->{'entityarray'}; $this->{'predicatearray'} = $temp->{'predicatearray'}; $this->{'entitypool'} = $temp->{'entitypool'}; } # }}} 1;
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Associative Database
by Anno (Deacon) on Mar 10, 2007 at 17:25 UTC | |
Re: Associative Database
by chanio (Priest) on Mar 11, 2007 at 06:25 UTC | |
Re: Associative Database
by jwkrahn (Abbot) on Mar 14, 2007 at 21:49 UTC | |
Re: Associative Database
by DrHyde (Prior) on Mar 12, 2007 at 10:22 UTC | |
by jettero (Monsignor) on Mar 16, 2007 at 22:13 UTC | |
Re: Associative Database
by halley (Prior) on Mar 14, 2007 at 16:44 UTC | |
by liverpole (Monsignor) on Mar 14, 2007 at 20:12 UTC | |
by DrHyde (Prior) on Mar 20, 2007 at 10:18 UTC |
Back to
Cool Uses for Perl