ebc47145d4587a6555decb0be4b2742d56b1bd29
[lhc/web/wiklou.git] / includes / HistoryBlob.php
1 <?php
2 /**
3 *
4 * @package MediaWiki
5 */
6
7 /**
8 * Pure virtual parent
9 * @package MediaWiki
10 */
11 class HistoryBlob
12 {
13 # setMeta and getMeta currently aren't used for anything, I just thought they might be useful in the future
14 # The meta value is a single string
15 function setMeta( $meta ) {}
16
17 # Gets the meta-value
18 function getMeta() {}
19
20 # Adds an item of text, returns a stub object which points to the item
21 # You must call setLocation() on the stub object before storing it to the database
22 function addItem() {}
23
24 # Get item by hash
25 function getItem( $hash ) {}
26
27 # Set the "default text"
28 # This concept is an odd property of the current DB schema, whereby each text item has a revision
29 # associated with it. The default text is the text of the associated revision. There may, however,
30 # be other revisions in the same object
31 function setText() {}
32
33 # Get default text. This is called from Article::getRevisionText()
34 function getText() {}
35 }
36
37 /**
38 * The real object
39 * @package MediaWiki
40 */
41 class ConcatenatedGzipHistoryBlob extends HistoryBlob
42 {
43 /* private */ var $mVersion = 0, $mCompressed = false, $mItems = array(), $mDefaultHash = '';
44 /* private */ var $mFast = 0, $mSize = 0;
45
46 function ConcatenatedGzipHistoryBlob() {
47 if ( !function_exists( 'gzdeflate' ) ) {
48 die( "Need zlib support to read or write this kind of history object (ConcatenatedGzipHistoryBlob)\n" );
49 }
50 }
51
52 function setMeta( $metaData ) {
53 $this->uncompress();
54 $this->mItems['meta'] = $metaData;
55 }
56
57 function getMeta() {
58 $this->uncompress();
59 return $this->mItems['meta'];
60 }
61
62 function addItem( $text ) {
63 $this->uncompress();
64 $hash = md5( $text );
65 $this->mItems[$hash] = $text;
66 $this->mSize += strlen( $text );
67
68 $stub = new HistoryBlobStub( $hash );
69 return $stub;
70 }
71
72 function getItem( $hash ) {
73 $this->uncompress();
74 if ( array_key_exists( $hash, $this->mItems ) ) {
75 return $this->mItems[$hash];
76 } else {
77 return false;
78 }
79 }
80
81 function removeItem( $hash ) {
82 $this->mSize -= strlen( $this->mItems[$hash] );
83 unset( $this->mItems[$hash] );
84 }
85
86 function compress() {
87 if ( !$this->mCompressed ) {
88 $this->mItems = gzdeflate( serialize( $this->mItems ) );
89 $this->mCompressed = true;
90 }
91 }
92
93 function uncompress() {
94 if ( $this->mCompressed ) {
95 $this->mItems = unserialize( gzinflate( $this->mItems ) );
96 $this->mCompressed = false;
97 }
98 }
99
100 function getText() {
101 $this->uncompress();
102 return $this->getItem( $this->mDefaultHash );
103 }
104
105 function setText( $text ) {
106 $this->uncompress();
107 $stub = $this->addItem( $text );
108 $this->mDefaultHash = $stub->mHash;
109 }
110
111 function __sleep() {
112 $this->compress();
113 return array( 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' );
114 }
115
116 function __wakeup() {
117 $this->uncompress();
118 }
119
120 # Determines if this object is happy
121 function isHappy( $maxFactor, $factorThreshold ) {
122 if ( count( $this->mItems ) == 0 ) {
123 return true;
124 }
125 if ( $this->mFast ) {
126 $this->uncompress();
127 $record = serialize( $this->mItems );
128 $size = strlen( $record );
129 $avgUncompressed = $size / count( $this->mItems );
130 $compressed = strlen( gzdeflate( $record ) );
131
132 if ( $compressed < $factorThreshold * 1024 ) {
133 return true;
134 } else {
135 return $avgUncompressed * $maxFactor < $compressed;
136 }
137 } else {
138 return count( $this->mItems ) <= 10;
139 }
140 }
141 }
142
143 class HistoryBlobStub
144 {
145 var $mOldId, $mHash;
146
147 function HistoryBlobStub( $hash = '', $oldid = 0 ) {
148 $this->mHash = $hash;
149 }
150
151 # Sets the location (old_id) of the main object to which this object points
152 function setLocation( $id ) {
153 $this->mOldId = $id;
154 }
155
156 function getText() {
157 $dbr =& wfGetDB( DB_SLAVE );
158 $row = $dbr->selectRow( 'old', array( 'old_flags', 'old_text' ), array( 'old_id' => $this->mOldId ) );
159 if ( !$row || $row->old_flags != 'object' ) {
160 return false;
161 }
162 $obj = unserialize( $row->old_text );
163 if ( !is_object( $obj ) ) {
164 $obj = unserialize( $obj );
165 }
166 return $obj->getItem( $this->mHash );
167 }
168
169 function getHash() {
170 return $this->mHash;
171 }
172 }
173 ?>