summaryrefslogtreecommitdiff
path: root/plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h')
-rw-r--r--plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h215
1 files changed, 215 insertions, 0 deletions
diff --git a/plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h b/plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h
new file mode 100644
index 0000000000..3630527157
--- /dev/null
+++ b/plugins/Dbx_kyoto/src/kyotocabinet/kccompare.h
@@ -0,0 +1,215 @@
+/*************************************************************************************************
+ * Comparator functions
+ * Copyright (C) 2009-2012 FAL Labs
+ * This file is part of Kyoto Cabinet.
+ * This program is free software: you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software Foundation, either version
+ * 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *************************************************************************************************/
+
+
+#ifndef _KCCOMPARE_H // duplication check
+#define _KCCOMPARE_H
+
+#include <kccommon.h>
+#include <kcutil.h>
+
+namespace kyotocabinet { // common namespace
+
+
+/**
+ * Interfrace of comparator of record keys.
+ */
+class Comparator {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Comparator() {}
+ /**
+ * Compare two keys.
+ * @param akbuf the pointer to the region of one key.
+ * @param aksiz the size of the region of one key.
+ * @param bkbuf the pointer to the region of the other key.
+ * @param bksiz the size of the region of the other key.
+ * @return positive if the former is big, negative if the latter is big, 0 if both are
+ * equivalent.
+ */
+ virtual int32_t compare(const char* akbuf, size_t aksiz, const char* bkbuf, size_t bksiz) = 0;
+};
+
+
+/**
+ * Comparator in the lexical order.
+ */
+class LexicalComparator : public Comparator {
+ public:
+ explicit LexicalComparator() {}
+ int32_t compare(const char* akbuf, size_t aksiz, const char* bkbuf, size_t bksiz) {
+ _assert_(akbuf && bkbuf);
+ size_t msiz = aksiz < bksiz ? aksiz : bksiz;
+ for (size_t i = 0; i < msiz; i++) {
+ if (((uint8_t*)akbuf)[i] != ((uint8_t*)bkbuf)[i])
+ return ((uint8_t*)akbuf)[i] - ((uint8_t*)bkbuf)[i];
+ }
+ return (int32_t)aksiz - (int32_t)bksiz;
+ }
+};
+
+
+/**
+ * Comparator in the lexical descending order.
+ */
+class LexicalDescendingComparator : public Comparator {
+ public:
+ explicit LexicalDescendingComparator() : comp_() {}
+ int32_t compare(const char* akbuf, size_t aksiz, const char* bkbuf, size_t bksiz) {
+ return -comp_.compare(akbuf, aksiz, bkbuf, bksiz);
+ }
+ private:
+ LexicalComparator comp_;
+};
+
+
+/**
+ * Comparator in the decimal order.
+ */
+class DecimalComparator : public Comparator {
+ public:
+ explicit DecimalComparator() {}
+ int32_t compare(const char* akbuf, size_t aksiz, const char* bkbuf, size_t bksiz) {
+ _assert_(akbuf && bkbuf);
+ const int32_t LDBLCOLMAX = 16;
+ const unsigned char* arp = (unsigned char*)akbuf;
+ int32_t alen = aksiz;
+ while (alen > 0 && (*arp <= ' ' || *arp == 0x7f)) {
+ arp++;
+ alen--;
+ }
+ int64_t anum = 0;
+ int32_t asign = 1;
+ if (alen > 0 && *arp == '-') {
+ arp++;
+ alen--;
+ asign = -1;
+ }
+ while (alen > 0) {
+ int32_t c = *arp;
+ if (c < '0' || c > '9') break;
+ anum = anum * 10 + c - '0';
+ arp++;
+ alen--;
+ }
+ anum *= asign;
+ const unsigned char* brp = (unsigned char*)bkbuf;
+ int32_t blen = bksiz;
+ while (blen > 0 && (*brp <= ' ' || *brp == 0x7f)) {
+ brp++;
+ blen--;
+ }
+ int64_t bnum = 0;
+ int32_t bsign = 1;
+ if (blen > 0 && *brp == '-') {
+ brp++;
+ blen--;
+ bsign = -1;
+ }
+ while (blen > 0) {
+ int32_t c = *brp;
+ if (c < '0' || c > '9') break;
+ bnum = bnum * 10 + c - '0';
+ brp++;
+ blen--;
+ }
+ bnum *= bsign;
+ if (anum < bnum) return -1;
+ if (anum > bnum) return 1;
+ if ((alen > 1 && *arp == '.') || (blen > 1 && *brp == '.')) {
+ long double aflt = 0;
+ if (alen > 1 && *arp == '.') {
+ arp++;
+ alen--;
+ if (alen > LDBLCOLMAX) alen = LDBLCOLMAX;
+ long double base = 10;
+ while (alen > 0) {
+ if (*arp < '0' || *arp > '9') break;
+ aflt += (*arp - '0') / base;
+ arp++;
+ alen--;
+ base *= 10;
+ }
+ aflt *= asign;
+ }
+ long double bflt = 0;
+ if (blen > 1 && *brp == '.') {
+ brp++;
+ blen--;
+ if (blen > LDBLCOLMAX) blen = LDBLCOLMAX;
+ long double base = 10;
+ while (blen > 0) {
+ if (*brp < '0' || *brp > '9') break;
+ bflt += (*brp - '0') / base;
+ brp++;
+ blen--;
+ base *= 10;
+ }
+ bflt *= bsign;
+ }
+ if (aflt < bflt) return -1;
+ if (aflt > bflt) return 1;
+ }
+ LexicalComparator lexcomp;
+ int32_t rv = lexcomp.compare(akbuf, aksiz, bkbuf, bksiz);
+ return rv;
+ }
+};
+
+
+/**
+ * Comparator in the decimal descending order.
+ */
+class DecimalDescendingComparator : public Comparator {
+ public:
+ explicit DecimalDescendingComparator() : comp_() {}
+ int32_t compare(const char* akbuf, size_t aksiz, const char* bkbuf, size_t bksiz) {
+ return -comp_.compare(akbuf, aksiz, bkbuf, bksiz);
+ }
+ private:
+ DecimalComparator comp_;
+};
+
+
+/**
+ * Prepared pointer of the comparator in the lexical order.
+ */
+extern LexicalComparator* const LEXICALCOMP;
+
+
+/**
+ * Prepared pointer of the comparator in the lexical descending order.
+ */
+extern LexicalDescendingComparator* const LEXICALDESCCOMP;
+
+
+/**
+ * Prepared pointer of the comparator in the decimal order.
+ */
+extern DecimalComparator* const DECIMALCOMP;
+
+
+/**
+ * Prepared pointer of the comparator in the decimal descending order.
+ */
+extern DecimalDescendingComparator* const DECIMALDESCCOMP;
+
+
+} // common namespace
+
+#endif // duplication check
+
+// END OF FILE