Anomaly support added
authorTasuku Suzuki <stasuku@gmail.com>
Sat, 25 Jan 2014 06:35:02 +0000 (15:35 +0900)
committerTasuku Suzuki <stasuku@gmail.com>
Sat, 25 Jan 2014 06:37:34 +0000 (15:37 +0900)
Change-Id: Iff13e5261d88d45d37d48f8d92289b569e66ee09
Reviewed-on: http://cr.qtquick.me/797
Reviewed-by: Tasuku Suzuki <stasuku@gmail.com>
Tested-by: Tasuku Suzuki <stasuku@gmail.com>
15 files changed:
examples/cpp/anomaly/anomaly.pro [new file with mode: 0644]
examples/cpp/anomaly/nikkei_stock_avarage/main.cpp [new file with mode: 0644]
examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.json [new file with mode: 0644]
examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.pro [new file with mode: 0644]
examples/cpp/cpp.pro
src/jubatus/anomaly/anomaly.pri [new file with mode: 0644]
src/jubatus/anomaly/qjubatusanomaly.cpp [new file with mode: 0644]
src/jubatus/anomaly/qjubatusanomaly.h [new file with mode: 0644]
src/jubatus/classifier/classifier.pri
src/jubatus/classifier/qjubatusclassifier.cpp
src/jubatus/classifier/qjubatusclassifier.h
src/jubatus/client/client.pri [new file with mode: 0644]
src/jubatus/client/qjubatusclient.cpp [new file with mode: 0644]
src/jubatus/client/qjubatusclient.h [new file with mode: 0644]
src/jubatus/jubatus.pro

