ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ObjectUtilities/ObjectStore.pm
Revision: 1.14
Committed: Mon Oct 9 12:29:32 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: V1_1_7, V1_1_6, V1_1_5, V1_2_0-cand3, V1_2_0-cand2, V1_2_0-cand1, V1_1_4, V1_1_3, V1_1_2, V1_1_0_reltag8, V1_1_0_reltag7, V1_1_0_reltag6, V1_1_1, V1_1_0_reltag5, V1_1_0_reltag4, V1_1_0_reltag3, V1_1_0_reltag2, V1_1_0_reltag1, V1_1_0_reltag, V1_0_3-p4, V1_1_0_cand3, V1_1_0_cand2, V1_1_0_cand1, HEAD_SM_071214, forV1_1_0, v103_xml_071106, V1_0_3-p3, V1_0_3-p2, V1_1_0, v110p1, V110p6, V110p5, V110p4, V110p3, before110xmlBRmerge, V110p2, V110p1, V1_0_4p1, V1_0_3-p1, V1_0_3, V1_0_2, V1_0_2_p1, v102p1, V1_0_1, V1_0_0, V1_pre0, SCRAM_V1, SCRAMV1_IMPORT, V0_19_7, V0_19_6, V0_19_6p1, V0_19_5, SFATEST, V0_19_4, V0_19_4_pre3, V0_19_4_pre2, V0_19_4_pre1, V0_19_3, V0_19_2, V0_19_1, V0_19_0, V0_18_5, V0_18_4, V_18_3_TEST, VO_18_3, V0_18_2, V0_18_1
Branch point for: forBinLess_SCRAM, HEAD_BRANCH_SM_071214, v200branch, v103_with_xml, v103_branch, V1_pre1, SCRAM_V1_BRANCH, V0_19_4_B
Changes since 1.13: +10 -0 lines
Log Message:
Import from V0_15branch - storeref method

File Contents

