NAME
Tie::SymlinkTree - Prototype SQL-, Class::DBI- or Tie::*-using apps by storing data in a directory of symlinks
SYNOPSIS
use Tie::SymlinkTree;
tie %hash, 'Tie::SymlinkTree', '/some_directory';
$hash{'one'} = "some text"; # Creates symlink /some_directory/one
# with contents "some text"
$hash{'bar'} = "some beer";
$hash{'two'} = [ "foo", "bar", "baz" ];
$hash{'three'} = {
one => { value => 1, popularity => 'high'},
two => { value => 2, popularity => 'medium'},
four => { value => 4, popularity => 'low'},
eleven => { value => 11, popularity => 'medium'},
};
# Warning: experimental and subject to change without notice:
my @entries = tied(%hash)->search(sub { m/some/ }); # returns ("some text","some beer")
my $firstmatch = $hash{'two'}->search(sub { m/b/ }); # returns "bar"
my @result1 = $hash{'three'}->search('popularity','medium'); # returns ($hash{'three'}{'two'}, $hash{'three'}{'eleven'})
my @result2 = $hash{'three'}->search('popularity','=','medium'); # the same
my @result3 = $hash{'three'}->search('popularity',sub { $_[0] eq $_[1] },'medium'); # the same
print $hash{'two'}->id; # prints out "two"
DESCRIPTION
The Tie::SymlinkTree module is a TIEHASH/TIEARRAY interface which lets you tie a Perl hash or array to a directory on the filesystem. Each entry in the hash represents a symlink in the directory. Nested arrays and hashes are represented as sugbdirectories.
For applications with small storage requirements, this module is perfectly capable of production usage. For example, web applications with less than a few hundred users should work great with this module.
To use it, tie a hash to a directory:
tie %hash, "Tie::SymlinkTree", "/some_directory";
Any changes you make to the hash will create, modify, or delete symlinks in the given directory. 'undef' values are represented by an empty file instead of a symlink.
If the directory itself doesn't exist Tie::SymlinkTree
will create it (or die trying).
This module is fully reentrant, multi-processing safe, and still real fast (as the OS permits; a modern filesystem is recommended when storing lots of keys/array elements).
CAVEATS
Tie::SymlinkTree
hashes behave 99% like classic perl hashes. Key ordering differs, and may also depend on the order of insertion. Moreover, two distinct hashes with equal contents may differ in key order.
Tie::SymlinkTree
is restricted in what it can store: Values are limited in length, depending on OS limits (modern Linux boxes can store 4095 bytes, older systems might only support 256). Scalars, hashrefs and arrayrefs will be transparently mapped to subdirs as neccessary, nested as deeply as you wish, but no objects are allowed.
This module will probably only work on UNIXish systems.
How fast are ties? I can't tell. That is the most important bottleneck left. Searches over more than a few hundred entries are slow if you don't use indexing. If you tend to do many different complex queries, you should switch to something SQL-based.
RATIONALE
This module was designed for quick prototyping of multi-processing applications as often found in CGI scripts. It uses the fastest way to store and retrive small bits of information: Symlinks. "Small bits" is the key: most web-centric tasks involve a need for permanent storage, yet the usage pattern and data set size usually doesn't require a full SQL database.
Setting up a database schema and designing queries can be quite tedious when you're doing a prototype. A tie is much easier to use, but the usual Tie::* modules are lacking mp-safety or performance (or both), since they usually store the hash data in one big chunk. Tie::SymlinkTree
avoids this bottleneck and source of bugs by only using atomic OS primitives on individual keys. Locking is not completely avoidable, but reduces to a minimum.
TODO: the next paragraphs talk about experimental stuff and/or stuff not yet implemented. Calling this release version 1.0 refers to the tie syntax: It is stable and working as expected, as plain-hash-compatible as it can get.
The primary purpose is to prototype apps quickly through very easy setup (nothing but a writable location is needed), good performance and several upgrade paths: depending on the interface you use, it's easy to model apps using plain DBI, Class::DBI, or just any Tie-interface of your liking. Just exchange your objects to "the real thing" and you are set.
Additionally, since Tie::SymlinkTree offers several APIs at once, you can upgrade your prototypes' code without messy storage conversion steps: Write a quick CGI on tied hashes, upgrade to a decent DBI-based application when complexity raises, and model the final application using Class::DBI - all with the same storage.
AUTHOR and LICENSE
Copyright (C) 2004, Jörg Walter
This plugin is licensed under either the GNU GPL Version 2, or the Perl Artistic License.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 452:
Non-ASCII character seen before =encoding in 'Jörg'. Assuming UTF-8