/[webpac]/openisis/current/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

Contents of /openisis/current/php/Isis/File.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 237 - (show annotations)
Mon Mar 8 17:43:12 2004 UTC (20 years, 1 month ago) by dpavlin
File size: 5439 byte(s)
initial import of openisis 0.9.0 vendor drop

1 <?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