Parse tags first, then check accelerator, then check database
Better than half-assed tag parsing in the accelerator then full parsing in the database
This commit is contained in:
parent
44fcc3a1e9
commit
6b9d18b52e
1 changed files with 82 additions and 72 deletions
|
@ -125,13 +125,11 @@ class Image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = null;
|
list($tag_querylets, $img_querylets) = self::parse_all_terms($tags);
|
||||||
if (SEARCH_ACCEL) {
|
|
||||||
$result = Image::get_accelerated_result($tags, $start, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$result = Image::get_accelerated_result($tag_querylets, $img_querylets, $start, $limit);
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$querylet = Image::build_search_querylet($tags);
|
$querylet = Image::build_search_querylet($tag_querylets, $img_querylets);
|
||||||
$querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string("index_order"))));
|
$querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string("index_order"))));
|
||||||
$querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", ["limit"=>$limit, "offset"=>$start]));
|
$querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", ["limit"=>$limit, "offset"=>$start]));
|
||||||
#var_dump($querylet->sql); var_dump($querylet->variables);
|
#var_dump($querylet->sql); var_dump($querylet->variables);
|
||||||
|
@ -170,13 +168,11 @@ class Image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = null;
|
list($tag_querylets, $img_querylets) = self::parse_all_terms($tags);
|
||||||
if (SEARCH_ACCEL) {
|
|
||||||
$result = Image::get_accelerated_result($tags, $start, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$result = Image::get_accelerated_result($tag_querylets, $img_querylets, $start, $limit);
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$querylet = Image::build_search_querylet($tags);
|
$querylet = Image::build_search_querylet($tag_querylets, $img_querylets);
|
||||||
$querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string("index_order"))));
|
$querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string("index_order"))));
|
||||||
$querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", ["limit"=>$limit, "offset"=>$start]));
|
$querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", ["limit"=>$limit, "offset"=>$start]));
|
||||||
#var_dump($querylet->sql); var_dump($querylet->variables);
|
#var_dump($querylet->sql); var_dump($querylet->variables);
|
||||||
|
@ -193,7 +189,7 @@ class Image
|
||||||
/*
|
/*
|
||||||
* Accelerator stuff
|
* Accelerator stuff
|
||||||
*/
|
*/
|
||||||
public static function get_acceleratable(array $tags): ?array
|
public static function get_acceleratable(array $tag_querylets): ?array
|
||||||
{
|
{
|
||||||
$ret = [
|
$ret = [
|
||||||
"yays" => [],
|
"yays" => [],
|
||||||
|
@ -201,16 +197,13 @@ class Image
|
||||||
];
|
];
|
||||||
$yays = 0;
|
$yays = 0;
|
||||||
$nays = 0;
|
$nays = 0;
|
||||||
foreach ($tags as $tag) {
|
foreach ($tag_querylets as $tq) {
|
||||||
if (!preg_match("/^-?[a-zA-Z0-9_'-]+$/", $tag)) {
|
if ($tq->positive) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if ($tag[0] == "-") {
|
|
||||||
$nays++;
|
|
||||||
$ret["nays"][] = substr($tag, 1);
|
|
||||||
} else {
|
|
||||||
$yays++;
|
$yays++;
|
||||||
$ret["yays"][] = $tag;
|
$ret["yays"][] = $tq->tag;
|
||||||
|
} else {
|
||||||
|
$nays++;
|
||||||
|
$ret["nays"][] = $tq->tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($yays > 1 || $nays > 0) {
|
if ($yays > 1 || $nays > 0) {
|
||||||
|
@ -219,11 +212,15 @@ class Image
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get_accelerated_result(array $tags, int $offset, int $limit): ?PDOStatement
|
public static function get_accelerated_result(array $tag_querylets, array $img_querylets, int $offset, int $limit): ?PDOStatement
|
||||||
{
|
{
|
||||||
|
if (!SEARCH_ACCEL || !empty($img_querylets)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$req = Image::get_acceleratable($tags);
|
$req = Image::get_acceleratable($tag_querylets);
|
||||||
if (!$req) {
|
if (!$req) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -240,9 +237,13 @@ class Image
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get_accelerated_count(array $tags): ?int
|
public static function get_accelerated_count(array $tag_querylets, array $img_querylets): ?int
|
||||||
{
|
{
|
||||||
$req = Image::get_acceleratable($tags);
|
if (!SEARCH_ACCEL || !empty($img_querylets)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$req = Image::get_acceleratable($tag_querylets);
|
||||||
if (!$req) {
|
if (!$req) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -295,9 +296,10 @@ class Image
|
||||||
["tag"=>$tags[0]]
|
["tag"=>$tags[0]]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$total = Image::get_accelerated_count($tags);
|
list($tag_querylets, $img_querylets) = self::parse_all_terms($tags);
|
||||||
|
$total = Image::get_accelerated_count($tag_querylets, $img_querylets);
|
||||||
if (is_null($total)) {
|
if (is_null($total)) {
|
||||||
$querylet = Image::build_search_querylet($tags);
|
$querylet = Image::build_search_querylet($tag_querylets, $img_querylets);
|
||||||
$total = $database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables);
|
$total = $database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,6 +320,53 @@ class Image
|
||||||
return ceil(Image::count_images($tags) / $config->get_int('index_images'));
|
return ceil(Image::count_images($tags) / $config->get_int('index_images'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function parse_all_terms(array $terms): array
|
||||||
|
{
|
||||||
|
$tag_querylets = [];
|
||||||
|
$img_querylets = [];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn a bunch of strings into a bunch of TagQuerylet
|
||||||
|
* and ImgQuerylet objects
|
||||||
|
*/
|
||||||
|
$stpe = new SearchTermParseEvent(null, $terms);
|
||||||
|
send_event($stpe);
|
||||||
|
if ($stpe->is_querylet_set()) {
|
||||||
|
foreach ($stpe->get_querylets() as $querylet) {
|
||||||
|
$img_querylets[] = new ImgQuerylet($querylet, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($terms as $term) {
|
||||||
|
$positive = true;
|
||||||
|
if (is_string($term) && !empty($term) && ($term[0] == '-')) {
|
||||||
|
$positive = false;
|
||||||
|
$term = substr($term, 1);
|
||||||
|
}
|
||||||
|
if (strlen($term) === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stpe = new SearchTermParseEvent($term, $terms);
|
||||||
|
send_event($stpe);
|
||||||
|
if ($stpe->is_querylet_set()) {
|
||||||
|
foreach ($stpe->get_querylets() as $querylet) {
|
||||||
|
$img_querylets[] = new ImgQuerylet($querylet, $positive);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the whole match is wild, skip this;
|
||||||
|
// if not, translate into SQL
|
||||||
|
if (str_replace("*", "", $term) != "") {
|
||||||
|
$term = str_replace('_', '\_', $term);
|
||||||
|
$term = str_replace('%', '\%', $term);
|
||||||
|
$term = str_replace('*', '%', $term);
|
||||||
|
$tag_querylets[] = new TagQuerylet($term, $positive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [$tag_querylets, $img_querylets];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessors & mutators
|
* Accessors & mutators
|
||||||
*/
|
*/
|
||||||
|
@ -352,7 +401,8 @@ class Image
|
||||||
');
|
');
|
||||||
} else {
|
} else {
|
||||||
$tags[] = 'id'. $gtlt . $this->id;
|
$tags[] = 'id'. $gtlt . $this->id;
|
||||||
$querylet = Image::build_search_querylet($tags);
|
list($tag_querylets, $img_querylets) = self::parse_all_terms($tags);
|
||||||
|
$querylet = Image::build_search_querylet($tag_querylets, $img_querylets);
|
||||||
$querylet->append_sql(' ORDER BY images.id '.$dir.' LIMIT 1');
|
$querylet->append_sql(' ORDER BY images.id '.$dir.' LIMIT 1');
|
||||||
$row = $database->get_row($querylet->sql, $querylet->variables);
|
$row = $database->get_row($querylet->sql, $querylet->variables);
|
||||||
}
|
}
|
||||||
|
@ -813,57 +863,17 @@ class Image
|
||||||
/**
|
/**
|
||||||
* #param string[] $terms
|
* #param string[] $terms
|
||||||
*/
|
*/
|
||||||
private static function build_search_querylet(array $terms): Querylet
|
private static function build_search_querylet(array $tag_querylets, array $img_querylets): Querylet
|
||||||
{
|
{
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$tag_querylets = [];
|
|
||||||
$img_querylets = [];
|
|
||||||
$positive_tag_count = 0;
|
$positive_tag_count = 0;
|
||||||
$negative_tag_count = 0;
|
$negative_tag_count = 0;
|
||||||
|
foreach ($tag_querylets as $tq) {
|
||||||
/*
|
if ($tq->positive) {
|
||||||
* Turn a bunch of strings into a bunch of TagQuerylet
|
$positive_tag_count++;
|
||||||
* and ImgQuerylet objects
|
|
||||||
*/
|
|
||||||
$stpe = new SearchTermParseEvent(null, $terms);
|
|
||||||
send_event($stpe);
|
|
||||||
if ($stpe->is_querylet_set()) {
|
|
||||||
foreach ($stpe->get_querylets() as $querylet) {
|
|
||||||
$img_querylets[] = new ImgQuerylet($querylet, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($terms as $term) {
|
|
||||||
$positive = true;
|
|
||||||
if (is_string($term) && !empty($term) && ($term[0] == '-')) {
|
|
||||||
$positive = false;
|
|
||||||
$term = substr($term, 1);
|
|
||||||
}
|
|
||||||
if (strlen($term) === 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$stpe = new SearchTermParseEvent($term, $terms);
|
|
||||||
send_event($stpe);
|
|
||||||
if ($stpe->is_querylet_set()) {
|
|
||||||
foreach ($stpe->get_querylets() as $querylet) {
|
|
||||||
$img_querylets[] = new ImgQuerylet($querylet, $positive);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// if the whole match is wild, skip this;
|
$negative_tag_count++;
|
||||||
// if not, translate into SQL
|
|
||||||
if (str_replace("*", "", $term) != "") {
|
|
||||||
$term = str_replace('_', '\_', $term);
|
|
||||||
$term = str_replace('%', '\%', $term);
|
|
||||||
$term = str_replace('*', '%', $term);
|
|
||||||
$tag_querylets[] = new TagQuerylet($term, $positive);
|
|
||||||
if ($positive) {
|
|
||||||
$positive_tag_count++;
|
|
||||||
} else {
|
|
||||||
$negative_tag_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue