Skip to content

Commit

Permalink
Use PCRE if available, QRegExp is orders of magnitude slower with act…
Browse files Browse the repository at this point in the history
…ual regexes.
  • Loading branch information
astifter committed Dec 14, 2015
1 parent 9268038 commit c5c432c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 9 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ else()
message(STATUS " Geographic map features won't be built.")
endif(KGEOMAP_FOUND)

find_package(PCRE)
if (PCRE_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_PCRE")
message(STATUS "added -DUSE_PCRE to preprocessor defines")
endif()

add_custom_target(
UpdateVersion ALL
COMMAND ${CMAKE_COMMAND} -DBASE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/UpdateVersion.cmake"
Expand Down Expand Up @@ -482,6 +488,10 @@ if(KGEOMAP_FOUND)
target_link_libraries(kphotoalbum ${KGEOMAP_LIBRARIES} )
endif()

if (PCRE_FOUND)
target_link_libraries(kphotoalbum pcre)
endif()

install(TARGETS kphotoalbum ${INSTALL_TARGETS_DEFAULT_ARGS})

########### install files ###############
Expand Down
46 changes: 38 additions & 8 deletions DB/ImageSearchInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,37 @@ ImageSearchInfo::ImageSearchInfo( const ImageDate& date,
const QString& label, const QString& description )
: m_date( date), m_label( label ), m_description( description ), m_rating( -1 ), m_megapixel( 0 ), m_ratingSearchMode( 0 ), m_searchRAW( false ), m_isNull( false ), m_compiled( false )
{
#ifdef USE_PCRE
m_regex = NULL; m_regexExtra = NULL;
#endif
}

ImageSearchInfo::ImageSearchInfo( const ImageDate& date,
const QString& label, const QString& description,
const QString& fnPattern )
const QString& fnPattern )
: m_date( date), m_label( label ), m_description( description ), m_fnPattern( fnPattern ), m_rating( -1 ), m_megapixel( 0 ), m_ratingSearchMode( 0 ), m_searchRAW( false ), m_isNull( false ), m_compiled( false )
{
#ifdef USE_PCRE
const char* pat = fnPattern.toUtf8().constData();
const char* errorStr; int errorOff;
m_regex = pcre_compile(pat, PCRE_UTF8, &errorStr, &errorOff, NULL);
if (errorStr != NULL || fnPattern.length() == 0) {
m_regex = NULL; m_regexExtra = NULL;
//qDebug() << "failed to compile pcre: " << errorStr << " at " << errorOff;
return;
}
m_regexExtra = pcre_study(m_regex, 0, &errorStr);
//qDebug() << "init pcre " << m_regex << ", " << m_regexExtra;
#else
m_regex = NULL; m_regexExtra = NULL;
#endif
}

QString ImageSearchInfo::label() const
{
return m_label;
}

QRegExp ImageSearchInfo::fnPattern() const
{
return m_fnPattern;
}

QString ImageSearchInfo::description() const
{
return m_description;
Expand All @@ -67,6 +79,9 @@ QString ImageSearchInfo::description() const
ImageSearchInfo::ImageSearchInfo()
: m_rating( -1 ), m_megapixel( 0 ), m_ratingSearchMode( 0 ), m_searchRAW( false ), m_isNull( true ), m_compiled( false )
{
#ifdef USE_PCRE
m_regex = NULL; m_regexExtra = NULL;
#endif
}

bool ImageSearchInfo::isNull() const
Expand Down Expand Up @@ -166,9 +181,21 @@ bool ImageSearchInfo::match( ImageInfoPtr info ) const
}

// -------------------------------------------------- File name pattern
#ifdef USE_PCRE
if (m_regex != NULL) {
QByteArray fnArray = info->fileName().relative().toUtf8();
//qDebug() << "matching " << info->fileName().relative() << "(" << fnArray.size() <<")";
int result = pcre_exec(m_regex, m_regexExtra, fnArray.constData(), fnArray.size(), 0, 0, NULL, 0);
if (result < 0) {
ok = ok && 0;
} else {
//qDebug() << "match found " << info->fileName().relative();
}
}
#else
ok = ok && ( m_fnPattern.isEmpty() ||
m_fnPattern.indexIn( info->fileName().relative() ) != -1 );

#endif

#ifdef HAVE_KGEOMAP
// Search for GPS Position
Expand Down Expand Up @@ -318,6 +345,10 @@ ImageSearchInfo::ImageSearchInfo( const ImageSearchInfo& other )
m_label = other.m_label;
m_description = other.m_description;
m_fnPattern = other.m_fnPattern;
#ifdef USE_PCRE
m_regex = other.m_regex;
m_regexExtra = other.m_regexExtra;
#endif
m_isNull = other.m_isNull;
m_compiled = false;
m_rating = other.m_rating;
Expand All @@ -330,7 +361,6 @@ ImageSearchInfo::ImageSearchInfo( const ImageSearchInfo& other )
#ifdef HAVE_KGEOMAP
m_regionSelection = other.m_regionSelection;
#endif

}

void ImageSearchInfo::compile() const
Expand Down
9 changes: 8 additions & 1 deletion DB/ImageSearchInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#ifdef HAVE_KGEOMAP
# include <libkgeomap/geocoordinates.h>
#endif
#ifdef USE_PCRE
# include <pcre.h>
#endif
namespace DB
{

Expand All @@ -46,7 +49,7 @@ class ImageSearchInfo {
const QString& label, const QString& description );
ImageSearchInfo( const ImageDate& date,
const QString& label, const QString& description,
const QString& fnPattern );
const QString& fnPattern );
ImageSearchInfo( const ImageSearchInfo& other );

ImageDate date() const;
Expand Down Expand Up @@ -100,6 +103,10 @@ class ImageSearchInfo {
QString m_label;
QString m_description;
QRegExp m_fnPattern;
#ifdef USE_PCRE
pcre* m_regex;
pcre_extra* m_regexExtra;
#endif
short m_rating;
short m_megapixel;
int m_ratingSearchMode;
Expand Down
37 changes: 37 additions & 0 deletions cmake/modules/FindPCRE.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (C) 2007-2009 LuaDist.
# Created by Peter Kapec <kapecp@gmail.com>
# Redistribution and use of this file is allowed according to the terms of the MIT license.
# For details see the COPYRIGHT file distributed with LuaDist.
# Note:
# Searching headers and libraries is very simple and is NOT as powerful as scripts
# distributed with CMake, because LuaDist defines directories to search for.
# Everyone is encouraged to contact the author with improvements. Maybe this file
# becomes part of CMake distribution sometimes.

# - Find pcre
# Find the native PCRE headers and libraries.
#
# PCRE_INCLUDE_DIRS - where to find pcre.h, etc.
# PCRE_LIBRARIES - List of libraries when using pcre.
# PCRE_FOUND - True if pcre found.

# Look for the header file.
FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h)

# Look for the library.
FIND_LIBRARY(PCRE_LIBRARY NAMES pcre)

# Handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if all listed variables are TRUE.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR)

# Copy the results to the output variables.
IF(PCRE_FOUND)
SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR})
ELSE(PCRE_FOUND)
SET(PCRE_LIBRARIES)
SET(PCRE_INCLUDE_DIRS)
ENDIF(PCRE_FOUND)

MARK_AS_ADVANCED(PCRE_INCLUDE_DIRS PCRE_LIBRARIES)

0 comments on commit c5c432c

Please sign in to comment.