diff --git a/examples/cpp/anomaly/anomaly.pro b/examples/cpp/anomaly/anomaly.pro
new file mode 100644 (file)
index 0000000..4cc3114
--- /dev/null
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += nikkei_stock_avarage
diff --git a/examples/cpp/anomaly/nikkei_stock_avarage/main.cpp b/examples/cpp/anomaly/nikkei_stock_avarage/main.cpp
new file mode 100644 (file)
index 0000000..03b9de6
--- /dev/null
@@ -0,0 +1,88 @@
+#include <QtCore>
+#include <QtNetwork>
+#include <QtWidgets>
+#include <QtJubatus>
+
+class Graph : public QWidget
+{
+    Q_OBJECT
+public:
+    Graph(QWidget *parent = 0);
+
+protected:
+    void paintEvent(QPaintEvent *e);
+
+private:
+    QNetworkAccessManager manager;
+    struct Data {
+        float first;
+        float last;
+        float score;
+    };
+
+    QList<Data> data;
+};
+
+Graph::Graph(QWidget *parent)
+    : QWidget(parent)
+{
+    QObject::connect(&manager, &QNetworkAccessManager::finished, [this](QNetworkReply *reply) {
+        QJubatusAnomaly anomaly;
+        anomaly.setTimeout(60);
+        QStringList lines = QTextCodec::codecForName("Shift-JIS")->toUnicode(reply->readAll()).split(QStringLiteral("\r\n"));
+        foreach (const QString &line, lines) {
+            QStringList columns = line.split(QStringLiteral(","));
+            if (columns.length() != 5) continue;
+            bool ok;
+            QString first = columns.at(2);
+            QString last = columns.at(1);
+            Data d;
+            d.first = first.replace("\"", "").toFloat(&ok);
+            d.last = last.replace("\"", "").toFloat(&ok);
+            if (ok) {
+                d.first = d.first / 20000;
+                d.last = d.last / 20000;
+                QVariantMap params;
+                params.insert("first", d.first * 100);
+                params.insert("last", d.last * 100);
+                params.insert("diff", (d.last - d.first) * 100);
+                QJubatusAnomaly::IdAndScore ret = anomaly.add(params);
+                d.score = ret.score;
+                data.append(d);
+            }
+        }
+        reply->deleteLater();
+        update();
+    });
+
+    // http://indexes.nikkei.co.jp/nkave/index
+    manager.get(QNetworkRequest(QUrl("http://indexes.nikkei.co.jp/nkave/historical/nikkei_stock_average_daily_jp.csv")));
+}
+
+void Graph::paintEvent(QPaintEvent *e)
+{
+    if (data.isEmpty()) return;
+
+    QPainter p(this);
+
+    float x = 0;
+    float dx = (float)width() / data.count();
+    float dy = height();
+
+    foreach (const Data &d, data) {
+        p.fillRect(QRectF(x, (1.0 - qMax(d.first, d.last)) * dy, dx, qAbs(d.last - d.first) * dy), QColor(qIsInf(d.score) ? Qt::red : Qt::black));
+        x += dx;
+    }
+}
+
+int main(int argc, char **argv)
+{
+    QApplication app(argc, argv);
+
+    Graph graph;
+    graph.show();
+
+    return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.json b/examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.json
new file mode 100644 (file)
index 0000000..d36a950
--- /dev/null
@@ -0,0 +1,30 @@
+{
+  "method" : "lof",
+  "parameter" : {
+    "nearest_neighbor_num" : 10,
+    "reverse_nearest_neighbor_num" : 30,
+    "method" : "euclid_lsh",
+    "parameter" : {
+      "hash_num" : 64,
+      "table_num" : 4,
+      "seed" : 1091,
+      "probe_num" : 64,
+      "bin_width" : 32,
+      "retain_projection" : true
+    }
+  },
+  "converter" : {
+    "string_filter_types" : {},
+    "string_filter_rules" : [],
+    "num_filter_types" : {},
+    "num_filter_rules" : [],
+    "string_types" : {},
+    "string_rules" : [
+      { "key" : "*", "type" : "str", "sample_weight" : "bin", "global_weight" : "bin" }
+    ],
+    "num_types" : {},
+    "num_rules" : [
+      { "key" : "*", "type" : "num" }
+    ]
+  }
+}
diff --git a/examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.pro b/examples/cpp/anomaly/nikkei_stock_avarage/nikkei_stock_avarage.pro
new file mode 100644 (file)
index 0000000..2af4b4a
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = jubatus-nikke-stock-avarage
+QT = core network gui widgets jubatus
+CONFIG += c++11
+SOURCES = main.cpp
+
+OTHER_FILES += nikkei_stock_avarage.json
index b102086..ea31fc9 100644 (file)
@@ -1,2 +1,2 @@
 TEMPLATE = subdirs
-SUBDIRS += classifier
+SUBDIRS += anomaly classifier
diff --git a/src/jubatus/anomaly/anomaly.pri b/src/jubatus/anomaly/anomaly.pri
new file mode 100644 (file)
index 0000000..00d0167
--- /dev/null
@@ -0,0 +1,6 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+PUBLIC_HEADERS += $$PWD/qjubatusanomaly.h
+HEADERS += $$PUBLIC_HEADERS
+SOURCES += $$PWD/qjubatusanomaly.cpp
diff --git a/src/jubatus/anomaly/qjubatusanomaly.cpp b/src/jubatus/anomaly/qjubatusanomaly.cpp
new file mode 100644 (file)
index 0000000..a7fd739
--- /dev/null
@@ -0,0 +1,120 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qjubatusanomaly.h"
+
+#include <QtCore/QDebug>
+
+#include <vector>
+
+#include <jubatus/client/anomaly_client.hpp>
+
+class QJubatusAnomaly::Private
+{
+public:
+    Private();
+    ~Private();
+
+    jubatus::anomaly::client::anomaly *client;
+};
+
+QJubatusAnomaly::Private::Private()
+    : client(0)
+{
+}
+
+QJubatusAnomaly::Private::~Private()
+{
+    delete client;
+}
+
+QJubatusAnomaly::QJubatusAnomaly(QObject *parent)
+    : QJubatusClient(parent)
+    , d(new Private)
+{
+    connect(this, &QJubatusAnomaly::destroyed, [this](){ delete d; });
+    auto deleteClient = [this]() { delete d->client; d->client = 0; };
+    connect(this, &QJubatusAnomaly::hostChanged, deleteClient);
+    connect(this, &QJubatusAnomaly::portChanged, deleteClient);
+    connect(this, &QJubatusAnomaly::nameChanged, deleteClient);
+    connect(this, &QJubatusAnomaly::timeoutChanged, deleteClient);
+}
+
+bool QJubatusAnomaly::clearRow(const QString &id)
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    return d->client->clear_row(id.toStdString());
+}
+
+QJubatusAnomaly::IdAndScore QJubatusAnomaly::add(const QVariantMap &data)
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    jubatus::anomaly::id_with_score id_with_score = d->client->add(convert(data));
+    IdAndScore ret;
+    ret.id = QString::fromStdString(id_with_score.id);
+    ret.score = id_with_score.score;
+    return ret;
+}
+
+float QJubatusAnomaly::update(const QString &id, const QVariantMap &data)
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    return d->client->update(id.toStdString(), convert(data));
+}
+
+float QJubatusAnomaly::overwrite(const QString &id, const QVariantMap &data)
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    return d->client->overwrite(id.toStdString(), convert(data));
+}
+
+float QJubatusAnomaly::calcScore(const QVariantMap &data)
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    return d->client->calc_score(convert(data));
+}
+
+QStringList QJubatusAnomaly::getAllRows()
+{
+    if (!d->client) {
+        d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
+    }
+    QStringList ret;
+    foreach (std::string id, d->client->get_all_rows())
+        ret.append(QString::fromStdString(id));
+    return ret;
+}
+
diff --git a/src/jubatus/anomaly/qjubatusanomaly.h b/src/jubatus/anomaly/qjubatusanomaly.h
new file mode 100644 (file)
index 0000000..e5362ca
--- /dev/null
@@ -0,0 +1,64 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QJUBATUSANOMALY_H
+#define QJUBATUSANOMALY_H
+
+#include "jubatus_global.h"
+#include "qjubatusclient.h"
+
+#include <QtCore/QVariant>
+
+namespace jubatus {
+    namespace anomaly {
+        struct id_with_score;
+    }
+}
+
+class JUBATUS_EXPORT QJubatusAnomaly : public QJubatusClient
+{
+    Q_OBJECT
+public:
+    explicit QJubatusAnomaly(QObject *parent = 0);
+
+    struct IdAndScore {
+        QString id;
+        float score;
+    };
+
+    bool clearRow(const QString &id);
+    IdAndScore add(const QVariantMap &data);
+    float update(const QString &id, const QVariantMap &data);
+    float overwrite(const QString &id, const QVariantMap &data);
+    float calcScore(const QVariantMap &data);
+    QStringList getAllRows();
+
+private:
+    class Private;
+    Private *d;
+};
+
+#endif // QJUBATUSANOMALY_H
index 8732c5f..a1ebc02 100644 (file)
@@ -1,5 +1,3 @@
-CONFIG += exceptions
-
 INCLUDEPATH += $$PWD
 DEPENDPATH += $$PWD
 
