~intrahealth+informatics/i2ce/4.2.1-release

« back to all changes in this revision

Viewing changes to lib/I2CE_MagicDataStorageSysV.php

  • Committer: Carl Leitner
  • Date: 2009-04-29 14:37:44 UTC
  • Revision ID: litlfred@cardamom-20090429143744-nyjpum1fqoysvhyr
added SysV magic data storage mechanism

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
* © Copyright 2009 IntraHealth International, Inc.
 
4
 
5
* This File is part of I2CE 
 
6
 
7
* I2CE is free software; you can redistribute it and/or modify 
 
8
* it under the terms of the GNU General Public License as published by 
 
9
* the Free Software Foundation; either version 3 of the License, or
 
10
* (at your option) any later version.
 
11
 
12
* This program 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 
 
15
* GNU General Public License for more details.
 
16
 
17
* You should have received a copy of the GNU General Public License 
 
18
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
* @package I2CE
 
20
* @subpackage Core
 
21
* @author Carl Leitner <litlfred@ibiblio.org>
 
22
* @version v3.2.0
 
23
* @since v3.2.0
 
24
* @filesource 
 
25
*/ 
 
26
/** 
 
27
* Class I2CE_MagicDataStorageSysV
 
28
 
29
* @access public
 
30
*/
 
