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