]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/LinkCache.php
MediaWiki 1.16.0
[autoinstalls/mediawiki.git] / includes / LinkCache.php
1 <?php
2 /**
3  * Cache for article titles (prefixed DB keys) and ids linked from one source
4  *
5  * @ingroup Cache
6  */
7 class LinkCache {
8         // Increment $mClassVer whenever old serialized versions of this class
9         // becomes incompatible with the new version.
10         /* private */ var $mClassVer = 4;
11
12         /* private */ var $mGoodLinks, $mBadLinks;
13         /* private */ var $mForUpdate;
14
15         /**
16          * Get an instance of this class
17          */
18         static function &singleton() {
19                 static $instance;
20                 if ( !isset( $instance ) ) {
21                         $instance = new LinkCache;
22                 }
23                 return $instance;
24         }
25
26         function __construct() {
27                 $this->mForUpdate = false;
28                 $this->mGoodLinks = array();
29                 $this->mGoodLinkFields = array();
30                 $this->mBadLinks = array();
31         }
32
33         /**
34          * General accessor to get/set whether SELECT FOR UPDATE should be used
35          */
36         public function forUpdate( $update = null ) {
37                 return wfSetVar( $this->mForUpdate, $update );
38         }
39
40         public function getGoodLinkID( $title ) {
41                 if ( array_key_exists( $title, $this->mGoodLinks ) ) {
42                         return $this->mGoodLinks[$title];
43                 } else {
44                         return 0;
45                 }
46         }
47
48         /**
49          * Get a field of a title object from cache.
50          * If this link is not good, it will return NULL.
51          * @param Title $title
52          * @param string $field ('length','redirect')
53          * @return mixed
54          */
55         public function getGoodLinkFieldObj( $title, $field ) {
56                 $dbkey = $title->getPrefixedDbKey();
57                 if ( array_key_exists( $dbkey, $this->mGoodLinkFields ) ) {
58                         return $this->mGoodLinkFields[$dbkey][$field];
59                 } else {
60                         return null;
61                 }
62         }
63
64         public function isBadLink( $title ) {
65                 return array_key_exists( $title, $this->mBadLinks );
66         }
67
68         /**
69          * Add a link for the title to the link cache
70          * @param int $id
71          * @param Title $title
72          * @param int $len
73          * @param int $redir
74          */
75         public function addGoodLinkObj( $id, $title, $len = -1, $redir = null ) {
76                 $dbkey = $title->getPrefixedDbKey();
77                 $this->mGoodLinks[$dbkey] = intval( $id );
78                 $this->mGoodLinkFields[$dbkey] = array(
79                         'length' => intval( $len ),
80                         'redirect' => intval( $redir ) );
81         }
82
83         public function addBadLinkObj( $title ) {
84                 $dbkey = $title->getPrefixedDbKey();
85                 if ( !$this->isBadLink( $dbkey ) ) {
86                         $this->mBadLinks[$dbkey] = 1;
87                 }
88         }
89
90         public function clearBadLink( $title ) {
91                 unset( $this->mBadLinks[$title] );
92         }
93
94         public function clearLink( $title ) {
95                 $dbkey = $title->getPrefixedDbKey();
96                 if( isset($this->mBadLinks[$dbkey]) ) {
97                         unset($this->mBadLinks[$dbkey]);
98                 }
99                 if( isset($this->mGoodLinks[$dbkey]) ) {
100                         unset($this->mGoodLinks[$dbkey]);
101                 }
102                 if( isset($this->mGoodLinkFields[$dbkey]) ) {
103                         unset($this->mGoodLinkFields[$dbkey]);
104                 }
105         }
106
107         public function getGoodLinks() { return $this->mGoodLinks; }
108         public function getBadLinks() { return array_keys( $this->mBadLinks ); }
109
110         /**
111          * Add a title to the link cache, return the page_id or zero if non-existent
112          * @param $title String: title to add
113          * @param $len int, page size
114          * @param $redir bool, is redirect?
115          * @return integer
116          */
117         public function addLink( $title, $len = -1, $redir = null ) {
118                 $nt = Title::newFromDBkey( $title );
119                 if( $nt ) {
120                         return $this->addLinkObj( $nt, $len, $redir );
121                 } else {
122                         return 0;
123                 }
124         }
125
126         /**
127          * Add a title to the link cache, return the page_id or zero if non-existent
128          * @param $nt Title to add.
129          * @param $len int, page size
130          * @param $redir bool, is redirect?
131          * @return integer
132          */
133         public function addLinkObj( &$nt, $len = -1, $redirect = null ) {
134                 global $wgAntiLockFlags, $wgProfiler;
135                 wfProfileIn( __METHOD__ );
136
137                 $key = $nt->getPrefixedDBkey();
138                 if ( $this->isBadLink( $key ) ) {
139                         wfProfileOut( __METHOD__ );
140                         return 0;
141                 }
142                 $id = $this->getGoodLinkID( $key );
143                 if ( $id != 0 ) {
144                         wfProfileOut( __METHOD__ );
145                         return $id;
146                 }
147
148                 if ( $key === '' ) {
149                         wfProfileOut( __METHOD__ );
150                         return 0;
151                 }
152                 
153                 # Some fields heavily used for linking...
154                 if ( $this->mForUpdate ) {
155                         $db = wfGetDB( DB_MASTER );
156                         if ( !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) {
157                                 $options = array( 'FOR UPDATE' );
158                         } else {
159                                 $options = array();
160                         }
161                 } else {
162                         $db = wfGetDB( DB_SLAVE );
163                         $options = array();
164                 }
165
166                 $s = $db->selectRow( 'page', 
167                         array( 'page_id', 'page_len', 'page_is_redirect' ),
168                         array( 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ),
169                         __METHOD__, $options );
170                 # Set fields...
171                 if ( $s !== false ) {
172                         $id = intval( $s->page_id );
173                         $len = intval( $s->page_len );
174                         $redirect = intval( $s->page_is_redirect );
175                 } else {
176                         $len = -1;
177                         $redirect = 0;
178                 }
179
180                 if ( $id == 0 ) {
181                         $this->addBadLinkObj( $nt );
182                 } else {
183                         $this->addGoodLinkObj( $id, $nt, $len, $redirect );
184                 }
185                 wfProfileOut( __METHOD__ );
186                 return $id;
187         }
188
189         /**
190          * Clears cache
191          */
192         public function clear() {
193                 $this->mGoodLinks = array();
194                 $this->mGoodLinkFields = array();
195                 $this->mBadLinks = array();
196         }
197 }