index c7c168e..5d7c99e 100644 (file)
 
 #include <QtCore/QDebug>
 
-#include <string>
 #include <vector>
 
-#include <jubatus/client.hpp>
+#include <jubatus/client/classifier_client.hpp>
 
 class QJubatusClassifier::Private
 {
 public:
-    Private(QJubatusClassifier *parent);
+    Private();
     ~Private();
 
-private:
-    QJubatusClassifier *q;
-
-public:
     jubatus::classifier::client::classifier *client;
-
-    QString host;
-    int port;
-    QString name;
-    double timeout;
 };
 
-QJubatusClassifier::Private::Private(QJubatusClassifier *parent)
-    : q(parent)
-    , client(0)
-    , host(QStringLiteral("localhost"))
-    , port(9199)
-    , name(QStringLiteral("classifier"))
-    , timeout(1.0)
+QJubatusClassifier::Private::Private()
+    : client(0)
 {
 }
 
@@ -67,8 +52,8 @@ QJubatusClassifier::Private::~Private()
 }
 
 QJubatusClassifier::QJubatusClassifier(QObject *parent)
-    : QObject(parent)
-    , d(new Private(this))
+    : QJubatusClient(parent)
+    , d(new Private)
 {
     connect(this, &QJubatusClassifier::destroyed, [this](){ delete d; });
     auto deleteClient = [this]() { delete d->client; d->client = 0; };
@@ -78,79 +63,6 @@ QJubatusClassifier::QJubatusClassifier(QObject *parent)
     connect(this, &QJubatusClassifier::timeoutChanged, deleteClient);
 }
 
