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 | 111 | if (gallery.isNull()) gallery = getMemoryGallery(input); |
| 112 | 112 | |
| 113 | 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 | 177 | return fileList; |
| 174 | 178 | } | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) |
| 131 | 131 | const QString valueString = value.toString(); |
| 132 | 132 | |
| 133 | 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 | 135 | and that it's numerical value is not relevant. */ |
| 136 | 136 | if (value.canConvert(QVariant::Double) && |
| 137 | 137 | (!valueString.startsWith('0') || (valueString == "0"))) | ... | ... |
openbr/plugins/format.cpp
| ... | ... | @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) |
| 492 | 492 | |
| 493 | 493 | /*! |
| 494 | 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 | 517 | * \brief RAW format |
| 496 | 518 | * |
| 497 | 519 | * http://www.nist.gov/srd/nistsd27.cfm | ... | ... |
openbr/plugins/qtnetwork.cpp
| ... | ... | @@ -50,55 +50,119 @@ class urlFormat : public Format |
| 50 | 50 | |
| 51 | 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 | 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 | 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 | 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 | 167 | } // namespace br |
| 104 | 168 | ... | ... |