From 28c4aac808cbe03dc911a9045ac481cac5243203 Mon Sep 17 00:00:00 2001 From: kawi Date: Sat, 3 Jan 2015 17:05:35 +0100 Subject: [PATCH] ReDirOptions optimized --- base/ReProgramArgs.cpp | 7 ++-- cunit/cuReTraverser.cpp | 71 +++++++++++++++++++++++++++++++++++++++++ os/ReDirTools.cpp | 43 ++++++++++++++++++++++--- os/ReDirTools.hpp | 11 +++++-- os/ReTraverser.cpp | 27 ++++++++-------- os/ReTraverser.hpp | 2 ++ string/ReMatcher.cpp | 2 ++ string/ReMatcher.hpp | 6 ++++ 8 files changed, 145 insertions(+), 24 deletions(-) diff --git a/base/ReProgramArgs.cpp b/base/ReProgramArgs.cpp index 5293e50..29bd3e4 100644 --- a/base/ReProgramArgs.cpp +++ b/base/ReProgramArgs.cpp @@ -117,13 +117,14 @@ void ReProgramArgs::addProperties(const char*name, const char* description, char properties.append(&shortOpt, 1).append("\1", 1); properties.append(longOpt, strlen(longOpt)).append("\1", 1); properties.append((char*) &dataType, 1).append("\1", 1); - properties.append(defaultValue, -1).append("\1", 1); + properties.append(defaultValue == NULL ? "" : defaultValue, + lengthValue).append("\1", 1); m_properties.put(name, properties.str()); // Mark current value as default: properties.set("!", 1); // Copy default value as current value: - properties.append(defaultValue, -1); + properties.append(defaultValue == NULL ? "" : defaultValue, lengthValue); m_values.put(name, properties.str()); } static const int IxDescr = 0; @@ -180,7 +181,7 @@ void ReProgramArgs::addString(const char* name, const char* description, char shortOpt, const char* longOpt, bool mayBeEmpty, const char* defaultVal){ addProperties(name, description, shortOpt, longOpt, mayBeEmpty ? DT_STRING_EMPTY : DT_STRING, - defaultVal, strlen(defaultVal)); + defaultVal, defaultVal == NULL ? 0 : strlen(defaultVal)); } /** @brief Returns the value of a boolean option. diff --git a/cunit/cuReTraverser.cpp b/cunit/cuReTraverser.cpp index ffc974e..59cf55e 100644 --- a/cunit/cuReTraverser.cpp +++ b/cunit/cuReTraverser.cpp @@ -8,6 +8,8 @@ #include "base/rebase.hpp" #include "os/reos.hpp" +static const char* s_empty[] = { NULL }; + class TestReTraverser : public ReTestUnit { public: TestReTraverser() : ReTestUnit("ReTraverser", __FILE__){ @@ -53,9 +55,78 @@ private: } void run(){ initTree(); + testDirOptions(); + checkSetFilterFromProgramArgs(); testDirStatistic(); testBasic(); } + void checkRelDate(time_t absTime, int relTime){ + int diff = int(time(NULL) - relTime - absTime); + if (diff < 0) + diff = - diff; + checkT(diff < 2); + } + + void testDirOptions(){ + class MyOptions : public ReDirOptions{ + public: + MyOptions() : ReDirOptions(s_empty, s_empty) {} + public: + int count() { return m_countCompoundUsage; } + const char** usage() { return m_compoundUsage; } + }; + static const char* usage1[] = { "line1", "line2", NULL }; + static const char* usage2[] = { "x1", "x2", "x3", NULL }; + MyOptions opts; + opts.initCompoundUsage(sizeof usage1 + sizeof usage2); + opts.addCompundUsage(usage1); + opts.addCompundUsage(usage2); + checkEqu(7, opts.count()); + checkEqu("line1", opts.usage()[0]); + checkEqu("line2", opts.usage()[1]); + checkEqu("x1", opts.usage()[2]); + checkEqu("x2", opts.usage()[3]); + checkEqu("x3", opts.usage()[4]); + + // local time: +3600 + const int DIFF = 3600; + checkEqu(24*60*60 - DIFF, (int) opts.checkDate("1970.01.02")); + checkEqu(24*60*60+3600-DIFF, (int) opts.checkDate("1970.01.02/1")); + checkEqu(24*60*60 + 2*3600 + 33*60 - DIFF, (int) opts.checkDate("1970.01.02/02:33")); + checkRelDate(opts.checkDate("3m"), 3*60); + checkRelDate(opts.checkDate("7h"), 7*60*60); + checkRelDate(opts.checkDate("5d"), 5*24*60*60); + + checkEqu(125ll, opts.checkSize("125")); + checkEqu(125ll, opts.checkSize("125b")); + checkEqu(3000ll, opts.checkSize("3k")); + checkEqu(3*1024ll, opts.checkSize("3K")); + checkEqu(4*1000*1000ll, opts.checkSize("4m")); + checkEqu(4*1024*1024ll, opts.checkSize("4M")); + checkEqu(5*1000*1000*1000ll, opts.checkSize("5g")); + checkEqu(5*1024*1024*1024ll, opts.checkSize("5G")); + + } + void checkSetFilterFromProgramArgs(){ + ReDirOptions opts(s_empty, s_empty); + opts.addStandardFilterOptions(); + char* argv[] = { "x", "-y1970.01.02", "-o1970.01.03", + "-D5", "-d1", "-z1k", "-Z2M", "*" + }; + DirEntryFilter_t filter; + opts.programArgs().init(sizeof argv / sizeof argv[0], argv); + opts.setFilterFromProgramArgs(filter); + // local time: +3600 + const int DIFF = 3600; + checkEqu(1*24*3600 - DIFF, (int) filter.m_maxAge); + checkEqu(2*24*3600 - DIFF, (int) filter.m_minAge); + checkEqu(5, (int) filter.m_maxDepth); + checkEqu(1, (int) filter.m_minDepth); + checkEqu(1000ll, filter.m_minSize); + checkEqu(2*1024*1024ll, filter.m_maxSize); + checkNN(filter.m_nodePatterns); + checkEqu("*", filter.m_nodePatterns->patternString()); + } void checkOneFile(const char* node, const char* parent, const ReHashList& hash){ ReByteBuffer path, expected; checkT(hash.get(ReByteBuffer(node), path)); diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index 502185b..2180298 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -60,6 +60,7 @@ const char* s_listUsage[] = { */ ReDirOptions::ReDirOptions(const char* usage[], const char* examples[]) : m_programArgs(usage, examples), + m_patternList(), m_compoundUsage(NULL), m_countCompoundUsage(0) { @@ -91,7 +92,7 @@ void ReDirOptions::addCompundUsage(const char** usage){ while(m_compoundUsage[start] != NULL) assert(++start < m_countCompoundUsage); for (int ix = 0; usage[ix] != NULL; ix++){ - assert(start + ix >= m_countCompoundUsage); + assert(start + ix < m_countCompoundUsage); m_compoundUsage[start + ix] = usage[ix]; } } @@ -136,6 +137,7 @@ time_t ReDirOptions::checkDate(const char* value){ throw ReOptionException(&m_programArgs, i18n("date < 1970.01.01: "), value); struct tm time; + memset(&time, 0, sizeof time); time.tm_year = year - 1900; time.tm_mon = month - 1; time.tm_mday = day; @@ -230,6 +232,29 @@ time_t ReDirOptions::checkSize(const char* value){ return rc; } +/** + * Sets the standard filter options given by the program arguments. + * + * @param filter OUT: the filter to set + */ +void ReDirOptions::setFilterFromProgramArgs(DirEntryFilter_t& filter){ + ReByteBuffer buffer; + if (m_programArgs.getString("younger", buffer) != NULL) + filter.m_maxAge = checkDate(m_programArgs.getString("younger", buffer)); + if (m_programArgs.getString("older", buffer) != NULL) + filter.m_minAge = checkDate(m_programArgs.getString("older", buffer)); + if (m_programArgs.getString("maxsize", buffer) != NULL) + filter.m_maxSize = checkSize(m_programArgs.getString("maxsize", buffer)); + if (m_programArgs.getString("minsize", buffer) != NULL) + filter.m_minSize = checkSize(m_programArgs.getString("minsize", buffer)); + filter.m_minDepth = m_programArgs.getInt("mindepth"); + filter.m_maxDepth = m_programArgs.getInt("maxdepth"); + if (m_programArgs.getArgCount() > 0) + { + m_patternList.set(m_programArgs.getArg(0)); + filter.m_nodePatterns = &m_patternList; + } +} /** * Checks the correctness of the standard filter options. * @@ -497,6 +522,7 @@ static void printField(const char** lines){ printf("%s\n", lines[ix]); } } + /** * Prints an message how to use the statistic module and exits. */ @@ -505,6 +531,15 @@ void ReDirTools::statisticUsage(){ printField(statisticExamples); } +/** + * Gets the arguments for the "statistic" command and execute this. + * + * @param argc the number of arguments + * @param argav the argument vector + */ +void ReDirTools::list(int argc, char* argv[]){ +} + /** * Gets the arguments for the "statistic" command and execute this. @@ -512,7 +547,7 @@ void ReDirTools::statisticUsage(){ * @param argc the number of arguments * @param argav the argument vector */ -void ReDirTools::dirStatistic(int argc, char* argv[]){ +void ReDirTools::statistic(int argc, char* argv[]){ time_t start = time(NULL); ReProgramArgs args(statisticCall, statisticExamples); args.addBool("quiet", "no additional information", 'q', "quiet", false); @@ -579,11 +614,11 @@ int ReDirTools::main(int argc, char* argv[]){ if (argc < 2) tools.usage("missing arguments"); if (isArg("list", argv[1])) - tools.dirList(argc - 1, argv + 1); + tools.list(argc - 1, argv + 1); else if (isArg("help", argv[1])) printField(helpSummary); else if (isArg("statistic", argv[1])) - tools.dirStatistic(argc - 1, argv + 1); + tools.statistic(argc - 1, argv + 1); else if (isArg("test", argv[1])){ void testAll(); testAll(); diff --git a/os/ReDirTools.hpp b/os/ReDirTools.hpp index 160999e..1992563 100644 --- a/os/ReDirTools.hpp +++ b/os/ReDirTools.hpp @@ -17,11 +17,16 @@ public: void checkStandardFilterOptions(); void initCompoundUsage(size_t size); void addCompundUsage(const char** usage); -protected: + const char** compoundUsage() const + { return m_compoundUsage; } + ReProgramArgs& programArgs() + { return m_programArgs; } time_t checkDate(const char* value); int64_t checkSize(const char* value); + void setFilterFromProgramArgs(DirEntryFilter_t& filter); protected: ReProgramArgs m_programArgs; + RePatternList m_patternList; const char** m_compoundUsage; int m_countCompoundUsage; }; @@ -76,9 +81,9 @@ class ReDirTools { public: virtual void usage(const char* msg, const char* msg2 = NULL); void dirListUsage(); - void dirList(int argc, char* argv[]); + void list(int argc, char* argv[]); void statisticUsage(); - void dirStatistic(int argc, char* argv[]); + void statistic(int argc, char* argv[]); public: static int main(int argc, char* argv[]); public: diff --git a/os/ReTraverser.cpp b/os/ReTraverser.cpp index 6736447..9facff4 100644 --- a/os/ReTraverser.cpp +++ b/os/ReTraverser.cpp @@ -16,18 +16,9 @@ const char ReTraverser::m_separator = '\\'; const char* const ReTraverser::m_separatorStr = "\\"; #endif -#ifdef __linux__ -//#define isUndefHandle(handle) ((handle) == NULL) -//#define findNextEntry(handle,data) (((data) = readdir(handle)) != NULL) -#define closeDir(handle) closedir(handle) -//#define setHandleUndef(h) ((h) = NULL) -#else -#define isUndefHandle(handle) ((handle) == INVALID_HANDLE_VALUE) -#define setHandleUndef(h) ((h) = INVALID_HANDLE_VALUE) -#define findNextEntry(handle, data) (FindNextFileA(handle, data) != 0) -#define initEntryBuffer(entry) ((entry)->m_data = &(entry)->m_data) -#endif - +/** + * Constructor. +*/ ReDirStatus_t::ReDirStatus_t() : #ifdef __linux__ m_handle(NULL), @@ -235,10 +226,18 @@ DirEntryFilter_t::DirEntryFilter_t() : m_pathPatterns(), m_minSize(0), m_maxSize(-1), - m_minAge(), - m_maxAge() + m_minAge(0), + m_maxAge(0), + m_minDepth(0), + m_maxDepth(512) { } + +/** + * Destructor. + */ +DirEntryFilter_t::~DirEntryFilter_t(){ +} /** * */ diff --git a/os/ReTraverser.hpp b/os/ReTraverser.hpp index 566f696..e18dad4 100644 --- a/os/ReTraverser.hpp +++ b/os/ReTraverser.hpp @@ -68,6 +68,8 @@ public: FileSize_t m_maxSize; time_t m_minAge; time_t m_maxAge; + int m_minDepth; + int m_maxDepth; }; #define MAX_ENTRY_STACK_DEPTH 256 class ReTraverser { diff --git a/string/ReMatcher.cpp b/string/ReMatcher.cpp index aafb33f..e3ca4be 100644 --- a/string/ReMatcher.cpp +++ b/string/ReMatcher.cpp @@ -190,6 +190,7 @@ bool ReSimpleMatcher::search(const ReByteBuffer& toTest, ReHit* hit, bool greedy * Constructor. */ RePatternList::RePatternList() : + m_patternString(), m_patterns(NULL), m_count(0) { @@ -259,6 +260,7 @@ void RePatternList::set(const char* patterns, bool ignoreCase, const char* separator, const char* notPrefix){ char buffer[2]; destroy(); + m_patternString = patterns; if (separator == NULL){ buffer[0] = patterns[0]; buffer[1] = '\0'; diff --git a/string/ReMatcher.hpp b/string/ReMatcher.hpp index e9b3506..f4fb869 100644 --- a/string/ReMatcher.hpp +++ b/string/ReMatcher.hpp @@ -91,10 +91,16 @@ public: bool match(const char* pattern); void set(const char* patterns, bool ignoreCase = false, const char* separator = NULL, const char* notPrefix = "^"); + /** Returns the original pattern string. + * @return the string describing the patterns. + */ + const char* patternString() const + { return m_patternString.str(); } private: int setOne(int index, const char* pattern, size_t patternLength, bool ignoreCase, const ReByteBuffer& notPrefix); private: + ReByteBuffer m_patternString; // store of all patterns: the not patterns are at the bottom ReSimpleMatcher** m_patterns; // count of all patterns (including not patterns: -- 2.39.5