3 * Contain the blockcache class
8 * Object for fast lookup of IP blocks
9 * Represents a memcached value, and in some sense, the entire ipblocks table
14 var $mData = false, $mMemcKey;
18 * Create a new BlockCache object
20 * @param Boolean $deferLoad specifies whether to immediately load the data from memcached.
21 * @param String $dbName specifies the memcached dbName prefix to be used. Defaults to $wgDBname.
23 function BlockCache( $deferLoad = false, $dbName = '' ) {
26 if ( $dbName == '' ) {
30 $this->mMemcKey
= $dbName.':ipblocks';
38 * Load the blocks from the database and save them to memcached
39 * @param bool $bFromSlave Whether to load data from slaves or master
41 function loadFromDB( $bFromSlave = false ) {
42 global $wgUseMemCached, $wgMemc;
43 $this->mData
= array();
44 # Selecting FOR UPDATE is a convenient way to serialise the memcached and DB operations,
45 # which is necessary even though we don't update the DB
47 Block
::enumBlocks( 'wfBlockCacheInsert', '', EB_FOR_UPDATE
);
48 #$wgMemc->set( $this->mMemcKey, $this->mData, 0 );
50 Block
::enumBlocks( 'wfBlockCacheInsert', '' );
55 * Load the cache from memcached or, if that's not possible, from the DB
57 function load( $bFromSlave ) {
58 global $wgUseMemCached, $wgMemc;
60 if ( $this->mData
=== false) {
61 $this->loadFromDB( $bFromSlave );
63 // Memcache disabled for performance issues.
65 if ( $wgUseMemCached ) {
66 $this->mData = $wgMemc->get( $this->mMemcKey );
69 if ( !is_array( $this->mData ) ) {
70 $this->loadFromDB( $bFromSlave );
76 * Add a block to the cache
78 * @param Object &$block Reference to a "Block" object.
80 function insert( &$block ) {
81 if ( $block->mUser
== 0 ) {
82 $nb = $block->getNetworkBits();
83 $ipint = $block->getIntegerAddr();
84 $index = $ipint >> ( 32 - $nb );
86 if ( !array_key_exists( $nb, $this->mData
) ) {
87 $this->mData
[$nb] = array();
90 $this->mData
[$nb][$index] = 1;
95 * Find out if a given IP address is blocked
97 * @param String $ip IP address
98 * @param bool $bFromSlave True means to load check against slave, else check against master.
100 function get( $ip, $bFromSlave ) {
101 $this->load( $bFromSlave );
102 $ipint = ip2long( $ip );
105 foreach ( $this->mData
as $networkBits => $blockInts ) {
106 if ( array_key_exists( $ipint >> ( 32 - $networkBits ), $blockInts ) ) {
112 # Clear low order bits
113 if ( $networkBits != 32 ) {
114 $ip .= '/'.$networkBits;
115 $ip = Block
::normaliseRange( $ip );
117 $block = new Block();
118 $block->forUpdate( $bFromSlave );
128 * Clear the local cache
129 * There was once a clear() to clear memcached too, but I deleted it
131 function clearLocal() {
132 $this->mData
= false;
137 * Add a block to the global $wgBlockCache
139 * @param Object $block A "Block"-object
140 * @param Any $tag unused
142 function wfBlockCacheInsert( $block, $tag ) {
143 global $wgBlockCache;
144 $wgBlockCache->insert( $block );