Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Philipp Frischmuth committed Jul 9, 2012
2 parents dd2613a + ce8bb2b commit b9b4c0a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 91 deletions.
38 changes: 7 additions & 31 deletions library/Erfurt/Sparql/Query2/GroupGraphPattern.php
Expand Up @@ -218,8 +218,8 @@ public function addElements($elements) {
* optimize
* little demo of optimization:
* - delete duplicate elements (object identity or syntactically equality)
* - sort by weight (number of vars used). slightly related to "Bernstein, OptARQ: A SPARQL Optimization Approach based on
Triple Pattern Selectivity Estimation, 2007"
* - sort by weight (number of vars used). slightly related to:
* "Bernstein, OptARQ: A SPARQL Optimization Approach based on Triple Pattern Selectivity Estimation, 2007"
*
* TODO: implement a sophisticated semantic equality check
* @return Erfurt_Sparql_Query2_GroupGraphPattern $this
Expand All @@ -239,35 +239,11 @@ public function optimize() {
$to_remove[] = $this->elements[$i];

//cant delete one without deleting both - need to copy first
if ($this->elements[$j] instanceof Erfurt_Sparql_Query2_ContainerHelper) {
$copy = $this->elements[$j];
$classname = get_class($this->elements[$j]);
$this->elements[$j] = new $classname;
$this->elements[$j]->setElements($copy->getElements());
} else if ($this->elements[$j] instanceof Erfurt_Sparql_Query2_Triple) {
$this->elements[$j] =
new Erfurt_Sparql_Query2_Triple(
$this->elements[$j]->getS(),
$this->elements[$j]->getP(),
$this->elements[$j]->getO()
);
} else if (
$this->elements[$j] instanceof Erfurt_Sparql_Query2_TriplesSameSubject
) {
$this->elements[$j] =
new Erfurt_Sparql_Query2_TriplesSameSubject(
$this->elements[$j]->getSubject(),
$this->elements[$j]->getPropList()
);
}
continue; //why continue
//TODO cover all cases - cant be generic?!
} else if ($this->elements[$i]->equals($this->elements[$j])
&& $this->elements[$i] != $this->elements[$j]) {
$this->elements[$j] = unserialize(serialize($this->elements[$j]));
} else if ($this->elements[$i]->equals($this->elements[$j])) {
//they are syntactically equal

//if the j of this i-j-pair is already
//marked for deletion: skip i
//if the j of this i-j-pair is already marked for deletion: skip i
if (!in_array($this->elements[$j], $to_remove)) {
$to_remove[] = $this->elements[$i];
}
Expand All @@ -280,15 +256,15 @@ public function optimize() {
}

//sort triples by weight
usort($this->elements, array("Erfurt_Sparql_Query2_TriplesSameSubject", "compareWeight"));
usort($this->elements, array('Erfurt_Sparql_Query2_TriplesSameSubject', 'compareWeight'));

//optimization is done on this level - proceed on deeper level
foreach ($this->elements as $element) {
if ($element instanceof Erfurt_Sparql_Query2_GroupGraphPattern) {
$element->optimize();
}
}

return $this;
}

Expand Down
30 changes: 11 additions & 19 deletions library/Erfurt/Sparql/Query2/TriplesSameSubject.php
Expand Up @@ -92,7 +92,6 @@ public function getWeight($part = null){
switch($part){
case 0:
return ($this->subject instanceof Erfurt_Sparql_Query2_Var ? 1 : 0);
break;
case 1:
$i = 0;
foreach($this->propertyList as $prop){
Expand All @@ -109,11 +108,16 @@ public function getWeight($part = null){
}
}
return $i;
break;
}
}
}