31
 
 
32
if (!class_exists('I2CE_MagicDataStorageSysV',false)) {
 
33
    require_once('I2CE_MagicDataStorage.php');
 
34
    class I2CE_MagicDataStorageSysV extends I2CE_MagicDataStorage {
 
35
        const KEY = 2469;
 
36
        const MAX_AQUISITIONS = 1024;
 
37
        const SEG_SIZE = 33554432; //max seg size
 
38
        const NUM_SEGS = 3;
 
39
        /**
 
40
         * Returns true if this storage mechanism is ready to be used.  false otherwise.
 
41
         */
 
42
        public function isAvailable() {
 
43
            if (!function_exists('sem_get') || !function_exists('shm_get_var')) {
 
44
                I2CE::raiseError("sem_get not available");
 
45
                return false;
 
46
            }
 
47
            if ( !is_resource($this->shm_id)) {
 
48
                I2CE::raiseError("no shared memory id");
 
49
            }
 
50
            if (self::NUM_SEGS < 1 ) { //prevent stupidity
 
51
                I2CE::raiseError("bad number of segements");
 
52
                return false;
 
53
            }
 
54
            for ($i=0; $i < self::NUM_SEGS; $i++) {
 
55
                if (!array_key_exists($i,$this->seg) || !($this->seg[$i])) {
 
56
                    I2CE::raiseError("segment $i  is not a resource");
 
57
                    var_dump($this->seg[$i]);
 
58
                    return false;
 
59
                }
 
60
            }
 
61
            return true;
 
62
        }
 
63
        /**
 
64
         * The semaphore identifier.
 
65
         * @var protected $shm_id
 
66
         */
 
67
        protected $shm_id = false;
 
68
        /**
 
69
         * The array of memory segments
 
70
         * @var protected array $seg
 
71
         */
 
72
        protected $seg = array();
 
73
 
 
74
        /**
 
75
         * Gets the key for the System V Sempahore
 
76
         * @return int;
 
77
         */
 
78
        public function getKey() {
 
79
            return self::KEY;
 
80
        }
 
81
 
 
82
        /**
 
83
         * Create a new instance for magic data storage.
 
84
         * @param string $name The name assigned to this storage object
 
85
         */
 
86
        public function __construct( $name ) {
 
87
            parent::__construct($name);
 
88
            if (!function_exists('sem_get') || !function_exists('shm_get_var')) {
 
89
                return;
 
90
            }
 
91
            $this->shm_id = sem_get($this->getKey(),self::MAX_AQUISITIONS,0644 | IPC_CREAT);
 
92
            if (!is_resource($this->shm_id)) {
 
93
                return;
 
94
            }
 
95
            if (self::NUM_SEGS < 1) {
 
96
                return;
 
97
            }
 
98
            for ($i=0; $i < self::NUM_SEGS; $i++) {
 
99
                $this->seg[$i] = shm_attach($this->shm_id,self::SEG_SIZE);
 
100
            }
 
101
            $this->div = hexdec(str_pad('',32,'f'))/self::NUM_SEGS;
 
102
        }
 
103
 
 
104
        protected $div;
 
105
        
 
106
        /**
 
107
         * Store the given I2CE_MagicDataNode into the database.
 
108
         * @param I2CE_MagicDataNode $node
 
109
         * @returns boolean.  True on sucess
 
110
         */
 
111
        public function store( $node ) {
 
112
            $hash = $this->getHash( $node );
 
113
            $seg = $this->getSegment($hash);
 
114
            if ($seg < 0) {
 
115
                I2CE::raiseError("Bad segement:$seg");
 
116
                return false;
 
117
            }
 
118
            $save_data= array( 
 
119
                'type' => $node->getType(), 
 
120
                'value' => $node->getSaveValue(),
 
121
                'children' => $node->getKeys(null,true)
 
122
                );
 
123
            sem_acquire($this->shm_id);
 
124
            $success = shm_put_var($this->seg[$seg],$hash,$save_data);
 
125
            sem_release($this->shm_id);
 
126
            if (!$success) {
 
127
                I2CE_MagicDataNode::raiseError( "Error saving to Shared Memory " . $node->getPath() . " Type: " . $node->getType() . " Value: " . $value . " Children: " . implode(',',$children) );
 
128
            }
 
129
            return $success;
 
130
        }
 
131
        
 
132
 
 
133
        public function getSegment($hash) {
 
134
            if (!is_string($hash) || strlen($hash) == 0 || self::NUM_SEGS < 1) {
 
135
                var_dump( array( $hash, !is_string($hash) , strlen($hash) == 0 , self::NUM_SEGS < 1));
 
136
                return -1;
 
137
            }
 
138
            if (self::NUM_SEGS == 1) {
 
139
                return 0;
 
140
            }
 
141
            return ((int) (hexdec($hash) / $this->div));            
 
142
        }
 
143
        
 
144
        /**
 
145
         * Retrieve the given I2CE_MagicDataNode value and type.
 
146
         * @param I2CE_MagicDataNode $node
 
147
         * @return array
 
148
         */
 
149
        public function retrieve( $node ) {
 
150
            $hash = $this->getHash( $node );
 
151
            $seg = $this->getSegment($hash);
 
152
            if ($seg < 0) {
 
153
                I2CE::raiseError("Bad segement:$seg");
 
154
                return false;
 
155
            }
 
156
            return @shm_get_var($this->seg[$seg],$hash);
 
157
        }
 
158
 
 
159
        /**
 
160
         * Erases the given I2CE_MagicDataNode from the storage mechanism
 
161
         * @param I2CE_MagicDataNode
 
162
         */
 
163
        public function destroy($node) {
 
164
            $hash = $this->getHash( $node );
 
165
            $seg = $this->getSegment($hash);
 
166
            if ($seg < 0) {
 
167
                I2CE::raiseError("Bad segement:$seg");
 
168
                return false;
 
169
            }
 
170
            sem_acquire($this->shm_id);
 
171
            $success = shm_remove_var($this->seg[$seg],$hash);
 
172
            sem_release($this->shm_id);
 
173
            return $success;
 
174
        }
 
175
 
 
176
        /**
 
177
         * releases all shared memory segments
 
178
         * @return boolean
 
179
         */
 
180
        public function clear() {
 
181
            I2CE::raiseError("Clearing all shared memory segemnts");
 
182
            $success = true;
 
183
            for ($i=0; $i < self::NUM_SEGS; $i++) {
 
184
                $success &=  shm_remove($this->seg[$i]);
 
185
            }
 
186
            for ($i=0; $i < self::NUM_SEGS; $i++) {
 
187
                $this->seg[$i] = shm_attach($this->shm_id,self::SEG_SIZE);
 
188
            }
 
189
            return $success;
 
190
        }
 
191
 
 
192
    
 
193
   }
 
194
}
 
195
# Local Variables:
 
196
# mode: php
 
197
# c-default-style: "bsd"
 
198
# indent-tabs-mode: nil
 
199
# c-basic-offset: 4
 
200
# End: