Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConcatenatedGzipHistoryBlob
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 11
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 addItem
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getItem
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 setText
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getText
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 removeItem
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 compress
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 uncompress
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 __sleep
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 __wakeup
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isHappy
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Efficient concatenated text storage.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23/**
24 * Concatenated gzip (CGZ) storage
25 * Improves compression ratio by concatenating like objects before gzipping
26 *
27 * WARNING: Objects of this class are serialized and permanently stored in the DB.
28 * Do not change the name or visibility of any property!
29 */
30class ConcatenatedGzipHistoryBlob implements HistoryBlob {
31    /** @var int */
32    public $mVersion = 0;
33    /** @var bool */
34    public $mCompressed = false;
35    /** @var string[]|string Array if uncompressed, string if compressed */
36    public $mItems = [];
37    /** @var string */
38    public $mDefaultHash = '';
39    /** @var int */
40    public $mSize = 0;
41    /** @var int */
42    public $mMaxSize = 10_000_000;
43    /** @var int */
44    public $mMaxCount = 100;
45
46    public function __construct() {
47        if ( !function_exists( 'gzdeflate' ) ) {
48            throw new RuntimeException( "Need zlib support to read or write this "
49                . "kind of history object (ConcatenatedGzipHistoryBlob)\n" );
50        }
51    }
52
53    /**
54     * @param string $text
55     * @return string
56     */
57    public function addItem( $text ) {
58        $this->uncompress();
59        $hash = md5( $text );
60        if ( !isset( $this->mItems[$hash] ) ) {
61            $this->mItems[$hash] = $text;
62            $this->mSize += strlen( $text );
63        }
64        return $hash;
65    }
66
67    /**
68     * @param string $hash
69     * @return string|false
70     */
71    public function getItem( $hash ) {
72        $this->uncompress();
73        if ( array_key_exists( $hash, $this->mItems ) ) {
74            return $this->mItems[$hash];
75        } else {
76            return false;
77        }
78    }
79
80    /**
81     * @param string $text
82     * @return void
83     */
84    public function setText( $text ) {
85        $this->uncompress();
86        $this->mDefaultHash = $this->addItem( $text );
87    }
88
89    /**
90     * @return string|false
91     */
92    public function getText() {
93        $this->uncompress();
94        return $this->getItem( $this->mDefaultHash );
95    }
96
97    /**
98     * Remove an item
99     *
100     * @param string $hash
101     */
102    public function removeItem( $hash ) {
103        $this->mSize -= strlen( $this->mItems[$hash] );
104        unset( $this->mItems[$hash] );
105    }
106
107    /**
108     * Compress the bulk data in the object
109     */
110    public function compress() {
111        if ( !$this->mCompressed ) {
112            $this->mItems = gzdeflate( serialize( $this->mItems ) );
113            $this->mCompressed = true;
114        }
115    }
116
117    /**
118     * Uncompress bulk data
119     */
120    public function uncompress() {
121        if ( $this->mCompressed ) {
122            $this->mItems = HistoryBlobUtils::unserializeArray( gzinflate( $this->mItems ) );
123            $this->mCompressed = false;
124        }
125    }
126
127    /**
128     * @return array
129     */
130    public function __sleep() {
131        $this->compress();
132        return [ 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' ];
133    }
134
135    public function __wakeup() {
136        $this->uncompress();
137    }
138
139    /**
140     * Helper function for compression jobs
141     * Returns true until the object is "full" and ready to be committed
142     *
143     * @return bool
144     */
145    public function isHappy() {
146        return $this->mSize < $this->mMaxSize
147            && count( $this->mItems ) < $this->mMaxCount;
148    }
149}
150
151// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
152// class name coerced to lowercase. We can improve efficiency by adding
153// autoload entries for the lowercase variants of these classes (T166759).
154// The code below is never executed, but it is picked up by the AutoloadGenerator
155// parser, which scans for class_alias() calls.
156/*
157class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
158*/