/**
* like strcmp for graph pattern elements
* @param type $c1
* @param type $c2
* @return int
*/
public static function compareWeight($c1, $c2){
switch(true){
case $c1 instanceof Erfurt_Sparql_Query2_IF_TriplesSameSubject:
Expand All @@ -138,25 +142,13 @@ public static function compareWeight($c1, $c2){
break;
}
if (!($c1 instanceof Erfurt_Sparql_Query2_IF_TriplesSameSubject && $c2 instanceof Erfurt_Sparql_Query2_IF_TriplesSameSubject)) {
return $c1weight - $c2weight;
$cmp = $c1weight - $c2weight;
return $cmp != 0 ? $cmp : strcmp((string)$c1, (string)$c2); //to avoid 0
}

//both are normal triples
$res = $c1->getWeight() - $c2->getWeight();
switch ($res){
case $res == 0:
// go deeper

break;
case $res < 0:
$ret = -1;
break;
case $res > 0:
$ret = 1;
break;
}

return $ret;
$cmp = $c1->getWeight() - $c2->getWeight();
return $cmp != 0 ? $cmp : strcmp((string)$c1, (string)$c2);
}
}
?>

65 changes: 38 additions & 27 deletions library/Erfurt/Store.php
Expand Up @@ -1160,14 +1160,26 @@ function toStr($a){$s=''; foreach($a as $aa){$s.=' '.$aa['uri'];} return $s;}
*/
protected function _prepareQuery($queryObject, &$options = array())
{
/*
* clone the Query2 Object to not modify the original one
* could be used elsewhere, could have side-effects
*/
if ($queryObject instanceof Erfurt_Sparql_Query2) {
//always clone
//the query will be altered here to implement AC and owl:imports
//dont make these changes global
$queryObject = clone $queryObject;
//bring triples etc. to canonical order
$queryObject->optimize();
}

$defaultOptions = array(
Erfurt_Store::RESULTFORMAT => Erfurt_Store::RESULTFORMAT_PLAIN,
Erfurt_Store::USE_AC => true,
Erfurt_Store::USE_OWL_IMPORTS => true,
Erfurt_Store::USE_ADDITIONAL_IMPORTS => true
);
$options = array_merge($defaultOptions, $options);
$noBindings = false;

//typechecking
if (is_string($queryObject)) {
Expand All @@ -1181,18 +1193,14 @@ protected function _prepareQuery($queryObject, &$options = array())
}

if ($options[Erfurt_Store::USE_AC] == false) {
//we are done preparing early
return $queryObject;
}

/*
* clone the Query2 Object to not modify the original one
* could be used elsewhere, could have side-effects
*/
if ($queryObject instanceof Erfurt_Sparql_Query2) { //always clone?
$queryObject = clone $queryObject;
}

$logger = $this->_getQueryLogger();

$noBindings = false;

//get available models (readable)
$available = array();
if ($options[Erfurt_Store::USE_AC] === true) {
Expand Down Expand Up @@ -1298,8 +1306,17 @@ protected function _prepareQuery($queryObject, &$options = array())
$ggp->addFilter(false); //unsatisfiable
$queryObject->setWhere($ggp);
}
}
return $queryObject;
}

$replacements = 0;
$queryString = str_replace(
$this->_bnodePrefix,
$this->_backendAdapter->getBlankNodePrefix(),
(string)$queryObject,
$replacements
);

return $queryString;
}

