sent in the
following documentation...
Indices are required to locate items of
importance in an information retrieval
system. Managing and index requires
several software features in a computer
system. Obviously it is necessary to
read and write the index files.
The following example returns the index named in the
%index_table hash. The method assumes that $index_path
and %index_table are globally declared variable locations.
###################################
# Sub get_index #
###################################
sub get_index
{
my @db_row;
my @db_definition;
my $index_line='';
my $line='';
open(INDEXVIRTUAL, "$index_path") ||
&file_open_error("$index_path","Read Index",
__VIRTUAL__,__LINE__);
$line = ;
@db_definition = split(/\|/,$line);
while (!eof(INDEXVIRTUAL))
{
$line = ;
@db_row = split(/\|/,$line);
$index_table{$db_row[1]} = $db_row[2];
}
} #end of get_index subroutine
As programmers become more structured, they
tend to want to pass the variables in a
consistent manner supported by the language.
Thus the method could look like this:
#####################################
# Sub get_index #
#####################################
sub get_index
{
local $index_path , %index_table = @_;
my @db_row;
my @db_definition;
my $index_line='';
my $line='';
open(INDEXVIRTUAL, "$index_path") ||
&file_open_error("$index_path","Read Index",
__VIRTUAL__,__LINE__);
$line = ;
@db_definition = split(/\|/,$line);
while (!eof(INDEXVIRTUAL))
{
$line = ;
@db_row = split(/\|/,$line);
$index_table{$db_row[1]} = $db_row[2];
}
return (%index_table);
} #end of get_index subroutine
It is more apparent the values passed to it,
and those returned.
If you study the method you will find that it
supports the existence of an incidental header
in the file, which can be used by an external
program like EZDB to access data in the file.
The header conveniently describes to commonly
used database management utilities the fieldnames
in each row of the data file.
pkey|company|value|blank # Row 0
1000|Acme Electric|32| # Row 1
1001|Sprites|11| # Row 2
1002|Northern Air|16| # Row 3
Thus the following method efficiently uses the get_index
subroutine twice to initialize to indices.
##################################
# Sub initialize_indices #
##################################
sub initialize_indices
{
$index_path = $categories_index_path;
%index_table=();
&get_index;
%categories_index = %index_table;
$index_path = $companies_index_path;
%index_table=();
&get_index;
%companies_index = %index_table;
}
These methods were entirely comprised of read operations.
To update the indices with new information, the following
fundamental method retains the incidental header segment,
and over-writes the remainder of the file with updated
information.
#############################
# Sub update_index #
#############################
sub update_index
{
local ($index_path,%index_table) = @_;
local (@db_row);
my $display_line='';
my $newline='';
my $line='';
open (INDEXVIRTUAL, "$index_path") ||
&file_open_error("$index_path","Reading Index",
__VIRTUAL__,__LINE__);
$line = ;
$newline = $line; # Variable holds header information.
while () # Contents of the hash array
# are read and replaced with new
# information before being into the
# $newline variable.
{
@db_row = ();
$line = $_;
@db_row = split(/\|/,$line);
$db_row[2] = $index_table{$db_row[1]};
$display_line = join "|",@db_row;
$newline .= $display_line;
#print "$display_line
";
} # $newline holds entire contents of index file.
close INDEXVIRTUAL;
open (INDEXVIRTUAL, ">$index_path") ||
&file_open_error("$index_path","Writing Index",
__VIRTUAL__,__LINE__);
flock INDEXVIRTUAL, $EXCLUSIVE;
print INDEXVIRTUAL $newline;
flock INDEXVIRTUAL, $UNLOCK;
close INDEXVIRTUAL;
} #end of update_index subroutine
With this fundamental kernal method in hand, its
easy to write methods that update indeces with
new information.
##############################
# Sub update_categories_index_values #
##############################
sub update_categories_index_values{
$index_path = $categories_index_path;
%index_table=();
%index_table=%categories_index;
&update_index_counters;
}
##############################
# Sub update_companies_index_values #
##############################
sub update_companies_index_values{
$index_path = $companies_index_path;
%index_table=();
%index_table=%companies_index;
&update_index_counters;
}
Another example of fetching and updating an order
number index uses the two fundamental kernal methods:
################################
# Sub get_order_number #
################################
sub get_order_number
{
local ($index_path) = $sc_order_counter_path;
local (%index_table) = ();
%index_table = &get_index ($index_path);
return %index_table;
}
################################
# Sub update_order_number #
################################
sub update_order_number {
local (%index_table) = @_;
local ($index_path) = $sc_order_counter_path;
&update_index ($index_path,%index_table);
}
The index file has the following structure:
pkey|counter|value|blank # Row 0
1000|orders_index|32| # Row 1
Obviously it is easy to develop new uses for indices,
reading and writing them with the same fundamental
methods shown. I have looked into the possibility
of using the DBM module to manage the indeces shown,
but have concluded that the only possible module that
will support my complex data requirements (to remain
compatible with remote flatfile management applications
like EZDB) is the MLDBM module.
Its possible that Webstore could be re-written, supported
by the MLDBM management module.
Also, if remote file management is not a requirement,
then other utilities could manage the indeces described
and simple DBM supported access would suffice. Development
of management utilities is much easier if remote access is
not a requirement at this time.