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 * @license GPL-2.0-or-later
6 * @file
7 */
8
9// NO_NAMESPACE Compatibility with serialized objects in permanent storage
10
11/**
12 * Concatenated gzip (CGZ) storage
13 * Improves compression ratio by concatenating like objects before gzipping
14 *
15 * WARNING: Objects of this class are serialized and permanently stored in the DB.
16 * Do not change the name or visibility of any property!
17 */
18class ConcatenatedGzipHistoryBlob implements HistoryBlob {
19    /** @var int */
20    public $mVersion = 0;
21    /** @var bool */
22    public $mCompressed = false;
23    /** @var string[]|string Array if uncompressed, string if compressed */
24    public $mItems = [];
25    /** @var string */
26    public $mDefaultHash = '';
27    /** @var int */
28    public $mSize = 0;
29    /** @var int */
30    public $mMaxSize = 10_000_000;
31    /** @var int */
32    public $mMaxCount = 100;
33
34    public function __construct() {
35        if ( !function_exists( 'gzdeflate' ) ) {
36            throw new RuntimeException( "Need zlib support to read or write this "
37                . "kind of history object (ConcatenatedGzipHistoryBlob)\n" );
38        }
39    }
40
41    /**
42     * @param string $text
43     * @return string
44     */
45    public function addItem( $text ) {
46        $this->uncompress();
47        $hash = md5( $text );
48        if ( !isset( $this->mItems[$hash] ) ) {
49            $this->mItems[$hash] = $text;
50            $this->mSize += strlen( $text );
51        }
52        return $hash;
53    }
54
55    /**
56     * @param string $hash
57     * @return string|false
58     */
59    public function getItem( $hash ) {
60        $this->uncompress();
61        if ( array_key_exists( $hash, $this->mItems ) ) {
62            return $this->mItems[$hash];
63        } else {
64            return false;
65        }
66    }
67
68    /**
69     * @param string $text
70     * @return void
71     */
72    public function setText( $text ) {
73        $this->uncompress();
74        $this->mDefaultHash = $this->addItem( $text );
75    }
76
77    /**
78     * @return string|false
79     */
80    public function getText() {
81        $this->uncompress();
82        return $this->getItem( $this->mDefaultHash );
83    }
84
85    /**
86     * Remove an item
87     *
88     * @param string $hash
89     */
90    public function removeItem( $hash ) {
91        $this->mSize -= strlen( $this->mItems[$hash] );
92        unset( $this->mItems[$hash] );
93    }
94
95    /**
96     * Compress the bulk data in the object
97     */
98    public function compress() {
99        if ( !$this->mCompressed ) {
100            $this->mItems = gzdeflate( serialize( $this->mItems ) );
101            $this->mCompressed = true;
102        }
103    }
104
105    /**
106     * Uncompress bulk data
107     */
108    public function uncompress() {
109        if ( $this->mCompressed ) {
110            $this->mItems = HistoryBlobUtils::unserializeArray( gzinflate( $this->mItems ) );
111            $this->mCompressed = false;
112        }
113    }
114
115    /**
116     * @return array
117     */
118    public function __sleep() {
119        $this->compress();
120        return [ 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' ];
121    }
122
123    public function __wakeup() {
124        $this->uncompress();
125    }
126
127    /** @inheritDoc */
128    public function isHappy(): bool {
129        return $this->mSize < $this->mMaxSize
130            && count( $this->mItems ) < $this->mMaxCount;
131    }
132}
133
134// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
135// class name coerced to lowercase. We can improve efficiency by adding
136// autoload entries for the lowercase variants of these classes (T166759).
137// The code below is never executed, but it is picked up by the AutoloadGenerator
138// parser, which scans for class_alias() calls.
139/*
140class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
141*/