Commit bf54835eabc6124ba47ba2f0f7ece20a93e20458
1 parent
853922ad
refactored server code
Showing
4 changed files
with
177 additions
and
87 deletions
openbr/core/core.cpp
| @@ -111,64 +111,68 @@ struct AlgorithmCore | @@ -111,64 +111,68 @@ struct AlgorithmCore | ||
| 111 | if (gallery.isNull()) gallery = getMemoryGallery(input); | 111 | if (gallery.isNull()) gallery = getMemoryGallery(input); |
| 112 | 112 | ||
| 113 | QScopedPointer<Gallery> g(Gallery::make(gallery)); | 113 | QScopedPointer<Gallery> g(Gallery::make(gallery)); |
| 114 | - if (g.isNull()) return FileList(); | ||
| 115 | - | ||
| 116 | - if (gallery.contains("read") || gallery.contains("cache")) { | ||
| 117 | - fileList = g->files(); | ||
| 118 | - } | ||
| 119 | - if (!fileList.isEmpty() && gallery.contains("cache")) | ||
| 120 | - return fileList; | ||
| 121 | - | ||
| 122 | - const TemplateList i(TemplateList::fromGallery(input)); | ||
| 123 | - if (i.isEmpty()) return fileList; // Nothing to enroll | ||
| 124 | - | ||
| 125 | - if (transform.isNull()) qFatal("Null transform."); | ||
| 126 | - const int blocks = Globals->blocks(i.size()); | ||
| 127 | - Globals->currentStep = 0; | ||
| 128 | - Globals->totalSteps = i.size(); | ||
| 129 | - Globals->startTime.start(); | ||
| 130 | - | ||
| 131 | - const bool noDuplicates = gallery.contains("noDuplicates"); | ||
| 132 | - QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); | ||
| 133 | - const int subBlockSize = 4*std::max(1, Globals->parallelism); | ||
| 134 | - const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); | ||
| 135 | - int totalCount = 0, failureCount = 0; | ||
| 136 | - double totalBytes = 0; | ||
| 137 | - for (int block=0; block<blocks; block++) { | ||
| 138 | - for (int subBlock = 0; subBlock<numSubBlocks; subBlock++) { | ||
| 139 | - TemplateList data = i.mid(block*Globals->blockSize + subBlock*subBlockSize, subBlockSize); | ||
| 140 | - if (data.isEmpty()) break; | ||
| 141 | - if (noDuplicates) | ||
| 142 | - for (int i=data.size()-1; i>=0; i--) | ||
| 143 | - if (fileNames.contains(data[i].file.name)) | ||
| 144 | - data.removeAt(i); | ||
| 145 | - const int numFiles = data.size(); | ||
| 146 | - | ||
| 147 | - if (Globals->backProject) { | ||
| 148 | - TemplateList backProjectedData; | ||
| 149 | - transform->backProject(data, backProjectedData); | ||
| 150 | - data = backProjectedData; | ||
| 151 | - } else { | ||
| 152 | - data >> *transform; | 114 | + if (g.isNull()) qFatal("Null gallery!"); |
| 115 | + | ||
| 116 | + do { | ||
| 117 | + fileList.clear(); | ||
| 118 | + | ||
| 119 | + if (gallery.contains("read") || gallery.contains("cache")) | ||
| 120 | + fileList = g->files(); | ||
| 121 | + | ||
| 122 | + if (!fileList.isEmpty() && gallery.contains("cache")) | ||
| 123 | + return fileList; | ||
| 124 | + | ||
| 125 | + const TemplateList i(TemplateList::fromGallery(input)); | ||
| 126 | + if (i.isEmpty()) return fileList; // Nothing to enroll | ||
| 127 | + | ||
| 128 | + if (transform.isNull()) qFatal("Null transform."); | ||
| 129 | + const int blocks = Globals->blocks(i.size()); | ||
| 130 | + Globals->currentStep = 0; | ||
| 131 | + Globals->totalSteps = i.size(); | ||
| 132 | + Globals->startTime.start(); | ||
| 133 | + | ||
| 134 | + const bool noDuplicates = gallery.contains("noDuplicates"); | ||
| 135 | + QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); | ||
| 136 | + const int subBlockSize = 4*std::max(1, Globals->parallelism); | ||
| 137 | + const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); | ||
| 138 | + int totalCount = 0, failureCount = 0; | ||
| 139 | + double totalBytes = 0; | ||
| 140 | + for (int block=0; block<blocks; block++) { | ||
| 141 | + for (int subBlock = 0; subBlock<numSubBlocks; subBlock++) { | ||
| 142 | + TemplateList data = i.mid(block*Globals->blockSize + subBlock*subBlockSize, subBlockSize); | ||
| 143 | + if (data.isEmpty()) break; | ||
| 144 | + if (noDuplicates) | ||
| 145 | + for (int i=data.size()-1; i>=0; i--) | ||
| 146 | + if (fileNames.contains(data[i].file.name)) | ||
| 147 | + data.removeAt(i); | ||
| 148 | + const int numFiles = data.size(); | ||
| 149 | + | ||
| 150 | + if (Globals->backProject) { | ||
| 151 | + TemplateList backProjectedData; | ||
| 152 | + transform->backProject(data, backProjectedData); | ||
| 153 | + data = backProjectedData; | ||
| 154 | + } else { | ||
| 155 | + data >> *transform; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + g->writeBlock(data); | ||
| 159 | + const FileList newFiles = data.files(); | ||
| 160 | + fileList.append(newFiles); | ||
| 161 | + | ||
| 162 | + totalCount += newFiles.size(); | ||
| 163 | + failureCount += newFiles.failures(); | ||
| 164 | + totalBytes += data.bytes<double>(); | ||
| 165 | + Globals->currentStep += numFiles; | ||
| 166 | + Globals->printStatus(); | ||
| 153 | } | 167 | } |
| 154 | - | ||
| 155 | - g->writeBlock(data); | ||
| 156 | - const FileList newFiles = data.files(); | ||
| 157 | - fileList.append(newFiles); | ||
| 158 | - | ||
| 159 | - totalCount += newFiles.size(); | ||
| 160 | - failureCount += newFiles.failures(); | ||
| 161 | - totalBytes += data.bytes<double>(); | ||
| 162 | - Globals->currentStep += numFiles; | ||
| 163 | - Globals->printStatus(); | ||
| 164 | } | 168 | } |
| 165 | - } | ||
| 166 | 169 | ||
| 167 | - const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); | ||
| 168 | - if (!Globals->quiet && (Globals->totalSteps > 1)) | ||
| 169 | - fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", | ||
| 170 | - speed, totalBytes/totalCount, failureCount, totalCount); | ||
| 171 | - Globals->totalSteps = 0; | 170 | + const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); |
| 171 | + if (!Globals->quiet && (Globals->totalSteps > 1)) | ||
| 172 | + fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", | ||
| 173 | + speed, totalBytes/totalCount, failureCount, totalCount); | ||
| 174 | + Globals->totalSteps = 0; | ||
| 175 | + } while (input.getBool("infinite")); | ||
| 172 | 176 | ||
| 173 | return fileList; | 177 | return fileList; |
| 174 | } | 178 | } |
openbr/openbr_plugin.cpp
| @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) | @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) | ||
| 131 | const QString valueString = value.toString(); | 131 | const QString valueString = value.toString(); |
| 132 | 132 | ||
| 133 | /* We assume that if the value starts with '0' | 133 | /* We assume that if the value starts with '0' |
| 134 | - then it was probably intended to to be a string UID | 134 | + then it was probably intended to be a string UID |
| 135 | and that it's numerical value is not relevant. */ | 135 | and that it's numerical value is not relevant. */ |
| 136 | if (value.canConvert(QVariant::Double) && | 136 | if (value.canConvert(QVariant::Double) && |
| 137 | (!valueString.startsWith('0') || (valueString == "0"))) | 137 | (!valueString.startsWith('0') || (valueString == "0"))) |
openbr/plugins/format.cpp
| @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) | @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) | ||
| 492 | 492 | ||
| 493 | /*! | 493 | /*! |
| 494 | * \ingroup formats | 494 | * \ingroup formats |
| 495 | + * \brief Returns an empty matrix. | ||
| 496 | + * \author Josh Klontz \cite jklontz | ||
| 497 | + */ | ||
| 498 | +class nullFormat : public Format | ||
| 499 | +{ | ||
| 500 | + Q_OBJECT | ||
| 501 | + | ||
| 502 | + Template read() const | ||
| 503 | + { | ||
| 504 | + return Template(file, Mat()); | ||
| 505 | + } | ||
| 506 | + | ||
| 507 | + void write(const Template &t) const | ||
| 508 | + { | ||
| 509 | + (void)t; | ||
| 510 | + } | ||
| 511 | +}; | ||
| 512 | + | ||
| 513 | +BR_REGISTER(Format, nullFormat) | ||
| 514 | + | ||
| 515 | +/*! | ||
| 516 | + * \ingroup formats | ||
| 495 | * \brief RAW format | 517 | * \brief RAW format |
| 496 | * | 518 | * |
| 497 | * http://www.nist.gov/srd/nistsd27.cfm | 519 | * http://www.nist.gov/srd/nistsd27.cfm |
openbr/plugins/qtnetwork.cpp
| @@ -50,55 +50,119 @@ class urlFormat : public Format | @@ -50,55 +50,119 @@ class urlFormat : public Format | ||
| 50 | 50 | ||
| 51 | BR_REGISTER(Format, urlFormat) | 51 | BR_REGISTER(Format, urlFormat) |
| 52 | 52 | ||
| 53 | -class WebServices : public QTcpServer | 53 | +/*! |
| 54 | + * \ingroup galleries | ||
| 55 | + * \brief Handle POST requests | ||
| 56 | + * \author Josh Klontz \cite jklontz | ||
| 57 | + */ | ||
| 58 | +class postGallery : public Gallery | ||
| 54 | { | 59 | { |
| 55 | Q_OBJECT | 60 | Q_OBJECT |
| 56 | 61 | ||
| 62 | + class TcpServer : public QTcpServer | ||
| 63 | + { | ||
| 64 | + QList<qintptr> socketDescriptors; | ||
| 65 | + QMutex socketDescriptorsLock; | ||
| 66 | + | ||
| 67 | + public: | ||
| 68 | + QList<qintptr> availableSocketDescriptors() | ||
| 69 | + { | ||
| 70 | + QMutexLocker locker(&socketDescriptorsLock); | ||
| 71 | + QList<qintptr> result(socketDescriptors); | ||
| 72 | + socketDescriptors.clear(); | ||
| 73 | + return result; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + void addPendingConnection(QTcpSocket *socket) | ||
| 77 | + { | ||
| 78 | + QTcpServer::addPendingConnection(socket); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + private: | ||
| 82 | + void incomingConnection(qintptr socketDescriptor) | ||
| 83 | + { | ||
| 84 | + QMutexLocker locker(&socketDescriptorsLock); | ||
| 85 | + socketDescriptors.append(socketDescriptor); | ||
| 86 | + } | ||
| 87 | + }; | ||
| 88 | + | ||
| 57 | public: | 89 | public: |
| 58 | - WebServices() | 90 | + static QScopedPointer<TcpServer> server; |
| 91 | + | ||
| 92 | + postGallery() | ||
| 59 | { | 93 | { |
| 60 | - connect(this, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); | 94 | + if (server.isNull()) { |
| 95 | + server.reset(new TcpServer()); | ||
| 96 | + server->listen(QHostAddress::Any, 8080); | ||
| 97 | + server->moveToThread(QCoreApplication::instance()->thread()); | ||
| 98 | + qDebug("Listening on %s:%d", qPrintable(server->serverAddress().toString()), server->serverPort()); | ||
| 99 | + } | ||
| 61 | } | 100 | } |
| 62 | 101 | ||
| 63 | - void listen() | 102 | +private: |
| 103 | + TemplateList readBlock(bool *done) | ||
| 64 | { | 104 | { |
| 65 | - QTcpServer::listen(QHostAddress::Any, 8080); | 105 | + *done = true; |
| 106 | + TemplateList templates; | ||
| 107 | + foreach (qintptr socketDescriptor, server->availableSocketDescriptors()) { | ||
| 108 | + File f(".post"); | ||
| 109 | + f.set("socketDescriptor", socketDescriptor); | ||
| 110 | + templates.append(f); | ||
| 111 | + } | ||
| 112 | + if (templates.isEmpty()) | ||
| 113 | + templates.append(File(".null")); | ||
| 114 | + return templates; | ||
| 66 | } | 115 | } |
| 67 | 116 | ||
| 68 | -private slots: | ||
| 69 | - void handleNewConnection() | 117 | + void write(const Template &t) |
| 70 | { | 118 | { |
| 71 | - while (hasPendingConnections()) { | ||
| 72 | - QTcpSocket *socket = QTcpServer::nextPendingConnection(); | ||
| 73 | - connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); | ||
| 74 | - connect(socket, SIGNAL(readyRead()), this, SLOT(read())); | ||
| 75 | -// socket->write("HTTP/1.1 200 OK\r\n" | ||
| 76 | -// "Content-Type: text/html; charset=UTF-8\r\n\r\n" | ||
| 77 | -// "Hello World!\r\n"); | ||
| 78 | -// socket->disconnectFromHost(); | ||
| 79 | - } | 119 | + (void) t; |
| 120 | + qFatal("Not supported!"); | ||
| 80 | } | 121 | } |
| 122 | +}; | ||
| 123 | + | ||
| 124 | +QScopedPointer<postGallery::TcpServer> postGallery::server; | ||
| 125 | + | ||
| 126 | +BR_REGISTER(Gallery, postGallery) | ||
| 81 | 127 | ||
| 82 | - void read() | 128 | +/*! |
| 129 | + * \ingroup formats | ||
| 130 | + * \brief Handle POST requests | ||
| 131 | + * \author Josh Klontz \cite jklontz | ||
| 132 | + */ | ||
| 133 | +class postFormat : public Format | ||
| 134 | +{ | ||
| 135 | + Q_OBJECT | ||
| 136 | + | ||
| 137 | + Template read() const | ||
| 83 | { | 138 | { |
| 84 | - QTcpSocket *socket = dynamic_cast<QTcpSocket*>(QObject::sender()); | ||
| 85 | - if (socket == NULL) return; | 139 | + Template t(file); |
| 140 | + qDebug() << t.file.flat(); | ||
| 141 | + QTcpSocket *socket = new QTcpSocket(); | ||
| 142 | + socket->setSocketDescriptor(file.get<qintptr>("socketDescriptor")); | ||
| 143 | + | ||
| 144 | + socket->write("HTTP/1.1 200 OK\r\n" | ||
| 145 | + "Content-Type: text/html; charset=UTF-8\r\n\r\n" | ||
| 146 | + "Hello World!\r\n"); | ||
| 147 | + socket->waitForBytesWritten(); | ||
| 148 | + | ||
| 149 | + socket->waitForReadyRead(); | ||
| 86 | QByteArray data = socket->readAll(); | 150 | QByteArray data = socket->readAll(); |
| 87 | - qDebug() << data; | 151 | + t.append(imdecode(Mat(1, data.size(), CV_8UC1, data.data()), 1)); |
| 152 | + | ||
| 153 | + socket->close(); | ||
| 154 | + delete socket; | ||
| 155 | + return t; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + void write(const Template &t) const | ||
| 159 | + { | ||
| 160 | + (void) t; | ||
| 161 | + qFatal("Not supported!"); | ||
| 88 | } | 162 | } |
| 89 | }; | 163 | }; |
| 90 | 164 | ||
| 91 | -//static void web() | ||
| 92 | -//{ | ||
| 93 | -// static WebServices webServices; | ||
| 94 | -// if (webServices.isListening()) | ||
| 95 | -// return; | ||
| 96 | - | ||
| 97 | -// webServices.listen(); | ||
| 98 | -// qDebug("Listening on %s:%d", qPrintable(webServices.serverAddress().toString()), webServices.serverPort()); | ||
| 99 | -// while (true) | ||
| 100 | -// QCoreApplication::processEvents(); | ||
| 101 | -//} | 165 | +BR_REGISTER(Format, postFormat) |
| 102 | 166 | ||
| 103 | } // namespace br | 167 | } // namespace br |
| 104 | 168 |