/**
Expand All @@ -1309,21 +1326,21 @@ protected function _prepareQuery($queryObject, &$options = array())
* @param string $askSparql
* @param boolean $useAc Whether to check for access control.
*/
public function sparqlAsk($queryObject, $useAc = true)
public function sparqlAsk($queryObject, $options = array())
{
$options = array( Erfurt_Store::USE_AC => $useAc);
$queryObject = $this->_prepareQuery($queryObject, $options);
$queryString = $this->_prepareQuery($queryObject, $options);


//query from query cache
$queryCache = Erfurt_App::getInstance()->getQueryCache();
$sparqlResult = $queryCache->load((string) $queryObject, 'plain');
$sparqlResult = $queryCache->load($queryString, 'plain');
if ($sparqlResult == Erfurt_Cache_Frontend_QueryCache::ERFURT_CACHE_NO_HIT) {
// TODO: check if adapter supports requested result format
$startTime = microtime(true);
$sparqlResult = $this->_backendAdapter->sparqlAsk((string) $queryObject);
$sparqlResult = $this->_backendAdapter->sparqlAsk($queryString);
self::$_queryCount++;
$duration = microtime(true) - $startTime;
$queryCache->save((string) $queryObject, 'plain', $sparqlResult, $duration);
$queryCache->save($queryString, 'plain', $sparqlResult, $duration);
}

return $sparqlResult;
Expand All @@ -1342,19 +1359,13 @@ public function sparqlQuery($queryObject, $options = array())
$logger = $this->_getQueryLogger();

$logger->debug('query in: '.(string)$queryObject);
$queryObject = $this->_prepareQuery($queryObject, $options);
$queryString = $this->_prepareQuery($queryObject, $options);
//dont use the query object afterwards anymore - only the string

//querying SparqlEngine or retrieving Result from QueryCache
$resultFormat = $options[Erfurt_Store::RESULTFORMAT];
$queryCache = Erfurt_App::getInstance()->getQueryCache();

$replacements = 0;
$queryString = str_replace(
$this->_bnodePrefix,
$this->_backendAdapter->getBlankNodePrefix(),
(string)$queryObject,
$replacements
);
$logger->debug('query after rewriting: '.$queryString);
if (!isset($options[Erfurt_Store::USE_CACHE]) || $options[Erfurt_Store::USE_CACHE]) {
$sparqlResult = $queryCache->load($queryString, $resultFormat);
Expand Down Expand Up @@ -1417,7 +1428,7 @@ public function sparqlQuery($queryObject, $options = array())
}
}

$q = (string)$queryObject;
$q = $queryString;
$q = str_replace(PHP_EOL, ' ', $q);

$logger->debug(
Expand All @@ -1429,7 +1440,7 @@ public function sparqlQuery($queryObject, $options = array())
} else {
$logger->debug('cached');
}
$queryCache->save((string) $queryObject, $resultFormat, $sparqlResult, $duration);
$queryCache->save($queryString, $resultFormat, $sparqlResult, $duration);
}
return $sparqlResult;
}
Expand Down
25 changes: 11 additions & 14 deletions library/Erfurt/Store/Adapter/Sparql.php
Expand Up @@ -155,8 +155,6 @@ public function sparqlAsk($query)

public function sparqlQuery($query, $options=array())
{
//var_dump($query);exit;

// Make sure, we only query for configured graphs...
$q = Erfurt_Sparql_SimpleQuery::initWithString((string)$query);
$from = $q->getFrom();
Expand All @@ -166,21 +164,23 @@ public function sparqlQuery($query, $options=array())
$newFrom[] = $f;
}
}
//var_dump($this->_configuredGraphs, $from);exit;

if (count($newFrom) === 0) {
return array();
}
$q->setFrom($newFrom);


$resultform =(isset($options[Erfurt_Store::RESULTFORMAT]))?$options[Erfurt_Store::RESULTFORMAT]:Erfurt_Store::RESULTFORMAT_PLAIN;

$url = $this->_serviceUrl . '?query=' . urlencode((string)$q);

$client = Erfurt_App::getInstance()->getHttpClient($url, array(
'maxredirects' => 10,
'timeout' => 2000
));
$client = Erfurt_App::getInstance()->getHttpClient(
$url,
array(
'maxredirects' => 10,
'timeout' => 2000
)
);

if (null !== $this->_username) {
if (substr($url, 0, 7) === 'http://') {
Expand Down Expand Up @@ -244,13 +244,10 @@ protected function _parseSparqlXmlResults($sparqlXmlResults)

$result = array();
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($sparqlXmlResults);
$ret = @$xmlDoc->loadXML($sparqlXmlResults);

if ($xmlDoc === false) {
return array(
'head' => array(),
'results' => array('bindings' => array())
);
if ($ret === false) {
throw new OntoWiki_Exception('SPARQL store could not parse the xml result "'.htmlentities($sparqlXmlResults).'"');
}

$headElems = $xmlDoc->getElementsByTagName('head');
Expand Down

0 comments on commit b9b4c0a

Please sign in to comment.