2016-09-18 20:01:57 +08:00
|
|
|
/*=============================================================================
|
|
|
|
# Filename: GeneralEvaluation.cpp
|
|
|
|
# Author: Jiaqi, Chen
|
|
|
|
# Mail: chenjiaqi93@163.com
|
2017-07-14 16:42:47 +08:00
|
|
|
# Last Modified: 2017-05-05
|
2016-09-18 20:01:57 +08:00
|
|
|
# Description: implement functions in GeneralEvaluation.h
|
|
|
|
=============================================================================*/
|
|
|
|
|
|
|
|
#include "GeneralEvaluation.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2016-09-25 22:14:36 +08:00
|
|
|
bool GeneralEvaluation::parseQuery(const string &_query)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
this->query_parser.SPARQLParse(_query, this->query_tree);
|
|
|
|
}
|
|
|
|
catch(const char *e)
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("%s\n", e);
|
2016-09-25 22:14:36 +08:00
|
|
|
return false;
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2016-09-25 22:14:36 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTree& GeneralEvaluation::getQueryTree()
|
2016-09-18 20:01:57 +08:00
|
|
|
{
|
2016-09-25 22:14:36 +08:00
|
|
|
return this->query_tree;
|
|
|
|
}
|
2016-09-18 20:01:57 +08:00
|
|
|
|
2017-02-17 17:09:47 +08:00
|
|
|
bool GeneralEvaluation::doQuery()
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!this->query_tree.checkProjectionAsterisk() && this->query_tree.getProjection().empty())
|
2017-02-17 17:09:47 +08:00
|
|
|
return false;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->query_tree.getGroupPattern().getVarset();
|
2017-09-06 14:17:20 +08:00
|
|
|
this->query_tree.getGroupByVarset() = this->query_tree.getGroupByVarset() * this->query_tree.getGroupPattern().group_pattern_resultset_maximal_varset;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
if (this->query_tree.checkProjectionAsterisk() && this->query_tree.getProjection().empty() && !this->query_tree.getGroupByVarset().empty())
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("[ERROR] Select * and Group By can't appear at the same time.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this->query_tree.checkSelectAggregateFunctionGroupByValid())
|
|
|
|
{
|
|
|
|
printf("[ERROR] The vars/aggregate functions in the Select Clause are invalid.\n");
|
2017-02-17 17:09:47 +08:00
|
|
|
return false;
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
if (this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset.hasCommonVar(this->query_tree.getGroupPattern().group_pattern_predicate_maximal_varset))
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("[ERROR] There are some vars occur both in subject/object and predicate.\n");
|
2017-02-17 17:09:47 +08:00
|
|
|
return false;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2016-09-18 20:01:57 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
this->strategy = Strategy(this->kvstore, this->vstree, this->pre2num, this->limitID_predicate, this->limitID_literal, this->limitID_entity);
|
2017-01-16 14:12:57 +08:00
|
|
|
if (this->query_tree.checkWellDesigned())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("=================\n");
|
|
|
|
printf("||well-designed||\n");
|
|
|
|
printf("=================\n");
|
2016-09-18 20:01:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->rewriting_evaluation_stack.clear();
|
2017-07-27 15:58:51 +08:00
|
|
|
this->rewriting_evaluation_stack.push_back(EvaluationStackStruct());
|
2017-09-06 14:17:20 +08:00
|
|
|
this->rewriting_evaluation_stack.back().group_pattern = this->query_tree.getGroupPattern();
|
2017-07-27 15:58:51 +08:00
|
|
|
this->rewriting_evaluation_stack.back().sparql_query = NULL;
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result = this->rewritingBasedQueryEvaluation(0);
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
else
|
2016-09-18 20:01:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("=====================\n");
|
|
|
|
printf("||not well-designed||\n");
|
|
|
|
printf("=====================\n");
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result = this->semanticBasedQueryEvaluation(this->query_tree.getGroupPattern());
|
2016-09-18 20:01:57 +08:00
|
|
|
}
|
2017-02-17 17:09:47 +08:00
|
|
|
|
|
|
|
return true;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
TempResultSet* GeneralEvaluation::semanticBasedQueryEvaluation(QueryTree::GroupPattern &group_pattern)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-27 15:58:51 +08:00
|
|
|
TempResultSet *result = new TempResultSet();
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern.initPatternBlockid();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)group_pattern.sub_group_pattern.size(); i++)
|
|
|
|
if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int st = i;
|
2017-09-06 14:17:20 +08:00
|
|
|
while (st > 0 && (group_pattern.sub_group_pattern[st - 1].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type || group_pattern.sub_group_pattern[st - 1].type == QueryTree::GroupPattern::SubGroupPattern::Union_type))
|
2017-07-14 16:42:47 +08:00
|
|
|
st--;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int j = st; j < i; j++)
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.sub_group_pattern[i].pattern.subject_object_varset.hasCommonVar(group_pattern.sub_group_pattern[j].pattern.subject_object_varset))
|
|
|
|
group_pattern.mergePatternBlockID(i, j);
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
if (i + 1 == (int)group_pattern.sub_group_pattern.size() ||
|
|
|
|
(group_pattern.sub_group_pattern[i + 1].type != QueryTree::GroupPattern::SubGroupPattern::Pattern_type && group_pattern.sub_group_pattern[i + 1].type != QueryTree::GroupPattern::SubGroupPattern::Union_type))
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
SPARQLquery sparql_query;
|
|
|
|
vector<vector<string> > encode_varset;
|
2017-09-06 14:17:20 +08:00
|
|
|
vector<vector<QueryTree::GroupPattern::Pattern> > basic_query_handle;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int j = st; j <= i; j++)
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
if (!group_pattern.sub_group_pattern[j].pattern.varset.empty())
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.getRootPatternBlockID(j) == j) //root node
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
Varset occur;
|
2017-09-06 14:17:20 +08:00
|
|
|
vector<QueryTree::GroupPattern::Pattern> basic_query;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int k = st; k <= i; k++)
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.sub_group_pattern[k].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
if (group_pattern.getRootPatternBlockID(k) == j)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
occur += group_pattern.sub_group_pattern[k].pattern.varset;
|
|
|
|
basic_query.push_back(group_pattern.sub_group_pattern[k].pattern);
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("select vars: ");
|
|
|
|
occur.print();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
printf("triple patterns: \n");
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int k = 0; k < (int)basic_query.size(); k++)
|
|
|
|
printf("%s\t%s\t%s\n", basic_query[k].subject.value.c_str(),
|
|
|
|
basic_query[k].predicate.value.c_str(),
|
|
|
|
basic_query[k].object.value.c_str()
|
|
|
|
);
|
|
|
|
|
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
|
|
|
|
2017-09-07 17:17:27 +08:00
|
|
|
bool success = false;
|
|
|
|
if (this->query_cache != NULL)
|
|
|
|
{
|
|
|
|
long tv_bfcheck = Util::get_cur_time();
|
|
|
|
success = this->query_cache->checkCached(basic_query, occur, temp->results[0]);
|
|
|
|
long tv_afcheck = Util::get_cur_time();
|
|
|
|
printf("after checkCache, used %ld ms.\n", tv_afcheck - tv_bfcheck);
|
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
printf("QueryCache hit\n");
|
|
|
|
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
|
|
|
result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
|
|
|
|
|
|
|
result->release();
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("QueryCache miss\n");
|
|
|
|
|
|
|
|
sparql_query.addBasicQuery();
|
|
|
|
for (int k = 0; k < (int)basic_query.size(); k++)
|
|
|
|
sparql_query.addTriple(Triple(basic_query[k].subject.value,
|
|
|
|
basic_query[k].predicate.value,
|
|
|
|
basic_query[k].object.value));
|
|
|
|
|
|
|
|
encode_varset.push_back(occur.vars);
|
|
|
|
basic_query_handle.push_back(basic_query);
|
|
|
|
}
|
|
|
|
|
|
|
|
temp->release();
|
|
|
|
delete temp;
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
long tv_begin = Util::get_cur_time();
|
|
|
|
sparql_query.encodeQuery(this->kvstore, encode_varset);
|
|
|
|
long tv_encode = Util::get_cur_time();
|
|
|
|
printf("after Encode, used %ld ms.\n", tv_encode - tv_begin);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->strategy.handle(sparql_query);
|
|
|
|
long tv_handle = Util::get_cur_time();
|
|
|
|
printf("after Handle, used %ld ms.\n", tv_handle - tv_encode);
|
|
|
|
|
|
|
|
//collect and join the result of each BasicQuery
|
|
|
|
for (int j = 0; j < sparql_query.getBasicQueryNum(); j++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
|
|
|
|
|
|
|
temp->results[0].id_varset = Varset(encode_varset[j]);
|
|
|
|
int varnum = (int)encode_varset[j].size();
|
|
|
|
|
|
|
|
vector<unsigned*> &basicquery_result = sparql_query.getBasicQuery(j).getResultList();
|
|
|
|
int basicquery_result_num = (int)basicquery_result.size();
|
|
|
|
|
|
|
|
temp->results[0].result.reserve(basicquery_result_num);
|
|
|
|
for (int k = 0; k < basicquery_result_num; k++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
unsigned *v = new unsigned [varnum];
|
|
|
|
memcpy(v, basicquery_result[k], sizeof(int) * varnum);
|
|
|
|
temp->results[0].result.push_back(TempResult::ResultPair());
|
|
|
|
temp->results[0].result.back().id = v;
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
if (this->query_cache != NULL)
|
|
|
|
{
|
|
|
|
//if unconnected, time is incorrect
|
|
|
|
int time = tv_handle - tv_begin;
|
|
|
|
|
|
|
|
long tv_bftry = Util::get_cur_time();
|
|
|
|
bool success = this->query_cache->tryCaching(basic_query_handle[j], temp->results[0], time);
|
|
|
|
if (success) printf("QueryCache cached\n");
|
|
|
|
else printf("QueryCache didn't cache\n");
|
|
|
|
long tv_aftry = Util::get_cur_time();
|
|
|
|
printf("after tryCache, used %ld ms.\n", tv_aftry - tv_bftry);
|
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (result->results.empty())
|
|
|
|
{
|
|
|
|
delete result;
|
|
|
|
result = temp;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
temp->release();
|
|
|
|
result->release();
|
|
|
|
delete temp;
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
else if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Union_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *sub_result = new TempResultSet();
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern.sub_group_pattern[i].unions.size(); j++)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
TempResultSet *temp = semanticBasedQueryEvaluation(group_pattern.sub_group_pattern[i].unions[j]);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
if (sub_result->results.empty())
|
|
|
|
{
|
|
|
|
delete sub_result;
|
|
|
|
sub_result = temp;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_result = new TempResultSet();
|
|
|
|
sub_result->doUnion(*temp, *new_result);
|
|
|
|
|
|
|
|
temp->release();
|
|
|
|
sub_result->release();
|
|
|
|
delete temp;
|
|
|
|
delete sub_result;
|
|
|
|
|
|
|
|
sub_result = new_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
if (result->results.empty())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
delete result;
|
|
|
|
result = sub_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
result->doJoin(*sub_result, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result->release();
|
|
|
|
result->release();
|
|
|
|
delete sub_result;
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
else if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Optional_type || group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Minus_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
TempResultSet *temp = semanticBasedQueryEvaluation(group_pattern.sub_group_pattern[i].optional);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Optional_type)
|
|
|
|
result->doOptional(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
|
|
|
else if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Minus_type)
|
|
|
|
result->doMinus(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
temp->release();
|
|
|
|
result->release();
|
|
|
|
delete temp;
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
}
|
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
else if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Filter_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
result->doFilter(group_pattern.sub_group_pattern[i].filter.root, *new_result, this->stringindex, group_pattern.group_pattern_subject_object_maximal_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
result->release();
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
else if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Bind_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
temp->results[0].str_varset = group_pattern.sub_group_pattern[i].bind.varset;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
temp->results[0].result.push_back(TempResult::ResultPair());
|
2017-09-06 14:17:20 +08:00
|
|
|
temp->results[0].result[0].str.push_back(group_pattern.sub_group_pattern[i].bind.str);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
temp->release();
|
|
|
|
result->release();
|
|
|
|
delete temp;
|
|
|
|
delete result;
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
bool GeneralEvaluation::expanseFirstOuterUnionGroupPattern(QueryTree::GroupPattern &group_pattern, deque<QueryTree::GroupPattern> &queue)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int first_union_pos = -1;
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)group_pattern.sub_group_pattern.size(); i++)
|
|
|
|
if (group_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Union_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
first_union_pos = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (first_union_pos == -1)
|
|
|
|
return false;
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)group_pattern.sub_group_pattern[first_union_pos].unions.size(); i++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
QueryTree::GroupPattern new_group_pattern;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
for (int j = 0; j < first_union_pos; j++)
|
2017-09-06 14:17:20 +08:00
|
|
|
new_group_pattern.sub_group_pattern.push_back(group_pattern.sub_group_pattern[j]);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern.sub_group_pattern[first_union_pos].unions[i].sub_group_pattern.size(); j++)
|
|
|
|
new_group_pattern.sub_group_pattern.push_back(group_pattern.sub_group_pattern[first_union_pos].unions[i].sub_group_pattern[j]);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = first_union_pos + 1; j < (int)group_pattern.sub_group_pattern.size(); j++)
|
|
|
|
new_group_pattern.sub_group_pattern.push_back(group_pattern.sub_group_pattern[j]);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
queue.push_back(new_group_pattern);
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
TempResultSet* GeneralEvaluation::rewritingBasedQueryEvaluation(int dep)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2016-09-25 22:14:36 +08:00
|
|
|
deque<QueryTree::GroupPattern> queue;
|
2017-09-06 14:17:20 +08:00
|
|
|
queue.push_back(this->rewriting_evaluation_stack[dep].group_pattern);
|
|
|
|
vector<QueryTree::GroupPattern> group_pattern_union;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
|
|
|
while (!queue.empty())
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!this->expanseFirstOuterUnionGroupPattern(queue.front(), queue))
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern_union.push_back(queue.front());
|
2016-09-25 22:14:36 +08:00
|
|
|
queue.pop_front();
|
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *result = new TempResultSet();
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)group_pattern_union.size(); i++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
this->rewriting_evaluation_stack[dep].group_pattern = group_pattern_union[i];
|
|
|
|
QueryTree::GroupPattern *group_pattern = &this->rewriting_evaluation_stack[dep].group_pattern;
|
|
|
|
group_pattern->getVarset();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
|
|
|
for (int j = 0; j < 80; j++) printf("="); printf("\n");
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern->print(dep);
|
2016-09-25 22:14:36 +08:00
|
|
|
for (int j = 0; j < 80; j++) printf("="); printf("\n");
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *sub_result = new TempResultSet();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
QueryTree::GroupPattern triple_pattern;
|
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
triple_pattern.addOnePattern(QueryTree::GroupPattern::Pattern(
|
|
|
|
QueryTree::GroupPattern::Pattern::Element(group_pattern->sub_group_pattern[j].pattern.subject.value),
|
|
|
|
QueryTree::GroupPattern::Pattern::Element(group_pattern->sub_group_pattern[j].pattern.predicate.value),
|
|
|
|
QueryTree::GroupPattern::Pattern::Element(group_pattern->sub_group_pattern[j].pattern.object.value)
|
2017-01-16 14:12:57 +08:00
|
|
|
));
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
|
|
|
|
triple_pattern.getVarset();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
//get useful varset
|
|
|
|
Varset useful = this->query_tree.getResultProjectionVarset() + this->query_tree.getGroupByVarset();
|
|
|
|
if (!this->query_tree.checkProjectionAsterisk())
|
|
|
|
{
|
|
|
|
for (int j = 0; j < dep; j++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
QueryTree::GroupPattern &parrent_group_pattern = this->rewriting_evaluation_stack[j].group_pattern;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int k = 0; k < (int)parrent_group_pattern.sub_group_pattern.size(); k++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (parrent_group_pattern.sub_group_pattern[k].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
useful += parrent_group_pattern.sub_group_pattern[k].pattern.varset;
|
|
|
|
else if (parrent_group_pattern.sub_group_pattern[k].type == QueryTree::GroupPattern::SubGroupPattern::Filter_type)
|
|
|
|
useful += parrent_group_pattern.sub_group_pattern[k].filter.varset;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Optional_type)
|
|
|
|
useful += group_pattern->sub_group_pattern[j].optional.group_pattern_resultset_maximal_varset;
|
|
|
|
else if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Filter_type)
|
|
|
|
useful += group_pattern->sub_group_pattern[j].filter.varset;
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-27 15:58:51 +08:00
|
|
|
this->rewriting_evaluation_stack[dep].sparql_query = new SPARQLquery();
|
|
|
|
this->rewriting_evaluation_stack[dep].encode_varset.clear();
|
2017-09-06 14:17:20 +08:00
|
|
|
vector<vector<QueryTree::GroupPattern::Pattern> > basic_query_handle;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
//get connected block
|
2017-09-06 14:17:20 +08:00
|
|
|
triple_pattern.initPatternBlockid();
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)triple_pattern.sub_group_pattern.size(); j++)
|
|
|
|
if (triple_pattern.sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int k = 0; k < j; k++)
|
2017-09-06 14:17:20 +08:00
|
|
|
if (triple_pattern.sub_group_pattern[k].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
if (triple_pattern.sub_group_pattern[j].pattern.subject_object_varset.hasCommonVar(triple_pattern.sub_group_pattern[k].pattern.subject_object_varset))
|
|
|
|
triple_pattern.mergePatternBlockID(j, k);
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
//each connected block is a BasicQuery
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)triple_pattern.sub_group_pattern.size(); j++)
|
|
|
|
if (triple_pattern.sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
if (triple_pattern.getRootPatternBlockID(j) == j)
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
Varset occur;
|
2017-09-06 14:17:20 +08:00
|
|
|
vector<QueryTree::GroupPattern::Pattern> basic_query;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int k = 0; k < (int)triple_pattern.sub_group_pattern.size(); k++)
|
|
|
|
if (triple_pattern.sub_group_pattern[k].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
|
|
|
if (triple_pattern.getRootPatternBlockID(k) == j)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
occur += triple_pattern.sub_group_pattern[k].pattern.varset;
|
|
|
|
basic_query.push_back(triple_pattern.sub_group_pattern[k].pattern);
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
|
|
|
//reduce return result vars
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!this->query_tree.checkProjectionAsterisk() && useful.hasCommonVar(occur))
|
|
|
|
useful = useful * occur;
|
|
|
|
else
|
|
|
|
useful = occur;
|
|
|
|
|
2017-01-16 14:12:57 +08:00
|
|
|
printf("select vars: ");
|
2017-07-14 16:42:47 +08:00
|
|
|
useful.print();
|
2017-01-16 14:12:57 +08:00
|
|
|
|
|
|
|
printf("triple patterns: \n");
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int k = 0; k < (int)basic_query.size(); k++)
|
|
|
|
printf("%s\t%s\t%s\n", basic_query[k].subject.value.c_str(),
|
|
|
|
basic_query[k].predicate.value.c_str(),
|
|
|
|
basic_query[k].object.value.c_str()
|
|
|
|
);
|
|
|
|
|
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
|
|
|
|
2017-09-07 17:17:27 +08:00
|
|
|
bool success = false;
|
|
|
|
if (this->query_cache != NULL && dep == 0)
|
|
|
|
{
|
|
|
|
long tv_bfcheck = Util::get_cur_time();
|
|
|
|
success = this->query_cache->checkCached(basic_query, useful, temp->results[0]);
|
|
|
|
long tv_afcheck = Util::get_cur_time();
|
|
|
|
printf("after checkCache, used %ld ms.\n", tv_afcheck - tv_bfcheck);
|
|
|
|
}
|
2017-09-06 14:17:20 +08:00
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
printf("QueryCache hit\n");
|
|
|
|
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
|
|
|
sub_result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
|
|
|
|
|
|
|
sub_result->release();
|
|
|
|
delete sub_result;
|
|
|
|
|
|
|
|
sub_result = new_result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-07 17:17:27 +08:00
|
|
|
if (dep == 0)
|
|
|
|
printf("QueryCache miss\n");
|
2017-09-06 14:17:20 +08:00
|
|
|
|
|
|
|
this->rewriting_evaluation_stack[dep].sparql_query->addBasicQuery();
|
|
|
|
for (int k = 0; k < (int)basic_query.size(); k++)
|
|
|
|
this->rewriting_evaluation_stack[dep].sparql_query->addTriple(Triple(basic_query[k].subject.value,
|
|
|
|
basic_query[k].predicate.value,
|
|
|
|
basic_query[k].object.value));
|
|
|
|
|
|
|
|
this->rewriting_evaluation_stack[dep].encode_varset.push_back(useful.vars);
|
|
|
|
basic_query_handle.push_back(basic_query);
|
|
|
|
}
|
|
|
|
|
|
|
|
temp->release();
|
|
|
|
delete temp;
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
long tv_begin = Util::get_cur_time();
|
2017-07-27 15:58:51 +08:00
|
|
|
this->rewriting_evaluation_stack[dep].sparql_query->encodeQuery(this->kvstore, this->rewriting_evaluation_stack[dep].encode_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
long tv_encode = Util::get_cur_time();
|
|
|
|
printf("after Encode, used %ld ms.\n", tv_encode - tv_begin);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (dep > 0)
|
2017-07-27 15:58:51 +08:00
|
|
|
{
|
|
|
|
SPARQLquery *this_sparql_query = this->rewriting_evaluation_stack[dep].sparql_query;
|
|
|
|
SPARQLquery *last_sparql_query = this->rewriting_evaluation_stack[dep - 1].sparql_query;
|
|
|
|
|
|
|
|
for (int j = 0; j < this_sparql_query->getBasicQueryNum(); j++)
|
|
|
|
{
|
|
|
|
BasicQuery &this_basic_query = this_sparql_query->getBasicQuery(j);
|
|
|
|
vector<string> &this_encode_varset = this->rewriting_evaluation_stack[dep].encode_varset[j];
|
|
|
|
|
|
|
|
for (int k = 0; k < last_sparql_query->getBasicQueryNum(); k++)
|
|
|
|
{
|
|
|
|
BasicQuery &last_basic_query = last_sparql_query->getBasicQuery(k);
|
|
|
|
vector<string> &last_encode_varset = this->rewriting_evaluation_stack[dep - 1].encode_varset[k];
|
|
|
|
|
|
|
|
for (int p = 0; p < (int)this_encode_varset.size(); p++)
|
|
|
|
{
|
|
|
|
for (int q = 0; q < (int)last_encode_varset.size(); q++)
|
|
|
|
if (this_encode_varset[p] == last_encode_varset[q])
|
|
|
|
{
|
|
|
|
vector<unsigned*> &result = last_basic_query.getResultList();
|
|
|
|
set<unsigned> result_set;
|
|
|
|
|
|
|
|
for (int l = 0; l < (int)result.size(); l++)
|
|
|
|
result_set.insert(result[l][q]);
|
|
|
|
|
|
|
|
vector<unsigned> result_vector;
|
|
|
|
result_vector.reserve(result_set.size());
|
|
|
|
|
|
|
|
for (set<unsigned>::iterator iter = result_set.begin(); iter != result_set.end(); iter++)
|
|
|
|
result_vector.push_back(*iter);
|
|
|
|
|
|
|
|
this_basic_query.getCandidateList(p).copy(result_vector);
|
|
|
|
this_basic_query.setReady(p);
|
|
|
|
|
|
|
|
printf("fill var %s CandidateList size %d\n", this_encode_varset[p].c_str(), (int)result_vector.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
long tv_fillcand = Util::get_cur_time();
|
|
|
|
printf("after FillCand, used %ld ms.\n", tv_fillcand - tv_encode);
|
|
|
|
|
|
|
|
this->strategy.handle(*this->rewriting_evaluation_stack[dep].sparql_query);
|
2017-07-14 16:42:47 +08:00
|
|
|
long tv_handle = Util::get_cur_time();
|
2017-07-27 15:58:51 +08:00
|
|
|
printf("after Handle, used %ld ms.\n", tv_handle - tv_fillcand);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
//collect and join the result of each BasicQuery
|
2017-07-27 15:58:51 +08:00
|
|
|
for (int j = 0; j < this->rewriting_evaluation_stack[dep].sparql_query->getBasicQueryNum(); j++)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-27 15:58:51 +08:00
|
|
|
temp->results[0].id_varset = Varset(this->rewriting_evaluation_stack[dep].encode_varset[j]);
|
|
|
|
int varnum = (int)this->rewriting_evaluation_stack[dep].encode_varset[j].size();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-27 15:58:51 +08:00
|
|
|
vector<unsigned*> &basicquery_result = this->rewriting_evaluation_stack[dep].sparql_query->getBasicQuery(j).getResultList();
|
2017-07-14 16:42:47 +08:00
|
|
|
int basicquery_result_num = (int)basicquery_result.size();
|
|
|
|
|
|
|
|
temp->results[0].result.reserve(basicquery_result_num);
|
|
|
|
for (int k = 0; k < basicquery_result_num; k++)
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
unsigned *v = new unsigned [varnum];
|
|
|
|
memcpy(v, basicquery_result[k], sizeof(int) * varnum);
|
|
|
|
temp->results[0].result.push_back(TempResult::ResultPair());
|
|
|
|
temp->results[0].result.back().id = v;
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-07 17:17:27 +08:00
|
|
|
if (this->query_cache != NULL && dep == 0)
|
2017-09-06 14:17:20 +08:00
|
|
|
{
|
|
|
|
//if unconnected, time is incorrect
|
|
|
|
int time = tv_handle - tv_begin;
|
|
|
|
|
|
|
|
long tv_bftry = Util::get_cur_time();
|
|
|
|
bool success = this->query_cache->tryCaching(basic_query_handle[j], temp->results[0], time);
|
|
|
|
if (success) printf("QueryCache cached\n");
|
|
|
|
else printf("QueryCache didn't cache\n");
|
|
|
|
long tv_aftry = Util::get_cur_time();
|
|
|
|
printf("after tryCache, used %ld ms.\n", tv_aftry - tv_bftry);
|
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (sub_result->results.empty())
|
|
|
|
{
|
|
|
|
delete sub_result;
|
|
|
|
sub_result = temp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
sub_result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
temp->release();
|
|
|
|
sub_result->release();
|
|
|
|
delete temp;
|
|
|
|
delete sub_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result = new_result;
|
|
|
|
}
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Bind_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *temp = new TempResultSet();
|
|
|
|
temp->results.push_back(TempResult());
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
temp->results[0].str_varset = group_pattern->sub_group_pattern[j].bind.varset;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
temp->results[0].result.push_back(TempResult::ResultPair());
|
2017-09-06 14:17:20 +08:00
|
|
|
temp->results[0].result[0].str.push_back(group_pattern->sub_group_pattern[j].bind.str);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
sub_result->doJoin(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
temp->release();
|
|
|
|
sub_result->release();
|
|
|
|
delete temp;
|
|
|
|
delete sub_result;
|
|
|
|
|
|
|
|
sub_result = new_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Filter_type)
|
|
|
|
if (!group_pattern->sub_group_pattern[j].filter.done && group_pattern->sub_group_pattern[j].filter.varset.belongTo(group_pattern->group_pattern_resultset_minimal_varset))
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern->sub_group_pattern[j].filter.done = true;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
sub_result->doFilter(group_pattern->sub_group_pattern[j].filter.root, *new_result, this->stringindex, group_pattern->group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result->release();
|
|
|
|
delete sub_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result = new_result;
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!sub_result->results[0].result.empty())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Optional_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if ((int)this->rewriting_evaluation_stack.size() == dep + 1)
|
|
|
|
{
|
2017-07-27 15:58:51 +08:00
|
|
|
this->rewriting_evaluation_stack.push_back(EvaluationStackStruct());
|
|
|
|
this->rewriting_evaluation_stack.back().sparql_query = NULL;
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern = &this->rewriting_evaluation_stack[dep].group_pattern;
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
this->rewriting_evaluation_stack[dep + 1].group_pattern = group_pattern->sub_group_pattern[j].optional;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
TempResultSet *temp = rewritingBasedQueryEvaluation(dep + 1);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
sub_result->doOptional(*temp, *new_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
|
|
|
temp->release();
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result->release();
|
2016-09-25 22:14:36 +08:00
|
|
|
delete temp;
|
2017-07-14 16:42:47 +08:00
|
|
|
delete sub_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result = new_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int j = 0; j < (int)group_pattern->sub_group_pattern.size(); j++)
|
|
|
|
if (group_pattern->sub_group_pattern[j].type == QueryTree::GroupPattern::SubGroupPattern::Filter_type)
|
|
|
|
if (!group_pattern->sub_group_pattern[j].filter.done)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
group_pattern->sub_group_pattern[j].filter.done = true;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_result = new TempResultSet();
|
2017-09-06 14:17:20 +08:00
|
|
|
sub_result->doFilter(group_pattern->sub_group_pattern[j].filter.root, *new_result, this->stringindex, group_pattern->group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result->release();
|
|
|
|
delete sub_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result = new_result;
|
|
|
|
}
|
2016-09-28 14:01:39 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (result->results.empty())
|
|
|
|
{
|
|
|
|
delete result;
|
|
|
|
result = sub_result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TempResultSet *new_result = new TempResultSet();
|
|
|
|
result->doUnion(*sub_result, *new_result);
|
2016-09-28 14:01:39 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
sub_result->release();
|
|
|
|
result->release();
|
|
|
|
delete sub_result;
|
|
|
|
delete result;
|
2016-09-28 14:01:39 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
result = new_result;
|
|
|
|
}
|
2017-07-27 15:58:51 +08:00
|
|
|
|
|
|
|
delete this->rewriting_evaluation_stack[dep].sparql_query;
|
|
|
|
this->rewriting_evaluation_stack[dep].sparql_query = NULL;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
return result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
void GeneralEvaluation::getFinalResult(ResultSet &ret_result)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (this->temp_result == NULL)
|
|
|
|
return;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
|
|
|
if (this->query_tree.getQueryForm() == QueryTree::Select_Query)
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
Varset useful = this->query_tree.getResultProjectionVarset() + this->query_tree.getGroupByVarset();
|
|
|
|
|
|
|
|
if (this->query_tree.checkProjectionAsterisk())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int i = 0 ; i < (int)this->temp_result->results.size(); i++)
|
|
|
|
useful += this->temp_result->results[i].getAllVarset();
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
TempResultSet *new_temp_result = new TempResultSet();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
this->temp_result->doProjection1(useful, *new_temp_result, this->stringindex, this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset);
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result->release();
|
|
|
|
delete this->temp_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result = new_temp_result;
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (this->query_tree.checkAtLeastOneAggregateFunction() || !this->query_tree.getGroupByVarset().empty())
|
|
|
|
{
|
|
|
|
vector<QueryTree::ProjectionVar> &proj = this->query_tree.getProjection();
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_temp_result = new TempResultSet();
|
|
|
|
new_temp_result->results.push_back(TempResult());
|
2016-09-18 20:01:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResult &result0 = this->temp_result->results[0];
|
|
|
|
TempResult &new_result0 = new_temp_result->results[0];
|
2016-09-18 20:01:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int i = 0; i < (int)proj.size(); i++)
|
|
|
|
if (proj[i].aggregate_type == QueryTree::ProjectionVar::None_type)
|
|
|
|
{
|
|
|
|
if (result0.id_varset.findVar(proj[i].var))
|
|
|
|
new_result0.id_varset.addVar(proj[i].var);
|
|
|
|
else if (result0.str_varset.findVar(proj[i].var))
|
|
|
|
new_result0.str_varset.addVar(proj[i].var);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
new_result0.str_varset.addVar(proj[i].var);
|
2017-02-28 20:32:01 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
vector<int> proj2temp((int)proj.size(), -1);
|
|
|
|
for (int i = 0; i < (int)proj.size(); i++)
|
|
|
|
if (proj[i].aggregate_type == QueryTree::ProjectionVar::None_type)
|
|
|
|
proj2temp[i] = Varset(proj[i].var).mapTo(result0.getAllVarset())[0];
|
|
|
|
else if (proj[i].aggregate_var != "*")
|
|
|
|
proj2temp[i] = Varset(proj[i].aggregate_var).mapTo(result0.getAllVarset())[0];
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
vector<int> proj2new = this->query_tree.getProjectionVarset().mapTo(new_result0.getAllVarset());
|
|
|
|
|
|
|
|
int result0_size = (int)result0.result.size();
|
|
|
|
vector<int> group2temp;
|
|
|
|
|
|
|
|
if (!this->query_tree.getGroupByVarset().empty())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
group2temp = this->query_tree.getGroupByVarset().mapTo(result0.getAllVarset());
|
|
|
|
result0.sort(0, result0_size - 1, group2temp);
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
TempResultSet *temp_result_distinct = NULL;
|
|
|
|
vector<int> group2distinct;
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)proj.size(); i++)
|
|
|
|
if (proj[i].aggregate_type == QueryTree::ProjectionVar::Count_type && proj[i].distinct && proj[i].aggregate_var == "*")
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
temp_result_distinct = new TempResultSet();
|
|
|
|
|
|
|
|
this->temp_result->doDistinct1(*temp_result_distinct);
|
|
|
|
group2distinct = this->query_tree.getGroupByVarset().mapTo(temp_result_distinct->results[0].getAllVarset());
|
|
|
|
temp_result_distinct->results[0].sort(0, (int)temp_result_distinct->results[0].result.size() - 1, group2distinct);
|
|
|
|
|
|
|
|
break;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
int result0_id_cols = result0.id_varset.getVarsetSize();
|
|
|
|
int new_result0_id_cols = new_result0.id_varset.getVarsetSize();
|
|
|
|
int new_result0_str_cols = new_result0.str_varset.getVarsetSize();
|
|
|
|
for (int begin = 0; begin < result0_size;)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int end;
|
|
|
|
if (group2temp.empty())
|
|
|
|
end = result0_size - 1;
|
|
|
|
else
|
|
|
|
end = result0.findRightBounder(group2temp, result0.result[begin], result0_id_cols, group2temp);
|
|
|
|
|
|
|
|
new_result0.result.push_back(TempResult::ResultPair());
|
|
|
|
new_result0.result.back().id = new unsigned [new_result0_id_cols];
|
|
|
|
new_result0.result.back().str.resize(new_result0_str_cols);
|
|
|
|
|
|
|
|
for (int i = 0; i < new_result0_id_cols; i++)
|
|
|
|
new_result0.result.back().id[i] = INVALID;
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)proj.size(); i++)
|
|
|
|
if (proj[i].aggregate_type == QueryTree::ProjectionVar::None_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (proj2temp[i] < result0_id_cols)
|
|
|
|
new_result0.result.back().id[proj2new[i]] = result0.result[begin].id[proj2temp[i]];
|
|
|
|
else
|
|
|
|
new_result0.result.back().str[proj2new[i] - new_result0_id_cols] = result0.result[begin].str[proj2temp[i] - result0_id_cols];
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
else if (proj[i].aggregate_type == QueryTree::ProjectionVar::Count_type)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int count = 0;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (proj[i].aggregate_var != "*")
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (proj[i].distinct)
|
|
|
|
{
|
|
|
|
if (proj2temp[i] < result0_id_cols)
|
|
|
|
{
|
|
|
|
set<int> count_set;
|
|
|
|
for (int j = begin; j <= end; j++)
|
|
|
|
if(result0.result[j].id[proj2temp[i]] != INVALID)
|
|
|
|
count_set.insert(result0.result[j].id[proj2temp[i]]);
|
|
|
|
count = (int)count_set.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
set<string> count_set;
|
|
|
|
for (int j = begin; j <= end; j++)
|
|
|
|
if (result0.result[j].str[proj2temp[i] - result0_id_cols].length() > 0)
|
|
|
|
count_set.insert(result0.result[j].str[proj2temp[i] - result0_id_cols]);
|
|
|
|
count = (int)count_set.size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (proj2temp[i] < result0_id_cols)
|
|
|
|
{
|
|
|
|
for (int j = begin; j <= end; j++)
|
|
|
|
if(result0.result[j].id[proj2temp[i]] != INVALID)
|
|
|
|
count++;
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
else
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
for (int j = begin; j <= end; j++)
|
|
|
|
if (result0.result[j].str[proj2temp[i] - result0_id_cols].length() > 0)
|
|
|
|
count++;
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
else
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (proj[i].distinct)
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
count = temp_result_distinct->results[0].findRightBounder(group2distinct, result0.result[begin], result0_id_cols, group2temp) -
|
|
|
|
temp_result_distinct->results[0].findLeftBounder(group2distinct, result0.result[begin], result0_id_cols, group2temp) + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count = end - begin + 1;
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
stringstream ss;
|
|
|
|
ss << "\"";
|
|
|
|
ss << count;
|
|
|
|
ss << "\"^^<http://www.w3.org/2001/XMLSchema#integer>";
|
|
|
|
ss >> new_result0.result.back().str[proj2new[i] - new_result0_id_cols];
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
begin = end + 1;
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
if (temp_result_distinct != NULL)
|
2017-01-16 14:12:57 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
temp_result_distinct->release();
|
|
|
|
delete temp_result_distinct;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
this->temp_result->release();
|
|
|
|
delete this->temp_result;
|
|
|
|
|
|
|
|
this->temp_result = new_temp_result;
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
//temp_result --> ret_result
|
|
|
|
|
|
|
|
if (this->query_tree.getProjectionModifier() == QueryTree::Modifier_Distinct)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResultSet *new_temp_result = new TempResultSet();
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result->doDistinct1(*new_temp_result);
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result->release();
|
|
|
|
delete this->temp_result;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result = new_temp_result;
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
TempResult &result0 = this->temp_result->results[0];
|
|
|
|
Varset ret_result_varset;
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (this->query_tree.checkProjectionAsterisk() && this->query_tree.getProjectionVarset().empty())
|
|
|
|
{
|
|
|
|
ret_result.select_var_num = result0.getAllVarset().getVarsetSize();
|
|
|
|
ret_result.setVar(result0.getAllVarset().vars);
|
|
|
|
ret_result_varset = result0.getAllVarset();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret_result.select_var_num = this->query_tree.getProjectionVarset().getVarsetSize();
|
|
|
|
ret_result.setVar(this->query_tree.getProjectionVarset().vars);
|
|
|
|
ret_result_varset = this->query_tree.getProjectionVarset();
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
ret_result.ansNum = (int)result0.result.size();
|
|
|
|
ret_result.setOutputOffsetLimit(this->query_tree.getOffset(), this->query_tree.getLimit());
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
#ifdef STREAM_ON
|
|
|
|
long long ret_result_size = (long long)ret_result.ansNum * (long long)ret_result.select_var_num * 100 / Util::GB;
|
|
|
|
if(Util::memoryLeft() < ret_result_size || !this->query_tree.getOrderVarVector().empty())
|
|
|
|
{
|
|
|
|
ret_result.setUseStream();
|
|
|
|
printf("set use Stream\n");
|
|
|
|
}
|
|
|
|
#endif
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!ret_result.checkUseStream())
|
|
|
|
{
|
|
|
|
ret_result.answer = new string* [ret_result.ansNum];
|
|
|
|
for (unsigned i = 0; i < ret_result.ansNum; i++)
|
|
|
|
ret_result.answer[i] = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector <unsigned> keys;
|
|
|
|
vector <bool> desc;
|
|
|
|
for (int i = 0; i < (int)this->query_tree.getOrderVarVector().size(); i++)
|
|
|
|
{
|
|
|
|
int var_id = Varset(this->query_tree.getOrderVarVector()[i].var).mapTo(ret_result_varset)[0];
|
|
|
|
if (var_id != -1)
|
|
|
|
{
|
|
|
|
keys.push_back(var_id);
|
|
|
|
desc.push_back(this->query_tree.getOrderVarVector()[i].descending);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret_result.openStream(keys, desc);
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
vector<int> proj2temp = ret_result_varset.mapTo(result0.getAllVarset());
|
|
|
|
int id_cols = result0.id_varset.getVarsetSize();
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (unsigned i = 0; i < ret_result.ansNum; i++)
|
|
|
|
{
|
|
|
|
if (!ret_result.checkUseStream())
|
|
|
|
{
|
|
|
|
ret_result.answer[i] = new string [ret_result.select_var_num];
|
|
|
|
}
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
for (int j = 0; j < ret_result.select_var_num; j++)
|
|
|
|
{
|
|
|
|
if (proj2temp[j] < id_cols)
|
|
|
|
{
|
|
|
|
unsigned ans_id = result0.result[i].id[proj2temp[j]];
|
2017-01-16 14:12:57 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!ret_result.checkUseStream())
|
|
|
|
{
|
|
|
|
ret_result.answer[i][j] = "";
|
|
|
|
if (ans_id != INVALID)
|
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset.findVar(result0.id_varset.vars[proj2temp[j]]))
|
2017-07-14 16:42:47 +08:00
|
|
|
this->stringindex->addRequest(ans_id, &ret_result.answer[i][j], true);
|
2017-01-16 14:12:57 +08:00
|
|
|
else
|
2017-07-14 16:42:47 +08:00
|
|
|
this->stringindex->addRequest(ans_id, &ret_result.answer[i][j], false);
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
string ans_str = "";
|
|
|
|
if (ans_id != INVALID)
|
|
|
|
{
|
2017-09-06 14:17:20 +08:00
|
|
|
if (this->query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset.findVar(result0.id_varset.vars[proj2temp[j]]))
|
2017-07-14 16:42:47 +08:00
|
|
|
this->stringindex->randomAccess(ans_id, &ans_str, true);
|
|
|
|
else
|
|
|
|
this->stringindex->randomAccess(ans_id, &ans_str, false);
|
|
|
|
}
|
|
|
|
ret_result.writeToStream(ans_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!ret_result.checkUseStream())
|
|
|
|
ret_result.answer[i][j] = result0.result[i].str[proj2temp[j] - id_cols];
|
|
|
|
else
|
|
|
|
ret_result.writeToStream(result0.result[i].str[proj2temp[j] - id_cols]);
|
2017-01-16 14:12:57 +08:00
|
|
|
}
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!ret_result.checkUseStream())
|
|
|
|
{
|
|
|
|
this->stringindex->trySequenceAccess();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret_result.resetStream();
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
else if (this->query_tree.getQueryForm() == QueryTree::Ask_Query)
|
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
ret_result.select_var_num = 1;
|
|
|
|
ret_result.setVar(vector<string>(1, "?__ask_retval"));
|
|
|
|
ret_result.ansNum = 1;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (!ret_result.checkUseStream())
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
ret_result.answer = new string* [ret_result.ansNum];
|
|
|
|
ret_result.answer[0] = new string[ret_result.select_var_num];
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
ret_result.answer[0][0] = "false";
|
|
|
|
for (int i = 0; i < (int)this->temp_result->results.size(); i++)
|
|
|
|
if (!this->temp_result->results[i].result.empty())
|
|
|
|
ret_result.answer[0][0] = "true";
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->releaseResult();
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
void GeneralEvaluation::releaseResult()
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
if (this->temp_result == NULL)
|
|
|
|
return;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
this->temp_result->release();
|
|
|
|
delete this->temp_result;
|
|
|
|
this->temp_result = NULL;
|
2016-09-18 20:01:57 +08:00
|
|
|
}
|
|
|
|
|
2017-03-25 20:08:23 +08:00
|
|
|
void GeneralEvaluation::prepareUpdateTriple(QueryTree::GroupPattern &update_pattern, TripleWithObjType *&update_triple, unsigned &update_triple_num)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
|
|
|
update_pattern.getVarset();
|
|
|
|
|
|
|
|
if (update_triple != NULL)
|
|
|
|
{
|
|
|
|
delete[] update_triple;
|
|
|
|
update_triple = NULL;
|
|
|
|
}
|
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (this->temp_result == NULL)
|
|
|
|
return;
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
update_triple_num = 0;
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)update_pattern.sub_group_pattern.size(); i++)
|
|
|
|
if (update_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
for (int j = 0 ; j < (int)this->temp_result->results.size(); j++)
|
2017-09-06 14:17:20 +08:00
|
|
|
if (update_pattern.sub_group_pattern[i].pattern.varset.belongTo(this->temp_result->results[j].getAllVarset()))
|
2017-07-14 16:42:47 +08:00
|
|
|
update_triple_num += this->temp_result->results[j].result.size();
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
|
|
|
update_triple = new TripleWithObjType[update_triple_num];
|
|
|
|
|
|
|
|
int update_triple_count = 0;
|
2017-09-06 14:17:20 +08:00
|
|
|
for (int i = 0; i < (int)update_pattern.sub_group_pattern.size(); i++)
|
|
|
|
if (update_pattern.sub_group_pattern[i].type == QueryTree::GroupPattern::SubGroupPattern::Pattern_type)
|
2017-07-14 16:42:47 +08:00
|
|
|
{
|
|
|
|
for (int j = 0 ; j < (int)this->temp_result->results.size(); j++)
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int id_cols = this->temp_result->results[j].id_varset.getVarsetSize();
|
|
|
|
|
2017-09-06 14:17:20 +08:00
|
|
|
if (update_pattern.sub_group_pattern[i].pattern.varset.belongTo(this->temp_result->results[j].getAllVarset()))
|
2016-09-25 22:14:36 +08:00
|
|
|
{
|
2017-07-14 16:42:47 +08:00
|
|
|
int subject_id = -1, predicate_id = -1, object_id = -1;
|
2017-09-06 14:17:20 +08:00
|
|
|
if (update_pattern.sub_group_pattern[i].pattern.subject.value[0] == '?')
|
|
|
|
subject_id = Varset(update_pattern.sub_group_pattern[i].pattern.subject.value).mapTo(this->temp_result->results[j].getAllVarset())[0];
|
|
|
|
if (update_pattern.sub_group_pattern[i].pattern.predicate.value[0] == '?')
|
|
|
|
predicate_id = Varset(update_pattern.sub_group_pattern[i].pattern.predicate.value).mapTo(this->temp_result->results[j].getAllVarset())[0];
|
|
|
|
if (update_pattern.sub_group_pattern[i].pattern.object.value[0] == '?')
|
|
|
|
object_id = Varset(update_pattern.sub_group_pattern[i].pattern.object.value).mapTo(this->temp_result->results[j].getAllVarset())[0];
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
string subject, predicate, object;
|
|
|
|
TripleWithObjType::ObjectType object_type;
|
|
|
|
|
|
|
|
if (subject_id == -1)
|
2017-09-06 14:17:20 +08:00
|
|
|
subject = update_pattern.sub_group_pattern[i].pattern.subject.value;
|
2017-07-14 16:42:47 +08:00
|
|
|
if (predicate_id == -1)
|
2017-09-06 14:17:20 +08:00
|
|
|
predicate = update_pattern.sub_group_pattern[i].pattern.predicate.value;
|
2017-07-14 16:42:47 +08:00
|
|
|
if (object_id == -1)
|
2017-09-06 14:17:20 +08:00
|
|
|
object = update_pattern.sub_group_pattern[i].pattern.object.value;
|
2017-07-14 16:42:47 +08:00
|
|
|
|
|
|
|
for (int k = 0; k < (int)this->temp_result->results[j].result.size(); k++)
|
|
|
|
{
|
|
|
|
if (subject_id != -1)
|
|
|
|
{
|
|
|
|
if (subject_id < id_cols)
|
|
|
|
this->stringindex->randomAccess(this->temp_result->results[j].result[k].id[subject_id], &subject, true);
|
|
|
|
else
|
|
|
|
subject = this->temp_result->results[j].result[k].str[subject_id - id_cols];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (predicate_id != -1)
|
|
|
|
{
|
|
|
|
if (predicate_id < id_cols)
|
|
|
|
this->stringindex->randomAccess(this->temp_result->results[j].result[k].id[predicate_id], &predicate, false);
|
|
|
|
else
|
|
|
|
predicate = this->temp_result->results[j].result[k].str[predicate_id - id_cols];
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
|
2017-07-14 16:42:47 +08:00
|
|
|
if (object_id != -1)
|
|
|
|
{
|
|
|
|
if (object_id < id_cols)
|
|
|
|
this->stringindex->randomAccess(this->temp_result->results[j].result[k].id[object_id], &object, true);
|
|
|
|
else
|
|
|
|
object = this->temp_result->results[j].result[k].str[object_id - id_cols];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (object[0] == '<')
|
|
|
|
object_type = TripleWithObjType::Entity;
|
|
|
|
else
|
|
|
|
object_type = TripleWithObjType::Literal;
|
|
|
|
|
|
|
|
update_triple[update_triple_count++] = TripleWithObjType(subject, predicate, object, object_type);
|
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-14 16:42:47 +08:00
|
|
|
}
|
2016-09-25 22:14:36 +08:00
|
|
|
}
|