-const QString &QJubatusClassifier::host() const
-{
-    return d->host;
-}
-
-void QJubatusClassifier::setHost(const QString &host)
-{
-    if (d->host == host) return;
-    d->host = host;
-    emit hostChanged(host);
-}
-
-int QJubatusClassifier::port() const
-{
-    return d->port;
-}
-
-void QJubatusClassifier::setPort(int port)
-{
-    if (d->port == port) return;
-    d->port = port;
-    emit portChanged(port);
-}
-
-const QString &QJubatusClassifier::name() const
-{
-    return d->name;
-}
-
-void QJubatusClassifier::setName(const QString &name)
-{
-    if (d->name == name) return;
-    d->name = name;
-    emit nameChanged(name);
-}
-
-double QJubatusClassifier::timeout() const
-{
-    return d->timeout;
-}
-
-void QJubatusClassifier::setTimeout(double timeout)
-{
-    if (d->timeout == timeout) return;
-    d->timeout = timeout;
-    emit timeoutChanged(timeout);
-}
-
-jubatus::client::common::datum QJubatusClassifier::convert(const QVariantMap &data)
-{
-    jubatus::client::common::datum ret;
-
-    foreach (const QString &key, data.keys()) {
-        QVariant value = data.value(key);
-        switch (value.type()) {
-        case QVariant::String:
-            ret.string_values.push_back(make_pair(key.toStdString(), value.toString().toStdString()));
-            break;
-        case QVariant::Int:
-            ret.num_values.push_back(make_pair(key.toStdString(), value.toInt()));
-            break;
-        case QVariant::Double:
-            ret.num_values.push_back(make_pair(key.toStdString(), value.toDouble()));
-            break;
-        default:
-            qDebug() << Q_FUNC_INFO << __LINE__ << value << "not supported.";
-            break;
-        }
-    }
-
-    return ret;
-}
-
 void QJubatusClassifier::train(const QList<QJubatusClassifier::TrainData> &data)
 {
     std::vector<jubatus::classifier::labeled_datum> train_data;
@@ -163,7 +75,7 @@ void QJubatusClassifier::train(const QList<QJubatusClassifier::TrainData> &data)
 void QJubatusClassifier::train(const std::vector<jubatus::classifier::labeled_datum> &data)
 {
     if (!d->client) {
-        d->client = new jubatus::classifier::client::classifier(d->host.toStdString(), d->port, d->name.toStdString(), d->timeout);
+        d->client = new jubatus::classifier::client::classifier(host().toStdString(), port(), name().toStdString(), timeout());
     }
     d->client->train(data);
 }
@@ -196,7 +108,7 @@ QList<QList<QJubatusClassifier::EstimateResult>> QJubatusClassifier::classify(co
 std::vector<std::vector<jubatus::classifier::estimate_result>> QJubatusClassifier::classify(const std::vector<jubatus::client::common::datum> &data)
 {
     if (!d->client) {
-        d->client = new jubatus::classifier::client::classifier(d->host.toStdString(), d->port, d->name.toStdString(), d->timeout);
+        d->client = new jubatus::classifier::client::classifier(host().toStdString(), port(), name().toStdString(), timeout());
     }
     return d->client->classify(data);
 }
index e131a21..e907290 100644 (file)
 #ifndef QJUBATUSCLASSIFIER_H
 #define QJUBATUSCLASSIFIER_H
 
-#include <QtCore/QObject>
+#include "jubatus_global.h"
+#include "qjubatusclient.h"
+
 #include <QtCore/QVariant>
 
-#include "jubatus_global.h"
 
 namespace jubatus {
-    namespace client {
-        namespace common {
-            struct datum;
-        }
-    }
     namespace classifier {
         struct estimate_result;
         struct labeled_datum;
     }
 }
 
-class JUBATUS_EXPORT QJubatusClassifier : public QObject
+class JUBATUS_EXPORT QJubatusClassifier : public QJubatusClient
 {
     Q_OBJECT
-    Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
-    Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
-    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
-    Q_PROPERTY(double timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
 public:
     explicit QJubatusClassifier(QObject *parent = 0);
 
-    const QString &host() const;
-    int port() const;
-    const QString &name() const;
-    double timeout() const;
-
     struct EstimateResult {
         QString label;
         double score;
@@ -69,22 +56,9 @@ public:
     void train(const QList<QJubatusClassifier::TrainData> &data);
     QList<QList<QJubatusClassifier::EstimateResult>> classify(const QList<QVariantMap> &data);
 
-public slots:
-    void setHost(const QString &host);
-    void setPort(int port);
-    void setName(const QString &name);
-    void setTimeout(double timeout);
-
-signals:
-    void hostChanged(const QString &host);
-    void portChanged(int port);
-    void nameChanged(const QString &name);
-    void timeoutChanged(double timeout);
-
 protected:
     void train(const std::vector<jubatus::classifier::labeled_datum> &data);
     std::vector<std::vector<jubatus::classifier::estimate_result>> classify(const std::vector<jubatus::client::common::datum> &data);
-    static jubatus::client::common::datum convert(const QVariantMap &data);
 
 private:
     class Private;
diff --git a/src/jubatus/client/client.pri b/src/jubatus/client/client.pri
new file mode 100644 (file)
index 0000000..f47722d
--- /dev/null
@@ -0,0 +1,8 @@
+CONFIG += exceptions
+
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+PUBLIC_HEADERS *= $$PWD/qjubatusclient.h
+HEADERS *= $$PUBLIC_HEADERS
+SOURCES *= $$PWD/qjubatusclient.cpp
diff --git a/src/jubatus/client/qjubatusclient.cpp b/src/jubatus/client/qjubatusclient.cpp
new file mode 100644 (file)
index 0000000..943a39c
--- /dev/null
@@ -0,0 +1,133 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qjubatusclient.h"
+
+#include <QtCore/QDebug>
+
+#include <jubatus/client/common/datum.hpp>
+
+class QJubatusClient::Private
+{
+public:
+    Private();
+
+    QString host;
+    int port;
+    QString name;
+    double timeout;
+};
+
+QJubatusClient::Private::Private()
+    : host(QStringLiteral("localhost"))
+    , port(9199)
+    , name(QStringLiteral("client"))
+    , timeout(1.0)
+{
+}
+
+QJubatusClient::QJubatusClient(QObject *parent)
+    : QObject(parent)
+    , d(new Private())
+{
+    connect(this, &QJubatusClient::destroyed, [this](){ delete d; });
+}
+
+const QString &QJubatusClient::host() const
+{
+    return d->host;
+}
+
+void QJubatusClient::setHost(const QString &host)
+{
+    if (d->host == host) return;
+    d->host = host;
+    emit hostChanged(host);
+}
+
+int QJubatusClient::port() const
+{
+    return d->port;
+}
+
+void QJubatusClient::setPort(int port)
+{
+    if (d->port == port) return;
+    d->port = port;
+    emit portChanged(port);
+}
+
+const QString &QJubatusClient::name() const
+{
+    return d->name;
+}
+
+void QJubatusClient::setName(const QString &name)
+{
+    if (d->name == name) return;
+    d->name = name;
+    emit nameChanged(name);
+}
+
+double QJubatusClient::timeout() const
+{
+    return d->timeout;
+}
+
+void QJubatusClient::setTimeout(double timeout)
+{
+    if (d->timeout == timeout) return;
+    d->timeout = timeout;
+    emit timeoutChanged(timeout);
+}
+
+jubatus::client::common::datum QJubatusClient::convert(const QVariantMap &data) const
+{
+    jubatus::client::common::datum ret;
+
+    foreach (const QString &key, data.keys()) {
+        QVariant value = data.value(key);
+        switch (value.type()) {
+        case QVariant::String:
+            ret.string_values.push_back(make_pair(key.toStdString(), value.toString().toStdString()));
+            break;
+        case QVariant::Int:
+            ret.num_values.push_back(make_pair(key.toStdString(), value.toInt()));
+            break;
+        case QMetaType::Float:
+            ret.num_values.push_back(make_pair(key.toStdString(), value.toFloat()));
+            break;
+        case QVariant::Double:
+            ret.num_values.push_back(make_pair(key.toStdString(), value.toDouble()));
+            break;
+        default:
+            qDebug() << Q_FUNC_INFO << __LINE__ << value.type() << value << "not supported.";
+            break;
+        }
+    }
+
+    return ret;
+}
diff --git a/src/jubatus/client/qjubatusclient.h b/src/jubatus/client/qjubatusclient.h
new file mode 100644 (file)
index 0000000..f5ff43f
--- /dev/null
@@ -0,0 +1,78 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QJUBATUSCLIENT_H
+#define QJUBATUSCLIENT_H
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+#include "jubatus_global.h"
+
+namespace jubatus {
+    namespace client {
+        namespace common {
+            struct datum;
+        }
+    }
+}
+
+class JUBATUS_EXPORT QJubatusClient : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
+    Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(double timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
+public:
+    explicit QJubatusClient(QObject *parent = 0);
+
+    const QString &host() const;
+    int port() const;
+    const QString &name() const;
+    double timeout() const;
+
+public slots:
+    void setHost(const QString &host);
+    void setPort(int port);
+    void setName(const QString &name);
+    void setTimeout(double timeout);
+
+signals:
+    void hostChanged(const QString &host);
+    void portChanged(int port);
+    void nameChanged(const QString &name);
+    void timeoutChanged(double timeout);
+
+protected:
+    jubatus::client::common::datum convert(const QVariantMap &data) const;
+
+private:
+    class Private;
+    Private *d;
+};
+
+#endif // QJUBATUSCLIENT_H
index 76323e0..8edfd78 100644 (file)
@@ -7,9 +7,10 @@ load(qt_module)
 CONFIG += link_pkgconfig
 PKGCONFIG += jubatus-client
 
-include(./classifier/classifier.pri)
-
 DEFINES += JUBATUS_LIBRARY
-
 HEADERS += \
     jubatus_global.h
+
+include(./client/client.pri)
+include(./anomaly/anomaly.pri)
+include(./classifier/classifier.pri)