]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/LinkCache.php
MediaWiki 1.14.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] = $id;
78                 $this->mGoodLinkFields[$dbkey] = array( 'length' => $len, 'redirect' => $redir );
79         }
80
81         public function addBadLinkObj( $title ) {
82                 $dbkey = $title->getPrefixedDbKey();
83                 if ( !$this->isBadLink( $dbkey ) ) {
84                         $this->mBadLinks[$dbkey] = 1;
85                 }
86         }
87
88         public function clearBadLink( $title ) {
89                 unset( $this->mBadLinks[$title] );
90         }
91
92         public function clearLink( $title ) {
93                 $dbkey = $title->getPrefixedDbKey();
94                 if( isset($this->mBadLinks[$dbkey]) ) {
95                         unset($this->mBadLinks[$dbkey]);
96                 }
97                 if( isset($this->mGoodLinks[$dbkey]) ) {
98                         unset($this->mGoodLinks[$dbkey]);
99                 }
100                 if( isset($this->mGoodLinkFields[$dbkey]) ) {
101                         unset($this->mGoodLinkFields[$dbkey]);
102                 }
103         }
104
105         public function getGoodLinks() { return $this->mGoodLinks; }
106         public function getBadLinks() { return array_keys( $this->mBadLinks ); }
107
108         /**
109          * Add a title to the link cache, return the page_id or zero if non-existent
110          * @param $title String: title to add
111          * @param $len int, page size
112          * @param $redir bool, is redirect?
113          * @return integer
114          */
115         public function addLink( $title, $len = -1, $redir = NULL ) {
116                 $nt = Title::newFromDBkey( $title );
117                 if( $nt ) {
118                         return $this->addLinkObj( $nt, $len, $redir );
119                 } else {
120                         return 0;
121                 }
122         }
123
124         /**
125          * Add a title to the link cache, return the page_id or zero if non-existent
126          * @param $nt Title to add.
127          * @param $len int, page size
128          * @param $redir bool, is redirect?
129          * @return integer
130          */
131         public function addLinkObj( &$nt, $len = -1, $redirect = NULL ) {
132                 global $wgAntiLockFlags, $wgProfiler;
133                 wfProfileIn( __METHOD__ );
134
135                 $key = $nt->getPrefixedDBkey();
136                 if ( $this->isBadLink( $key ) ) {
137                         wfProfileOut( __METHOD__ );
138                         return 0;
139                 }
140                 $id = $this->getGoodLinkID( $key );
141                 if ( $id != 0 ) {
142                         wfProfileOut( __METHOD__ );
143                         return $id;
144                 }
145
146                 if ( $key === '' ) {
147                         wfProfileOut( __METHOD__ );
148                         return 0;
149                 }
150                 
151                 # Some fields heavily used for linking...
152                 if ( $this->mForUpdate ) {
153                         $db = wfGetDB( DB_MASTER );
154                         if ( !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) {
155                                 $options = array( 'FOR UPDATE' );
156                         } else {
157                                 $options = array();
158                         }
159                 } else {
160                         $db = wfGetDB( DB_SLAVE );
161                         $options = array();
162                 }
163
164                 $s = $db->selectRow( 'page', 
165                         array( 'page_id', 'page_len', 'page_is_redirect' ),
166                         array( 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ),
167                         __METHOD__, $options );
168                 # Set fields...
169                 if ( $s !== false ) {
170                         $id = $s->page_id;
171                         $len = $s->page_len;
172                         $redirect = $s->page_is_redirect;
173                 } else {
174                         $len = -1;
175                         $redirect = 0;
176                 }
177
178                 if ( $id == 0 ) {
179                         $this->addBadLinkObj( $nt );
180                 } else {
181                         $this->addGoodLinkObj( $id, $nt, $len, $redirect );
182                 }
183                 wfProfileOut( __METHOD__ );
184                 return $id;
185         }
186
187         /**
188          * Clears cache
189          */
190         public function clear() {
191                 $this->mGoodLinks = array();
192                 $this->mGoodLinkFields = array();
193                 $this->mBadLinks = array();
194         }
195 }