public function has($value) { $hashes = $this->_hashes($value); if (function_exists('gmp_testbit')) { foreach ($hashes as $hash) { if (!gmp_testbit($this->_gmp, $hash)) { return false; } } } else { foreach ($hashes as $hash) { if (gmp_scan1($this->_gmp, $hash) !== $hash) { return false; } } } return true; }
/** * Scan the blobs table for rows not registered in blob_tracking (and thus not * registered in the text table). * * Orphan blobs are indicative of DB corruption. They are inaccessible and * should probably be deleted. */ function findOrphanBlobs() { if (!extension_loaded('gmp')) { echo "Can't find orphan blobs, need bitfield support provided by GMP.\n"; return; } $dbw = wfGetDB(DB_MASTER); foreach ($this->clusters as $cluster) { echo "Searching for orphan blobs in {$cluster}...\n"; $lb = wfGetLBFactory()->getExternalLB($cluster); try { $extDB = $lb->getConnection(DB_SLAVE); } catch (DBConnectionError $e) { if (strpos($e->error, 'Unknown database') !== false) { echo "No database on {$cluster}\n"; } else { echo "Error on {$cluster}: " . $e->getMessage() . "\n"; } continue; } $table = $extDB->getLBInfo('blobs table'); if (is_null($table)) { $table = 'blobs'; } if (!$extDB->tableExists($table)) { echo "No blobs table on cluster {$cluster}\n"; continue; } $startId = 0; $batchesDone = 0; $actualBlobs = gmp_init(0); $endId = $extDB->selectField($table, 'MAX(blob_id)', false, __METHOD__); // Build a bitmap of actual blob rows while (true) { $res = $extDB->select($table, array('blob_id'), array('blob_id > ' . $extDB->addQuotes($startId)), __METHOD__, array('LIMIT' => $this->batchSize, 'ORDER BY' => 'blob_id')); if (!$res->numRows()) { break; } foreach ($res as $row) { gmp_setbit($actualBlobs, $row->blob_id); } $startId = $row->blob_id; ++$batchesDone; if ($batchesDone >= $this->reportingInterval) { $batchesDone = 0; echo "{$startId} / {$endId}\n"; } } // Find actual blobs that weren't tracked by the previous passes // This is a set-theoretic difference A \ B, or in bitwise terms, A & ~B $orphans = gmp_and($actualBlobs, gmp_com($this->trackedBlobs[$cluster])); // Traverse the orphan list $insertBatch = array(); $id = 0; $numOrphans = 0; while (true) { $id = gmp_scan1($orphans, $id); if ($id == -1) { break; } $insertBatch[] = array('bo_cluster' => $cluster, 'bo_blob_id' => $id); if (count($insertBatch) > $this->batchSize) { $dbw->insert('blob_orphans', $insertBatch, __METHOD__); $insertBatch = array(); } ++$id; ++$numOrphans; } if ($insertBatch) { $dbw->insert('blob_orphans', $insertBatch, __METHOD__); } echo "Found {$numOrphans} orphan(s) in {$cluster}\n"; } }
// definitely a prime // gmp_random -- not implemented // gmp_scan0 // "0" bit is found at position 3. index starts at 0 $s1 = gmp_init("10111", 2); echo gmp_scan0($s1, 0) . "\n"; // "0" bit is found at position 7. index starts at 5 $s2 = gmp_init("101110000", 2); echo gmp_scan0($s2, 5) . "\n"; // gmp_scan1 // "0" bit is found at position 3. index starts at 0 $s1 = gmp_init("01000", 2); echo gmp_scan1($s1, 0) . "\n"; // "0" bit is found at position 7. index starts at 5 $s2 = gmp_init("01000001111", 2); echo gmp_scan1($s2, 5) . "\n"; // gmp_setbit $a = gmp_init("2"); // echo gmp_strval($a), ' -> 0b', gmp_strval($a, 2), "\n"; gmp_setbit($a, 0); // 0b10 now becomes 0b11 echo gmp_strval($a), ' -> 0b', gmp_strval($a, 2), "\n"; $a = gmp_init("0xfd"); echo gmp_strval($a), ' -> 0b', gmp_strval($a, 2), "\n"; gmp_setbit($a, 1); // index starts at 0 echo gmp_strval($a), ' -> 0b', gmp_strval($a, 2), "\n"; $a = gmp_init("0xff"); echo gmp_strval($a), ' -> 0b', gmp_strval($a, 2), "\n"; gmp_setbit($a, 0, false);
<?php var_dump(gmp_scan1("434234", -10)); var_dump(gmp_scan1("434234", 1)); var_dump(gmp_scan1(4096, 0)); var_dump(gmp_scan1("1000000000", 5)); var_dump(gmp_scan1("1000000000", 200)); $n = gmp_init("24234527465274"); var_dump(gmp_scan1($n, 10)); var_dump(gmp_scan1(array(), 200)); var_dump(gmp_scan1(array())); var_dump(gmp_scan1()); echo "Done\n";