r25732 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r25731‎ | r25732 | r25733 >
Date:15:52, 10 September 2007
Author:mkroetzsch
Status:old
Tags:
Comment:
More efficient treatment of loops in category/property hierarchy, more efficient processing of disjunctions of
catgories.
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php
@@ -217,8 +217,11 @@
218218 $this->m_label = '';
219219 $this->m_curstring = $querystring;
220220 $this->m_sepstack = array();
221 - $setNS = true;
 221+ $setNS = false;
222222 $result = $this->getSubqueryDescription($setNS, $this->m_label);
 223+ if (!$setNS) { // add default namespaces if applicable
 224+ $result = $this->addDescription($result, $this->m_defaultns);
 225+ }
223226 wfProfileOut('SMWQueryParser::getQueryDescription (SMW)');
224227 return $result;
225228 }
@@ -252,7 +255,7 @@
253256 * "<q>...</q>". Recursively calls similar methods and returns NULL upon error.
254257 *
255258 * The call-by-ref parameter $setNS is a boolean. Its input specifies whether
256 - * the query should set the current default namespace if no namespace restricitons
 259+ * the query should set the current default namespace if no namespace restrictions
257260 * were given. If false, the calling super-query is happy to set the required
258261 * NS-restrictions by itself if needed. Otherwise the subquery has to impose the defaults.
259262 * This is so, since outermost queries and subqueries of disjunctions will have to set
@@ -380,8 +383,8 @@
381384 */
382385 protected function getLinkDescription(&$setNS, &$label) {
383386 // This method is called when we encountered an opening '[['. The following
384 - // block could be a Category-statement, fixed object, relation or attribute
385 - // statements, or according print statements.
 387+ // block could be a Category-statement, fixed object, property statements,
 388+ // or according print statements.
386389 $chunk = $this->readChunk();
387390 if ($chunk == $this->m_categoryprefix) { // category statement
388391 return $this->getCategoryDescription($setNS, $label);
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php
@@ -1220,19 +1220,30 @@
12211221 * Make a (temporary) table that contains the lower closure of the given category
12221222 * wrt. the category table.
12231223 */
1224 - protected function getCategoryTable($catname, &$db) {
 1224+ protected function getCategoryTable($cats, &$db) {
12251225 wfProfileIn("SMWSQLStore::getCategoryTable (SMW)");
12261226 global $wgDBname, $smwgQSubcategoryDepth;
12271227
 1228+ $sqlvalues = '';
 1229+ $hashkey = '';
 1230+ foreach ($cats as $cat) {
 1231+ if ($sqlvalues != '') {
 1232+ $sqlvalues .= ', ';
 1233+ }
 1234+ $sqlvalues .= '(' . $db->addQuotes($cat->getDBKey()) . ')';
 1235+ $hashkey .= ']' . $cat->getDBKey();
 1236+ }
 1237+
12281238 $tablename = 'cats' . SMWSQLStore::$m_tablenum++;
12291239 $this->m_usedtables[] = $tablename;
12301240 $db->query( 'CREATE TEMPORARY TABLE ' . $tablename .
12311241 '( title VARCHAR(255) NOT NULL )
12321242 TYPE=MEMORY', 'SMW::getCategoryTable' );
1233 - if (array_key_exists($catname, SMWSQLStore::$m_categorytables)) { // just copy known result
 1243+ $db->query( 'ALTER TABLE ' . $tablename . ' ADD PRIMARY KEY ( title )' );
 1244+ if (array_key_exists($hashkey, SMWSQLStore::$m_categorytables)) { // just copy known result
12341245 $db->query("INSERT INTO $tablename (title) SELECT " .
1235 - SMWSQLStore::$m_categorytables[$catname] .
1236 - '.title FROM ' . SMWSQLStore::$m_categorytables[$catname],
 1246+ SMWSQLStore::$m_categorytables[$hashkey] .
 1247+ '.title FROM ' . SMWSQLStore::$m_categorytables[$hashkey],
12371248 'SMW::getCategoryTable');
12381249 wfProfileOut("SMWSQLStore::getCategoryTable (SMW)");
12391250 return $tablename;
@@ -1250,8 +1261,8 @@
12511262
12521263 $pagetable = $db->tableName('page');
12531264 $cltable = $db->tableName('categorylinks');
1254 - $db->query("INSERT INTO $tablename (title) VALUES (" . $db->addQuotes($catname) . ')', 'SMW::getCategoryTable');
1255 - $db->query("INSERT INTO $tmpnew (title) VALUES (" . $db->addQuotes($catname) . ')', 'SMW::getCategoryTable');
 1265+ $db->query("INSERT INTO $tablename (title) VALUES " . $sqlvalues, 'SMW::getCategoryTable');
 1266+ $db->query("INSERT INTO $tmpnew (title) VALUES " . $sqlvalues, 'SMW::getCategoryTable');
12561267
12571268 /// TODO: avoid duplicate results?
12581269 for ($i=0; $i<$smwgQSubcategoryDepth; $i++) {
@@ -1260,18 +1271,18 @@
12611272 $cltable.cl_to=$tmpnew.title AND
12621273 $pagetable.page_namespace=" . NS_CATEGORY . " AND
12631274 $pagetable.page_id=$cltable.cl_from", 'SMW::getCategoryTable');
 1275+ $db->query("INSERT IGNORE INTO $tablename (title) SELECT $tmpres.title
 1276+ FROM $tmpres", 'SMW::getCategoryTable');
12641277 if ($db->affectedRows() == 0) { // no change, exit loop
12651278 continue;
12661279 }
1267 - $db->query("INSERT INTO $tablename (title) SELECT $tmpres.title
1268 - FROM $tmpres", 'SMW::getCategoryTable');
12691280 $db->query('TRUNCATE TABLE ' . $tmpnew, 'SMW::getCategoryTable'); // empty "new" table
12701281 $tmpname = $tmpnew;
12711282 $tmpnew = $tmpres;
12721283 $tmpres = $tmpname;
12731284 }
12741285
1275 - SMWSQLStore::$m_categorytables[$catname] = $tablename;
 1286+ SMWSQLStore::$m_categorytables[$hashkey] = $tablename;
12761287 $db->query('DROP TABLE smw_newcats', 'SMW::getCategoryTable');
12771288 $db->query('DROP TABLE smw_rescats', 'SMW::getCategoryTable');
12781289 wfProfileOut("SMWSQLStore::getCategoryTable (SMW)");
@@ -1291,6 +1302,7 @@
12921303 $db->query( 'CREATE TEMPORARY TABLE ' . $tablename .
12931304 '( title VARCHAR(255) NOT NULL )
12941305 TYPE=MEMORY', 'SMW::getPropertyTable' );
 1306+ $db->query( 'ALTER TABLE ' . $tablename . ' ADD PRIMARY KEY ( title )' );
12951307 if (array_key_exists($propname, SMWSQLStore::$m_propertytables)) { // just copy known result
12961308 $db->query("INSERT INTO $tablename (title) SELECT " .
12971309 SMWSQLStore::$m_propertytables[$propname] .
@@ -1322,8 +1334,11 @@
13231335 if ($db->affectedRows() == 0) { // no change, exit loop
13241336 continue;
13251337 }
1326 - $db->query("INSERT INTO $tablename (title) SELECT $tmpres.title
 1338+ $db->query("INSERT IGNORE INTO $tablename (title) SELECT $tmpres.title
13271339 FROM $tmpres", 'SMW::getCategoryTable');
 1340+ if ($db->affectedRows() == 0) { // no change, exit loop
 1341+ continue;
 1342+ }
13281343 $db->query('TRUNCATE TABLE ' . $tmpnew, 'SMW::getPropertyTable'); // empty "new" table
13291344 $tmpname = $tmpnew;
13301345 $tmpnew = $tmpres;
@@ -1531,11 +1546,16 @@
15321547 if ($table = $this->addJoin('CATS', $from, $db, $curtables, $nary_pos)) {
15331548 global $smwgQSubcategoryDepth;
15341549 if ($smwgQSubcategoryDepth > 0) {
1535 - $ct = $this->getCategoryTable($description->getCategory()->getDBKey(), $db);
 1550+ $ct = $this->getCategoryTable($description->getCategories(), $db);
15361551 $from = '`' . $ct . '`, ' . $from;
15371552 $where = "$ct.title=" . $table . '.cl_to';
15381553 } else {
1539 - $where .= $table . '.cl_to=' . $db->addQuotes($description->getCategory()->getDBKey());
 1554+ foreach ($description->getCategories() as $cat) {
 1555+ if ($subwhere != '') {
 1556+ $subwhere .= ' OR ';
 1557+ }
 1558+ $subwhere .= '(' . $table . '.cl_to=' . $db->addQuotes($description->getCategories()->getDBKey()) . ')';
 1559+ }
15401560 }
15411561 }
15421562 } elseif ($description instanceof SMWNamespaceDescription) {
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Description.php
@@ -229,32 +229,72 @@
230230 }
231231
232232 /**
233 - * Description of a single class, i.e. a wiki category.
234 - * Corresponds to atomic concepts in OWL and to classes in RDF.
 233+ * Description of a single class, i.e. a wiki category, or of a disjunction
 234+ * of such classes. Corresponds to (disjunctions of) atomic concepts in OWL and
 235+ * to (unions of) classes in RDF.
235236 */
236237 class SMWClassDescription extends SMWDescription {
237 - protected $m_title;
 238+ protected $m_titles;
238239
239 - public function SMWClassDescription(Title $category) {
240 - $this->m_title = $category;
 240+ public function SMWClassDescription($content) {
 241+ if ($content instanceof Title) {
 242+ $this->m_titles = array($content);
 243+ } elseif (is_array($content)) {
 244+ $this->m_titles = $content;
 245+ }
241246 }
242247
243 - public function getCategory() {
244 - return $this->m_title;
 248+ public function addDescription(SMWClassDescription $description) {
 249+ $this->m_titles = array_merge($this->m_titles, $description->getCategories());
245250 }
246251
 252+ public function getCategories() {
 253+ return $this->m_titles;
 254+ }
 255+
247256 public function getQueryString() {
248 - if ($this->m_title !== NULL) {
249 - return '[[' . $this->m_title->getPrefixedText() . ']]';
250 - } else {
251 - return '';
 257+ $first = true;
 258+ foreach ($this->m_titles as $cat) {
 259+ if ($first) {
 260+ $result = '[[' . $cat->getPrefixedText();
 261+ $first = false;
 262+ } else {
 263+ $result .= '||' . $cat->getText();
 264+ }
252265 }
 266+ return $result . ']]';
253267 }
254268
255269 public function isSingleton() {
256270 return false;
257271 }
258272
 273+ public function getSize() {
 274+ global $smwgQSubcategoryDepth;
 275+ if ($smwgQSubcategoryDepth > 0) {
 276+ return 1; // disj. of cats should not cause much effort if we compute cat-hierarchies anyway!
 277+ } else {
 278+ return count($this->m_titles);
 279+ }
 280+ }
 281+
 282+ public function prune(&$maxsize, &$maxdepth, &$log) {
 283+ if ($maxsize >= $this->getSize()) {
 284+ $maxsize = $maxsize - $this->getSize();
 285+ return $this;
 286+ } elseif ( $maxsize <= 0 ) {
 287+ $log[] = $this->getQueryString();
 288+ $result = new SMWThingDescription();
 289+ } else {
 290+ $result = new SMWClassDescription(array_slice($this->m_titles, 0, $maxsize));
 291+ $rest = new SMWClassDescription(array_slice($this->m_titles, $maxsize));
 292+ $log[] = $rest->getQueryString();
 293+ $maxsize = 0;
 294+ }
 295+ $result->setPrintRequests($this->getPrintRequests());
 296+ return $result;
 297+ }
 298+
259299 }
260300
261301 /**
@@ -352,8 +392,8 @@
353393 /**
354394 * Description of an ordered list of SMWDescription objects, used as
355395 * values for some n-ary property. NULL values are to be used for
356 - * Corresponds to the built-in support for n-ary properties, i.e.
357 - * can be viewed as a macro in OWL and RDF.
 396+ * unspecifed values. Corresponds to the built-in support for n-ary
 397+ * properties, i.e. can be viewed as a macro in OWL and RDF.
358398 */
359399 class SMWValueList extends SMWDescription {
360400 protected $m_descriptions;
@@ -556,6 +596,8 @@
557597 */
558598 class SMWDisjunction extends SMWDescription {
559599 protected $m_descriptions;
 600+ protected $m_classdesc = NULL; // contains a single class description if any such disjunct was given;
 601+ // disjunctive classes are aggregated therein
560602 protected $m_true = false; // used if disjunction is trivially true already
561603
562604 public function SMWDisjunction($descriptions = array()) {
@@ -572,9 +614,20 @@
573615 if ($description instanceof SMWThingDescription) {
574616 $this->m_true = true;
575617 $this->m_descriptions = array(); // no conditions any more
 618+ $this->m_catdesc = NULL;
576619 }
577620 if (!$this->m_true) {
578 - $this->m_descriptions[] = $description;
 621+ if ($description instanceof SMWClassDescription) {
 622+ if ($this->m_classdesc === NULL) { // first class description
 623+ $this->m_classdesc = $description;
 624+ $this->m_descriptions[] = $description;
 625+ } else {
 626+ $this->m_classdesc->addDescription($description);
 627+ }
 628+ } else {
 629+ $this->m_descriptions[] = $description;
 630+ }
 631+
579632 }
580633 }
581634
@@ -675,7 +728,7 @@
676729 }
677730
678731 public function getQueryString() {
679 - return '[[' . $this->m_property->getText() . ':=' . $this->m_description->getQueryString() . ']]';
 732+ return '[[' . $this->m_property->getText() . '::' . $this->m_description->getQueryString() . ']]';
680733 }
681734
682735 public function isSingleton() {

Status & tagging log