/[webpac]/openisis/0.9.0/php/Isis/File.php
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /openisis/0.9.0/php/Isis/File.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 238 - (hide annotations)
Mon Mar 8 17:46:16 2004 UTC (20 years, 3 months ago) by dpavlin
File size: 5439 byte(s)
tagging openisis 0.9.0

1 dpavlin 237 <?php
2     /*
3     OpenIsis - an open implementation of the CDS/ISIS database
4     Version 0.8.x (patchlevel see file Version)
5     Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
6    
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11    
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     Lesser General Public License for more details.
16    
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20    
21     see README for more information
22     EOH */
23    
24     // $Id: File.php,v 1.4 2003/06/13 19:35:24 kripke Exp $
25    
26    
27     /**
28     the magic for a 4/4/0 little endian isis xref file.
29     http://OpenIsis.org/openisis/doc/Serialized
30     */
31     define( 'ISIS_FILE_MAGIC', "ISIXD\0:)" );
32     /**
33     The flat file database.
34     It does not know anything about isis records,
35     it's just dealing with the string representation.
36    
37     58971 records (unesb), 29442129 bytes flat (34565120 as .mst)
38     mkxrf: 8.1 sec (7280 recs / sec)
39     read all (just the string): 3.48 sec (~17.000 recs / sec)
40     read 10.000, creating recs: 3.95 sec
41     read 1.000, creating recs, printing: ~2 sec
42    
43     @version $Revision: 1.4 $
44     @license LGPL
45     @package Isis
46     */
47     class Isis_File {
48     var $name;
49     var $mst;
50     var $xrf = 0;
51     var $w;
52     /** number of records == number of last record
53     */
54     var $len = 0;
55    
56     function Isis_File ( $name, $write = 0 )
57     {
58     $this->name = $name;
59     $this->w = $write;
60     $this->mst = fopen($name.'.txt', $write ? 'a+' : 'r');
61     if ( ! $this->mst )
62     return;
63     flock($this->mst, $write ? LOCK_EX : LOCK_SH);
64     $s = fstat($this->mst);
65     $mtime = $s['mtime'];
66     if ( file_exists($name.'.ptr') ) // avoid annoying warning
67     $this->xrf = fopen($name.'.ptr', $write ? 'r+' : 'r');
68     if (!$this->xrf)
69     $remake = 1;
70     else {
71     $s = fstat($this->xrf);
72     $magic = fread($this->xrf, 8);
73     $remake = $s['mtime'] < $mtime || ISIS_FILE_MAGIC != $magic;
74     if ( !$remake )
75     $this->len = $s['size'] / 8 - 1;
76     if ( $remake && !$write ) {
77     fclose($this->xrf);
78     $this->xrf = 0;
79     }
80     }
81     if ( !$this->xrf && !($this->xrf = fopen($name.'.ptr','w+')) ) {
82     fclose($this->mst);
83     return;
84     }
85     if ( $remake )
86     $this->mkxref();
87     }
88    
89    
90     function mkxref ()
91     {
92     fseek($this->mst, 0);
93     ftruncate($this->xrf, 0);
94     fseek($this->xrf, 0);
95     fwrite( $this->xrf, ISIS_FILE_MAGIC, 8 );
96     $mfn = 0;
97     $lines = 0;
98     for (;;) {
99     $line = fgets($this->mst);
100     $end = !is_string($line) || '' == $line;
101     if ( $end || "\n" == $line{0} ) {
102     $now = ftell($this->mst);
103     $len = $now - $pos - 1;
104     if ( $len && !$end )
105     $len--;
106     if ($mfn) {
107     $xrf = pack('VV', $pos, $len);
108     // echo "mfn $mfn pos $pos len $len\n";
109     if ( 8 != ($foo = fwrite($this->xrf, $xrf)) )
110     echo "FOO! $foo\n";
111     if ($this->len < $mfn)
112     $this->len = $mfn;
113     }
114     if ($end)
115     break;
116     $mfn++;
117     $pos = $now;
118     $lines = 0;
119     continue;
120     }
121     if ( ! $lines
122     && ! (int)$line
123     && 2 == sscanf($line, "%c %d", &$ctrl, &$num)
124     && 'W' == $ctrl
125     ) {
126     echo "W $num\n";
127     $pos = ftell($this->mst);
128     $mfn = $num;
129     fseek($this->xrf, 8*$mfn);
130     continue;
131     }
132     $lines++;
133     }
134     fflush( $this->xrf );
135     } // mkxref
136    
137    
138     /**
139     @return string number $mfn or null
140     */
141     function read ( $mfn )
142     {
143     fseek($this->xrf, 8*$mfn);
144     $xrf = fread( $this->xrf, 8 );
145     if ( 8 != strlen($xrf) ) {
146     // echo "no xrf for $mfn\n";
147     return null;
148     }
149     $xrf = unpack('Vpos/Vlen', $xrf);
150     // echo "mfn $mfn pos ${xrf['pos']} len ${xrf['len']}\n";
151     if ( !$xrf['pos'] || !$xrf['len'] )
152     return null;
153     fseek($this->mst, $xrf['pos']);
154     $rec = fread($this->mst, $xrf['len']);
155     return $xrf['len'] == strlen($rec) ? $rec : null;
156     }
157    
158    
159     /**
160     write $data as $mfn or ++$this->len
161     @return mfn
162     */
163     function write ( $data, $mfn = 0 )
164     {
165     if ( !$this->w )
166     trigger_error( $this->name.' not writable', E_USER_ERROR );
167     if ( !$mfn )
168     $mfn = ++$this->len;
169     elseif ($this->len < $mfn)
170     $this->len = $mfn;
171     if ( !is_string($data) )
172     $len = 0;
173     elseif ( $len = strlen($data) ) {
174     if ("\n" == $data{$len-1})
175     $len--;
176     else
177     $data .= "\n";
178     }
179     fseek($this->mst, 0, SEEK_END); // prbly not needed by mode a+
180     fwrite($this->mst, "\nW\t$mfn\n");
181     fflush($this->mst);
182     $pos = ftell($this->mst);
183     if ( $len )
184     fwrite($this->mst, $data);
185     fseek($this->xrf, 8*$mfn);
186     // echo "write $mfn len $len\n";
187     fwrite($this->xrf, pack('VV', $pos, $len));
188     fflush($this->xrf);
189     return $mfn;
190     }
191    
192    
193     function compact ()
194     {
195     if ( !$this->w )
196     trigger_error( $this->name.' not writable', E_USER_ERROR );
197     $c = fopen($this->name.'.new', 'w+');
198     flock($c, LOCK_EX); // so we have exclusive locks on both
199     for ( $n=1; $n<=$this->len; $n++ )
200     fwrite($c, is_null($data = $this->read($n))
201     ? "\n" : "\n".$data."\n"
202     );
203     fflush($c);
204     if ( file_exists($this->name.'.old') )
205     unlink($this->name.'.old');
206     rename($this->name.'.txt', $this->name.'.old');
207     rename($this->name.'.new', $this->name.'.txt');
208     fclose($this->mst);
209     $this->mst = $c;
210     $this->mkxref(); // frob the xref in place
211     }
212    
213     } // class Isis_File
214     ?>

  ViewVC Help
Powered by ViewVC 1.1.26