From 0ec73e44caf0264581f7636ac03ea47b0fd96df3 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 3 Mar 2016 16:06:59 +0100 Subject: [PATCH] Index search method added --- lib/libZRCola/include/zrcola/common.h | 45 +++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/libZRCola/include/zrcola/common.h b/lib/libZRCola/include/zrcola/common.h index 6d73d37..5d2af28 100644 --- a/lib/libZRCola/include/zrcola/common.h +++ b/lib/libZRCola/include/zrcola/common.h @@ -69,6 +69,7 @@ namespace ZRCola { /// index(_In_ std::vector &h) : host(h) {} + /// /// Sorts index /// @@ -77,6 +78,7 @@ namespace ZRCola { qsort_s(data(), size(), sizeof(T_idx), compare_s, this); } + /// /// Compares two elements /// @@ -90,6 +92,49 @@ namespace ZRCola { /// virtual int compare(_In_ const T &a, _In_ const T &b) const = 0; + + /// + /// Search for the element in the index + /// The elements matching \p el are located on the interval [\p start, \p end) in the index. + /// + /// \param[in] el Element we are looking for (needle) + /// \param[out] start Index of the first matching element found + /// \param[out] end Index of the first non-matching element found + /// + /// \returns + /// - true if found + /// - false otherwise + /// + bool find(_In_ const T &el, _Out_ size_type &start, _Out_ size_type &end) const + { + // Start with the full search area. + for (start = 0, end = size(); start < end; ) { + size_type m = (start + end) / 2; + int r = compare(el, host[at(m)]); + if (r < 0) end = m; + else if (r > 0) start = m + 1; + else { + // Narrow the search area on the left to start at the first element in the run. + for (size_type end2 = m; start < end2;) { + size_type m = (start + end2) / 2; + int r = compare(el, host[at(m)]); + if (r <= 0) end2 = m; else start = m + 1; + } + + // Narrow the search area on the right to end at the first element not in the run. + for (size_type start2 = m + 1; start2 < end;) { + size_type m = (start2 + end) / 2; + int r = compare(el, host[at(m)]); + if (0 <= r) start2 = m + 1; else end = m; + } + + return true; + } + } + + return false; + } + private: static int __cdecl compare_s(void *p, const void *a, const void *b) {