# Content
1 #
2 # ObjectStore.pm
3 #
4 # Originally Written by Christopher Williams
5 #
6 # Description
7 # -----------
8 # An very simple object persistency manager for small scale use.
9 # Objects are saved and recovered on demand
10 # Objects to be stored in this manager must implement the following interface
11 # new(ObjectStore) :
12 # store(location) : dump out to location
13 # restore(location) : restore from location
14 # objects must inherit from StorableObject
15 #
16 # Interface
17 # ---------
18 # new(store_directory,[object]) : A new ObjectStore object. An alternative
19 # object can be specified with which to
20 # construct the stored objects with by
21 # supplying the object reference
22 # if store_directory begins with "<" - does
23 # not attempt to build it if it dosnt exist
24 # storeref([object]) : set/return the object store referefnce object
25 # (as passed in new)
26 # store(oref,@keys) : store an object - each object must have
27 # a unique key
28 # find(@keys) : find and recover object(s) from the store
29 # that match keys. Returned as a list of oref
30 # sequence(@keys) : return the sequence number of the object
31 # matching the keys
32 # An object is assigned a new sequence number
33 # with each store.
34 # delete(@keys) : Delete the object with the given key
35 # alias(\@refofkeys,\@aliaskeys) : attatch another set of keys to objects that
36 # match the refofkeys
37 # note that these are references to the arrays
38 # unalias(@aliaskeys) :remove an alias
39 # location() : return the top directory where the store is
40 # located
41
42 package ObjectUtilities::ObjectStore;
43 require 5.004;
44 use Utilities::AddDir;
45 use Utilities::HashDB;
46
47 sub new {
48 my $class=shift;
49 my $dir=shift;
50 $self={};
51 # do we have an alternative object to instantiate objects with
52 if ( @_ ) {
53 $self->{storeobject}=shift;
54 }
55 else {
56 $self->{storeobject}=$self;
57 }
58 bless $self, $class;
59 ($self->{location}=$dir)=~s/^\<//;
60 $self->{admindir}=$self->{location}."/admin";
61 if ( $dir=~"^\<" ) {
62 }
63 else {
64 AddDir::adddir($self->{admindir});
65 }
66 if ( -d $self->{location} ) {
67 $self->{storage}=$dir."/objects";
68 AddDir::adddir($self->{storage});
69 $self->_init();
70 }
71 else {
72 return undef;
73 }
74 #print "ObjectStore -- $self->{storeobject}\n";
75 return $self;
76 }
77
78 sub storeref {
79 my $self=shift;
80 if ( @_ ) {
81 $self->{storeobject}=shift;
82 }
83 return $self->{storeobject};
84 }
85
86 sub location {
87 my $self=shift;
88 return $self->{location};
89 }
90
91 sub store {
92 my $self=shift;
93 my $oref=shift;
94 my @keys=@_;
95
96 my $oreftype=ref($oref);
97 #print "$self: Storing an object of type : $oreftype\n";
98 my $filename=$self->_filename(@keys);
99 $oref->store($self->_fullfilename($filename));
100 # Update the sequence number to track changes
101 my @seqnumbers=$self->{filehash}->getdata("__seq_number",@keys);
102 my $seqnumb=((@seqnumbers)?$seqnumbers[0]:-1)+1;
103 $self->{filehash}->deletedata("__seq_number",@keys);
104 $self->{filehash}->setdata($seqnumb,"__seq_number",@keys);
105
106 $self->{filehash}->deletedata(@keys);
107 $self->{filehash}->setdata($filename,@keys); # persistent
108 $self->{typehash}->deletedata($filename);
109 $self->{typehash}->setdata($oreftype,$filename); # persistent
110 $self->{orefhash}->deletedata($filename);
111 $self->{orefhash}->setdata($oref,$filename); # transient
112 $self->_storedb();
113 }
114
115 sub sequence {
116 my $self=shift;
117 my @keys=@_;
118
119 my @seq=$self->{filehash}->getdata("__seq_number",@keys);
120 return (($#seq == 0)?$seq[0]:-1);
121 }
122
123 sub find {
124 my $self=shift;
125 my @keys=@_;
126
127 my @oref=();
128 my $oref;
129 my @types;
130 my $type;
131 my @validobjs=();
132 my $fh;
133
134 #print "$self: Searching for : @keys\n";
135 my @datafiles=$self->{filehash}->getdata(@keys);
136 foreach $file ( @datafiles ) {
137 @oref=$self->{orefhash}->getdata($file);
138 if ( $#oref < 0 ) { # we need to instatniate it
139 @types=$self->{typehash}->getdata($file);
140 $type=$types[0];
141 eval "require $type";
142 $oref=$type->new($self->{storeobject});
143 $oref->restore($self->_fullfilename($file));
144 }
145 else {
146 $oref=$oref[0];
147 }
148 push @validobjs, $oref;
149 }
150 return @validobjs;
151 }
152
153 sub alias {
154 my $self=shift;
155 $self->{filehash}->alias(@_);
156 $self->_storedb();
157 }
158
159 sub unalias {
160 my $self=shift;
161 $self->{filehash}->unalias(@_);
162 $self->_storedb();
163 }
164
165 sub delete {
166 my $self=shift;
167 my @keys=@_;
168
169 my $filename=$self->_filename(@keys);
170 $self->{filehash}->deletedata("__seq_number",@keys);
171 $self->{filehash}->deletedata(@keys);
172 $self->{typehash}->deletedata($filename);
173 $self->{orefhash}->deletedata($filename);
174 $self->_storedb();
175 print "Deleting ".$self->_fullfilename($filename)."\n";
176 unlink $self->_fullfilename($filename);
177 }
178
179 #
180 # Private routines
181 #
182 sub _filename {
183 my $self=shift;
184 my @keys=@_;
185
186 my ($file)=$self->{filehash}->getdata(@keys);
187 if ( ! defined $file ) {
188 # need to generate a new filename - a random number will do
189 srand();
190 do {
191 $file=int(rand 99999999)+1;
192 } until ( ! ( -e $self->_fullfilename($file) ) );
193 }
194 return $file;
195 }
196
197 sub _fullfilename {
198 my $self=shift;
199 my $file=shift;
200
201 if ( $file!~/^\// ) { # return only full path names
202 $file=$self->{storage}."/".$file;
203 }
204 return $file;
205 }
206
207 sub _storedb {
208 my $self=shift;
209 $self->{filehash}->store($self->{admindir}."/filedb");
210 $self->{typehash}->store($self->{admindir}."/typedb");
211 }
212
213 sub _restoredb {
214 my $self=shift;
215 if ( -f $self->{admindir}."/filedb" ) {
216 $self->{filehash}->restore($self->{admindir}."/filedb");
217 $self->{typehash}->restore($self->{admindir}."/typedb");
218 }
219 }
220
221 sub _openfile {
222 my $self=shift;
223 my $filename=shift;
224
225 local $fh=FileHandle->new();
226 open ( $fh, $filename) or die "Unable to open $filename\n $!\n";
227 return $fh;
228 }
229
230 sub _init {
231 my $self=shift;
232 $self->{filehash}=Utilities::HashDB->new();
233 $self->{typehash}=Utilities::HashDB->new();
234 $self->{orefhash}=Utilities::HashDB->new();
235 $self->_restoredb();
236 }