mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-10-05 19:18:01 +08:00
fix
This commit is contained in:
parent
cee99c923d
commit
2e5c5f3fc0
|
@ -42,21 +42,10 @@ static void usp_end_ir_web()
|
|||
U_DELETE(footer)
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern U_EXPORT void runDynamicPage_ir_web(int param);
|
||||
U_EXPORT void runDynamicPage_ir_web(int param)
|
||||
static void usp_body_ir_web()
|
||||
{
|
||||
U_TRACE(0, "::runDynamicPage_ir_web(%d)", param)
|
||||
U_TRACE(5, "::usp_body_ir_web()")
|
||||
|
||||
|
||||
if (param)
|
||||
{
|
||||
if (param == U_DPAGE_INIT) { usp_init_ir_web(); return; }
|
||||
if (param == U_DPAGE_DESTROY) { usp_end_ir_web(); return; }
|
||||
return;
|
||||
}
|
||||
|
||||
UHTTP::mime_index = U_html;
|
||||
if (UHTTP::getDataSession() == false) UHTTP::setSessionCookie();
|
||||
const char* ref = "?ext=help";
|
||||
uint32_t num_args = UHTTP::processForm() / 2;
|
||||
|
@ -190,7 +179,25 @@ extern U_EXPORT void runDynamicPage_ir_web(int param);
|
|||
(void) UClientImage_Base::wbuffer->append(
|
||||
U_CONSTANT_TO_PARAM(" </div>\n</body>\n</html>")
|
||||
);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern U_EXPORT void runDynamicPage_ir_web(int param);
|
||||
U_EXPORT void runDynamicPage_ir_web(int param)
|
||||
{
|
||||
U_TRACE(0, "::runDynamicPage_ir_web(%d)", param)
|
||||
|
||||
|
||||
if (param)
|
||||
{
|
||||
if (param == U_DPAGE_INIT) { usp_init_ir_web(); return; }
|
||||
if (param == U_DPAGE_DESTROY) { usp_end_ir_web(); return; }
|
||||
return;
|
||||
}
|
||||
|
||||
usp_body_ir_web();
|
||||
UHTTP::putDataSession();
|
||||
U_http_info.endHeader = 0;
|
||||
UHTTP::mime_index = U_html;
|
||||
|
||||
} }
|
|
@ -97,13 +97,6 @@ public:
|
|||
U_RETURN(_length == 0);
|
||||
}
|
||||
|
||||
void setEmpty()
|
||||
{
|
||||
U_TRACE_NO_PARAM(0, "UVector<void*>::setEmpty()")
|
||||
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
// Make room for a total of n element
|
||||
|
||||
void reserve(uint32_t n);
|
||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#ifndef U_MYSQL_STRING_SIZE
|
||||
#define U_MYSQL_STRING_SIZE 8192
|
||||
#define U_MYSQL_STRING_SIZE (8192-sizeof(USqlStatementBindResult))
|
||||
#endif
|
||||
|
||||
class U_EXPORT UMySqlStatementBindParam : public USqlStatementBindParam {
|
||||
|
|
|
@ -374,6 +374,18 @@ public:
|
|||
bool setBindParam( UOrmDriver* pdrv);
|
||||
void setBindResult(UOrmDriver* pdrv);
|
||||
|
||||
void prepareStatement(UOrmDriver* pdrv)
|
||||
{
|
||||
U_TRACE(0, "UPgSqlStatement::prepareStatement(%p)", pdrv)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pdrv)
|
||||
U_INTERNAL_ASSERT_EQUALS(pHandle, U_NULLPTR)
|
||||
|
||||
pHandle = (PGresult*) U_SYSCALL(PQprepare, "%p,%S,%S,%d,%p",
|
||||
(PGconn*)pdrv->UOrmDriver::connection,
|
||||
stmtName, stmt.data(), num_bind_param, paramTypes);
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
|
||||
|
@ -524,6 +536,27 @@ public:
|
|||
bool asyncPipelineSendQueryPrepared(USqlStatement* pstmt, uint32_t i);
|
||||
bool asyncPipelineSendQuery(USqlStatement* pstmt, const char* stmt, uint32_t len, uint32_t n);
|
||||
|
||||
// SERVICES
|
||||
|
||||
PGresult* execPrepared(USqlStatement* pstmt)
|
||||
{
|
||||
U_TRACE(0, "UOrmDriverPgSql::execPrepared(%p)", pstmt)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pstmt)
|
||||
U_INTERNAL_ASSERT_POINTER(UOrmDriver::connection)
|
||||
|
||||
PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%d,%p,%p,%p,%d",
|
||||
(PGconn*)UOrmDriver::connection,
|
||||
((UPgSqlStatement*)pstmt)->stmtName,
|
||||
pstmt->num_bind_param,
|
||||
((UPgSqlStatement*)pstmt)->paramValues,
|
||||
((UPgSqlStatement*)pstmt)->paramLengths,
|
||||
((UPgSqlStatement*)pstmt)->paramFormats,
|
||||
((UPgSqlStatement*)pstmt)->resultFormat); // is zero/one to obtain results in text/binary format
|
||||
|
||||
U_RETURN_POINTER(res, PGresult);
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
void* getConnection() __pure;
|
||||
bool connect(const UString& option);
|
||||
|
||||
UOrmDriver* getDriver() const { return pdrv; }
|
||||
|
||||
// statement that should only be executed once and immediately
|
||||
|
||||
bool query(const char* query, uint32_t query_len);
|
||||
|
@ -212,6 +214,10 @@ public:
|
|||
UOrmStatement(UOrmSession& session, const char* query, uint32_t query_len);
|
||||
~UOrmStatement();
|
||||
|
||||
// will be typecast into conn-specific type
|
||||
|
||||
USqlStatement* getStatement() const { return pstmt; }
|
||||
|
||||
// Execute the statement
|
||||
|
||||
void execute();
|
||||
|
|
|
@ -326,13 +326,25 @@ public:
|
|||
|
||||
U_CHECK_MEMORY
|
||||
|
||||
U_INTERNAL_DUMP("str = %.*S", U_min(_length, n), str)
|
||||
U_INTERNAL_DUMP("str(%u) = %.*S", _length, U_min(_length, n), str)
|
||||
|
||||
if (*str != *s) U_RETURN(*(const unsigned char*)str - *(const unsigned char*)s);
|
||||
U_INTERNAL_ASSERT_MAJOR(n, 0)
|
||||
|
||||
int r = memcmp(str+1, s+1, U_min(_length, n)-1);
|
||||
int r = *(const unsigned char*)str - *(const unsigned char*)s;
|
||||
|
||||
if (r == 0) r = (_length - n);
|
||||
if (r == 0)
|
||||
{
|
||||
uint32_t len = U_min(_length, n);
|
||||
|
||||
if (len > 1)
|
||||
{
|
||||
r = memcmp(str+1, s+1, len-1);
|
||||
|
||||
if (r) U_RETURN(r);
|
||||
}
|
||||
|
||||
r = _length < n ? -1 : _length > n; // _length - n;
|
||||
}
|
||||
|
||||
U_RETURN(r);
|
||||
}
|
||||
|
@ -546,9 +558,7 @@ public:
|
|||
U_INTERNAL_ASSERT_MAJOR(n, 0)
|
||||
U_INTERNAL_ASSERT(_capacity >= n)
|
||||
|
||||
U_MEMCPY((char*)str, s, n);
|
||||
|
||||
((char*)str)[(_length = n)] = '\0';
|
||||
(void) memcpy((char*)str, s, _length = n);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include <ulib/utility/xml_escape.h>
|
||||
#include <ulib/net/server/client_image.h>
|
||||
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
# include <ulib/orm/driver/orm_driver_pgsql.h>
|
||||
#endif
|
||||
|
||||
class Fortune {
|
||||
public:
|
||||
// Check for memory error
|
||||
|
@ -22,30 +26,21 @@ public:
|
|||
uint32_t id;
|
||||
UString message;
|
||||
|
||||
Fortune()
|
||||
Fortune(uint32_t _id) : id(_id), message(101U)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "")
|
||||
|
||||
// coverity[uninit_ctor]
|
||||
# ifdef U_COVERITY_FALSE_POSITIVE
|
||||
id = 0;
|
||||
# endif
|
||||
U_TRACE_CTOR(5, Fortune, "%u", _id)
|
||||
}
|
||||
|
||||
Fortune(uint32_t _id, const UString& _message) : id(_id), message(100U)
|
||||
Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
|
||||
|
||||
UXMLEscape::encode(_message, message);
|
||||
}
|
||||
|
||||
Fortune(const Fortune& f) : id(f.id), message(100U)
|
||||
Fortune(const Fortune& f) : id(f.id), message(f.message)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "%p", &f)
|
||||
|
||||
U_MEMORY_TEST_COPY(f)
|
||||
|
||||
UXMLEscape::encode(f.message, message);
|
||||
}
|
||||
|
||||
~Fortune()
|
||||
|
@ -113,33 +108,51 @@ public:
|
|||
stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
|
||||
}
|
||||
|
||||
static char* pwbuffer;
|
||||
static Fortune* pfortune;
|
||||
static Fortune* pfortune2add;
|
||||
static uint32_t uid;
|
||||
static UString* pmessage;
|
||||
static UVector<Fortune*>* pvfortune;
|
||||
|
||||
static UOrmSession* psql_fortune;
|
||||
static UOrmStatement* pstmt_fortune;
|
||||
|
||||
static void replace(uint32_t i, uint32_t _id, const char* msg, uint32_t len)
|
||||
{
|
||||
U_TRACE(0, "Fortune::replace(%u,%u,%.*S,%u)", i, _id, len, msg, len)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
|
||||
Fortune* elem = pvfortune->at(1+i);
|
||||
|
||||
elem->id = _id;
|
||||
|
||||
UXMLEscape::encode(msg, len, elem->message);
|
||||
}
|
||||
|
||||
static void replace(uint32_t i) { replace(i, uid, U_STRING_TO_PARAM(*pmessage)); }
|
||||
static void replace(uint32_t i, uint32_t _id) { replace(i, _id, U_STRING_TO_PARAM(*pmessage)); }
|
||||
static void replace(uint32_t i, const UString& message) { replace(i, i+1, U_STRING_TO_PARAM(message)); }
|
||||
static void replace(uint32_t i, uint32_t _id, const UString& message) { replace(i, _id, U_STRING_TO_PARAM(message)); }
|
||||
|
||||
static void doQuery(vPF handlerQuery)
|
||||
{
|
||||
U_TRACE(0, "Fortune::doQuery(%p)", handlerQuery)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pfortune2add)
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
|
||||
pwbuffer = UClientImage_Base::wbuffer->pend();
|
||||
char* pwbuffer = UClientImage_Base::wbuffer->pend();
|
||||
|
||||
(void) memcpy(pwbuffer, U_CONSTANT_TO_PARAM("<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>"));
|
||||
pwbuffer += U_CONSTANT_SIZE("<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
|
||||
|
||||
pvfortune->push(pfortune2add);
|
||||
Fortune* elem = pvfortune->at(0);
|
||||
|
||||
elem->id = 0;
|
||||
elem->message.rep->replace(U_CONSTANT_TO_PARAM("Additional fortune added at request time."));
|
||||
|
||||
handlerQuery();
|
||||
|
||||
pvfortune->sort(Fortune::cmp_obj);
|
||||
|
||||
Fortune* elem;
|
||||
|
||||
for (uint32_t sz, i = 0, n = pvfortune->size(); i < n; ++i)
|
||||
{
|
||||
elem = pvfortune->at(i);
|
||||
|
@ -159,12 +172,8 @@ public:
|
|||
u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
|
||||
u_put_unalignedp16(pwbuffer+8, U_MULTICHAR_CONSTANT16('r','>'));
|
||||
pwbuffer += 10;
|
||||
|
||||
if (elem != pfortune2add) U_DELETE(elem)
|
||||
}
|
||||
|
||||
pvfortune->setEmpty();
|
||||
|
||||
(void) memcpy(pwbuffer, U_CONSTANT_TO_PARAM("</table></body></html>"));
|
||||
|
||||
UClientImage_Base::wbuffer->size_adjust(pwbuffer + U_CONSTANT_SIZE("</table></body></html>"));
|
||||
|
@ -176,9 +185,18 @@ public:
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "Fortune::handlerFork()")
|
||||
|
||||
U_NEW_STRING(pmessage, UString(101U));
|
||||
|
||||
U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
|
||||
|
||||
U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
|
||||
Fortune* elem;
|
||||
|
||||
for (uint32_t i = 0; i < 13; ++i)
|
||||
{
|
||||
U_NEW(Fortune, elem, Fortune(i));
|
||||
|
||||
pvfortune->push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
static void handlerForkSql()
|
||||
|
@ -202,11 +220,9 @@ public:
|
|||
|
||||
U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
|
||||
|
||||
U_NEW(Fortune, pfortune, Fortune);
|
||||
|
||||
pstmt_fortune->into(*pfortune);
|
||||
|
||||
handlerFork();
|
||||
|
||||
pstmt_fortune->into(uid, *pmessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +231,11 @@ public:
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "Fortune::handlerEnd()")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pmessage)
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
U_INTERNAL_ASSERT_POINTER(pfortune2add)
|
||||
|
||||
U_DELETE(pmessage)
|
||||
U_DELETE(pvfortune)
|
||||
U_DELETE(pfortune2add)
|
||||
}
|
||||
|
||||
static void handlerEndSql()
|
||||
|
@ -230,7 +246,6 @@ public:
|
|||
{
|
||||
handlerEnd();
|
||||
|
||||
U_DELETE(pfortune)
|
||||
U_DELETE(psql_fortune)
|
||||
U_DELETE(pstmt_fortune)
|
||||
|
||||
|
@ -244,7 +259,4 @@ public:
|
|||
private:
|
||||
U_DISALLOW_ASSIGN(Fortune)
|
||||
};
|
||||
|
||||
// override the default...
|
||||
template <> inline void u_destroy(const Fortune** ptr, uint32_t n) { U_TRACE(0,"u_destroy<Fortune*>(%p,%u)", ptr, n) }
|
||||
#endif
|
||||
|
|
|
@ -5,28 +5,75 @@ TechEmpower Web Framework Benchmarks
|
|||
<!--#declaration
|
||||
#include "fortune.h"
|
||||
|
||||
static vPF handle_query;
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
static UOrmDriver* pdrv;
|
||||
static USqlStatement* pstmt;
|
||||
#endif
|
||||
|
||||
static void handlerQuery()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::handlerQuery()")
|
||||
|
||||
Fortune* elem;
|
||||
uint32_t i = 0;
|
||||
|
||||
Fortune::pstmt_fortune->execute();
|
||||
|
||||
do {
|
||||
U_NEW(Fortune, elem, Fortune(*Fortune::pfortune));
|
||||
|
||||
Fortune::pvfortune->push(elem);
|
||||
Fortune::replace(i++);
|
||||
}
|
||||
while (Fortune::pstmt_fortune->nextRow());
|
||||
}
|
||||
|
||||
static void usp_fork_fortune() { Fortune::handlerForkSql(); }
|
||||
static void handlerQueryPGSQL()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::handlerQueryPGSQL()")
|
||||
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
int sz;
|
||||
char* id;
|
||||
char* ptr;
|
||||
PGresult* res = ((UOrmDriverPgSql*)pdrv)->execPrepared(pstmt);
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 2)
|
||||
|
||||
for (uint32_t i = 0, n = U_SYSCALL(PQntuples, "%p", res); i < n; ++i)
|
||||
{
|
||||
id = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, i, 0);
|
||||
ptr = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, i, 1);
|
||||
sz = U_SYSCALL(PQgetlength, "%p,%d,%d", res, i, 1);
|
||||
|
||||
Fortune::replace(i, ntohl(*(uint32_t*)id), ptr, sz);
|
||||
}
|
||||
|
||||
U_SYSCALL_VOID(PQclear, "%p", res);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usp_fork_fortune()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::usp_fork_fortune()")
|
||||
|
||||
Fortune::handlerForkSql();
|
||||
|
||||
if (UOrmDriver::isPGSQL() == false) handle_query = handlerQuery;
|
||||
else
|
||||
{
|
||||
handle_query = handlerQueryPGSQL;
|
||||
|
||||
# ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
pdrv = Fortune::psql_fortune->getDriver();
|
||||
pstmt = Fortune::pstmt_fortune->getStatement();
|
||||
|
||||
((UPgSqlStatement*)pstmt)->prepareStatement(pdrv);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void usp_end_fortune() { Fortune::handlerEndSql(); }
|
||||
#endif
|
||||
-->
|
||||
<!--#code
|
||||
Fortune::doQuery(handlerQuery);
|
||||
Fortune::doQuery(handle_query);
|
||||
-->
|
||||
|
|
|
@ -23,19 +23,18 @@ public:
|
|||
{
|
||||
U_TRACE(0, "FortuneNoSql::handlerQueryMongoDB()")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(Fortune::pmessage)
|
||||
|
||||
# ifdef USE_MONGODB
|
||||
(void) mc->findAll();
|
||||
|
||||
for (uint32_t i = 0, n = mc->vitem.size(); i < n; ++i)
|
||||
{
|
||||
Fortune* item;
|
||||
UString result;
|
||||
(void) U_JFIND(mc->vitem[i], "message", *Fortune::pmessage);
|
||||
|
||||
(void) U_JFIND(mc->vitem[i], "message", result);
|
||||
Fortune::replace(i, i+1);
|
||||
|
||||
U_NEW(Fortune, item, Fortune(i+1, result));
|
||||
|
||||
Fortune::pvfortune->push(item);
|
||||
Fortune::pmessage->clear();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
@ -84,14 +83,7 @@ public:
|
|||
|
||||
(void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
|
||||
|
||||
for (uint32_t i = 0, n = rc->vitem.size(); i < n; ++i)
|
||||
{
|
||||
Fortune* item;
|
||||
|
||||
U_NEW(Fortune, item, Fortune(i+1, rc->vitem[i]));
|
||||
|
||||
Fortune::pvfortune->push(item);
|
||||
}
|
||||
for (uint32_t i = 0, n = rc->vitem.size(); i < n; ++i) Fortune::replace(i, rc->vitem[i]);
|
||||
}
|
||||
|
||||
static void handlerForkREDIS()
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
#include "fortune.h"
|
||||
|
||||
char* Fortune::pwbuffer;
|
||||
Fortune* Fortune::pfortune;
|
||||
Fortune* Fortune::pfortune2add;
|
||||
uint32_t Fortune::uid;
|
||||
UString* Fortune::pmessage;
|
||||
UOrmSession* Fortune::psql_fortune;
|
||||
UOrmStatement* Fortune::pstmt_fortune;
|
||||
UVector<Fortune*>* Fortune::pvfortune;
|
||||
|
|
|
@ -11,7 +11,7 @@ do
|
|||
OBJ="$OBJ $(basename $i .usp).la"
|
||||
done
|
||||
|
||||
UMEMPOOL="0,0,0,48,-20,-20,-20,-20,0" make -j6 $OBJ
|
||||
UMEMPOOL="0,0,0,48,-20,-20,-20,-20,0" make -i -j6 $OBJ
|
||||
|
||||
rm -f .libs/lib*.so
|
||||
|
||||
|
|
|
@ -345,8 +345,6 @@ public:
|
|||
|
||||
if (token)
|
||||
{
|
||||
if (U_STRING_FIND(token, 0, "return") != U_NOT_FOUND) U_WARNING("use of 'return' inside usp can cause problem, please avoid it");
|
||||
|
||||
token = UStringExt::substitute(token, '\n', U_CONSTANT_TO_PARAM("\n\t"));
|
||||
|
||||
(void) output0.reserve(20U + token.size());
|
||||
|
@ -364,8 +362,6 @@ public:
|
|||
|
||||
if (token)
|
||||
{
|
||||
if (U_STRING_FIND(token, 0, "return") != U_NOT_FOUND) U_WARNING("use of 'return' inside usp can cause problem, please avoid it");
|
||||
|
||||
token = UStringExt::substitute(token, '\n', U_CONSTANT_TO_PARAM("\n\t"));
|
||||
|
||||
(void) output0.reserve(20U + token.size());
|
||||
|
@ -387,8 +383,6 @@ public:
|
|||
|
||||
if (token)
|
||||
{
|
||||
if (U_STRING_FIND(token, 0, "return") != U_NOT_FOUND) U_WARNING("use of 'return' inside usp can cause problem, please avoid it");
|
||||
|
||||
token = UStringExt::substitute(token, '\n', U_CONSTANT_TO_PARAM("\n\t"));
|
||||
|
||||
(void) output0.reserve(20U + token.size());
|
||||
|
@ -488,13 +482,13 @@ public:
|
|||
|
||||
U_ASSERT(encoded.isQuoted())
|
||||
|
||||
(void) output2.reserve(200U);
|
||||
(void) output1.reserve(200U);
|
||||
(void) http_header.reserve(200U + encoded.size());
|
||||
|
||||
(void) http_header.snprintf(U_CONSTANT_TO_PARAM("\n\tU_ASSERT_EQUALS(UClientImage_Base::wbuffer->findEndHeader(),false)"
|
||||
"\n\t(void) UClientImage_Base::wbuffer->insert(0, U_CONSTANT_TO_PARAM(%v));\n\t\n"), encoded.rep);
|
||||
|
||||
(void) output2.snprintf_add(U_CONSTANT_TO_PARAM("\n\tU_http_info.endHeader = %.*s%u;\n"), bheader ? U_CONSTANT_SIZE("(uint32_t)-") : 0, "(uint32_t)-", n);
|
||||
(void) output1.snprintf_add(U_CONSTANT_TO_PARAM("\n\tU_http_info.endHeader = %.*s%u;\n"), bheader ? U_CONSTANT_SIZE("(uint32_t)-") : 0, "(uint32_t)-", n);
|
||||
}
|
||||
else if (strncmp(directive, U_CONSTANT_TO_PARAM("number")) == 0)
|
||||
{
|
||||
|
@ -750,21 +744,20 @@ loop: distance = t.getDistance();
|
|||
bopen, // usp_open
|
||||
bclose; // usp_close
|
||||
|
||||
char ptr1[100] = { '\0' };
|
||||
char ptr2[100] = { '\0' };
|
||||
char ptr3[100] = { '\0' };
|
||||
char ptr4[100] = { '\0' };
|
||||
char ptr5[100] = { '\0' };
|
||||
char ptr6[100] = { '\0' };
|
||||
char ptr7[100] = { '\0' };
|
||||
const char* ptr8 = "";
|
||||
char ptr1[100] = { '\0' };
|
||||
char ptr2[100] = { '\0' };
|
||||
char ptr3[100] = { '\0' };
|
||||
char ptr4[100] = { '\0' };
|
||||
char ptr5[100] = { '\0' };
|
||||
char ptr6[100] = { '\0' };
|
||||
char ptr7[100] = { '\0' };
|
||||
|
||||
# ifndef U_CACHE_REQUEST_DISABLE
|
||||
if (usp.c_char(4) == '#' &&
|
||||
u__isspace(usp.c_char(5)) &&
|
||||
u_get_unalignedp32(usp.data()) == U_MULTICHAR_CONSTANT32('<','!','-','-')) // <!--# --> (comment)
|
||||
{
|
||||
ptr8 = "\n\tUClientImage_Base::setRequestNoCache();\n\t\n";
|
||||
(void) output1.append(U_CONSTANT_TO_PARAM("\n\tUClientImage_Base::setRequestNoCache();\n\t\n"));
|
||||
}
|
||||
# endif
|
||||
|
||||
|
@ -841,12 +834,35 @@ loop: distance = t.getDistance();
|
|||
|
||||
if (http_header.empty())
|
||||
{
|
||||
if (is_html) (void) http_header.append(U_CONSTANT_TO_PARAM("\n\tUHTTP::mime_index = U_html;\n"));
|
||||
|
||||
(void) output2.append(U_CONSTANT_TO_PARAM("\n\tU_http_info.endHeader = 0;\n"));
|
||||
(void) output1.append(U_CONSTANT_TO_PARAM("\n\tU_http_info.endHeader = 0;\n"));
|
||||
if (is_html) (void) output1.append(U_CONSTANT_TO_PARAM("\n\tUHTTP::mime_index = U_html;\n"));
|
||||
}
|
||||
|
||||
UString result(1024U + declaration.size() + http_header.size() + output0.size() + output1.size() + output2.size() + vars.size());
|
||||
// NB: we check for presence of 'return' inside the code...
|
||||
|
||||
if (U_STRING_FIND(output0, 0, "return") != U_NOT_FOUND)
|
||||
{
|
||||
(void) declaration.reserve(200U + vars.size() + output0.size());
|
||||
|
||||
declaration.snprintf_add(U_CONSTANT_TO_PARAM(
|
||||
"\n\t\nstatic void usp_body_%.*s()\n"
|
||||
"{\n"
|
||||
"\tU_TRACE(5, \"::usp_body_%.*s()\")\n"
|
||||
"\t\n"
|
||||
"%v"
|
||||
"%v"
|
||||
"\n}"),
|
||||
basename_sz, basename_ptr,
|
||||
basename_sz, basename_ptr,
|
||||
vars.rep,
|
||||
output0.rep);
|
||||
|
||||
vars.clear();
|
||||
|
||||
output0.snprintf(U_CONSTANT_TO_PARAM("\n\tusp_body_%.*s();\n"), basename_sz, basename_ptr);
|
||||
}
|
||||
|
||||
UString result(1024U + declaration.size() + http_header.size() + vars.size() + output0.size() + output1.size());
|
||||
|
||||
result.snprintf(U_CONSTANT_TO_PARAM(
|
||||
"// %.*s.cpp - dynamic page translation (%.*s.usp => %.*s.cpp)\n"
|
||||
|
@ -878,8 +894,6 @@ loop: distance = t.getDistance();
|
|||
"\t\n"
|
||||
"%v"
|
||||
"%v"
|
||||
"%s"
|
||||
"%v"
|
||||
"%v"
|
||||
"%v"
|
||||
"\t\n"
|
||||
|
@ -902,10 +916,8 @@ loop: distance = t.getDistance();
|
|||
ptr7,
|
||||
vcode.rep,
|
||||
http_header.rep,
|
||||
ptr8,
|
||||
output0.rep,
|
||||
output1.rep,
|
||||
output2.rep);
|
||||
output1.rep);
|
||||
|
||||
UString name(200U);
|
||||
|
||||
|
@ -917,7 +929,7 @@ loop: distance = t.getDistance();
|
|||
private:
|
||||
UTokenizer t;
|
||||
UVector<UString> vdefine;
|
||||
UString pinclude, usp, token, output0, output1, output2, declaration, vcode, http_header, sseloop, vars;
|
||||
UString pinclude, usp, token, output0, output1, declaration, vcode, http_header, sseloop, vars;
|
||||
const char* basename_ptr;
|
||||
uint32_t basename_sz;
|
||||
bool bvar, bsession, bstorage, bfirst_pass, is_html, test_if_html, bpreprocessing_failed;
|
||||
|
|
|
@ -442,7 +442,12 @@ void UMySqlStatement::setStringBindedAsResult()
|
|||
{
|
||||
result = vresult[i];
|
||||
|
||||
if (result->type == string_type) ((UMySqlStatementBindResult*)result)->setString();
|
||||
if (result->type == string_type)
|
||||
{
|
||||
U_INTERNAL_ASSERT_MINOR(result->length, U_MYSQL_STRING_SIZE)
|
||||
|
||||
((UMySqlStatementBindResult*)result)->setString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -337,9 +337,7 @@ bool UPgSqlStatement::setBindParam(UOrmDriver* pdrv)
|
|||
* numbers higher than nParams; data types will be inferred for these symbols as well
|
||||
*/
|
||||
|
||||
pHandle = (PGresult*) U_SYSCALL(PQprepare, "%p,%S,%S,%d,%p",
|
||||
(PGconn*)pdrv->UOrmDriver::connection,
|
||||
stmtName, stmt.data(), num_bind_param, paramTypes);
|
||||
prepareStatement(pdrv);
|
||||
|
||||
if (pHandle == U_NULLPTR ||
|
||||
U_SYSCALL(PQresultStatus, "%p", (PGresult*)pHandle) != PGRES_COMMAND_OK)
|
||||
|
@ -381,7 +379,7 @@ bool UPgSqlStatement::setBindParam(UOrmDriver* pdrv)
|
|||
|
||||
num_bind_result = U_SYSCALL(PQnfields, "%p", res);
|
||||
|
||||
# ifdef DEBUG
|
||||
# ifdef DEBUG
|
||||
uint32_t i;
|
||||
Oid paramtype;
|
||||
|
||||
|
@ -402,7 +400,7 @@ bool UPgSqlStatement::setBindParam(UOrmDriver* pdrv)
|
|||
|
||||
U_INTERNAL_DUMP("result[%u] (%s): size = %d type = %d format = %d", i, fname, fsize, paramtype, fformat)
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
if (num_bind_param)
|
||||
|
@ -535,14 +533,7 @@ void UOrmDriverPgSql::execute(USqlStatement* pstmt)
|
|||
|
||||
if (((UPgSqlStatement*)pstmt)->setBindParam(this))
|
||||
{
|
||||
PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%d,%p,%p,%p,%d",
|
||||
(PGconn*)UOrmDriver::connection,
|
||||
((UPgSqlStatement*)pstmt)->stmtName,
|
||||
pstmt->num_bind_param,
|
||||
((UPgSqlStatement*)pstmt)->paramValues,
|
||||
((UPgSqlStatement*)pstmt)->paramLengths,
|
||||
((UPgSqlStatement*)pstmt)->paramFormats,
|
||||
((UPgSqlStatement*)pstmt)->resultFormat); // is zero/one to obtain results in text/binary format
|
||||
PGresult* res = execPrepared(pstmt);
|
||||
|
||||
if (checkExecution(res) == false) return;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
0142
|
||||
0173
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include <ulib/utility/xml_escape.h>
|
||||
#include <ulib/net/server/client_image.h>
|
||||
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
# include <ulib/orm/driver/orm_driver_pgsql.h>
|
||||
#endif
|
||||
|
||||
class Fortune {
|
||||
public:
|
||||
// Check for memory error
|
||||
|
@ -22,30 +26,21 @@ public:
|
|||
uint32_t id;
|
||||
UString message;
|
||||
|
||||
Fortune()
|
||||
Fortune(uint32_t _id) : id(_id), message(101U)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "")
|
||||
|
||||
// coverity[uninit_ctor]
|
||||
# ifdef U_COVERITY_FALSE_POSITIVE
|
||||
id = 0;
|
||||
# endif
|
||||
U_TRACE_CTOR(5, Fortune, "%u", _id)
|
||||
}
|
||||
|
||||
Fortune(uint32_t _id, const UString& _message) : id(_id), message(100U)
|
||||
Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
|
||||
|
||||
UXMLEscape::encode(_message, message);
|
||||
}
|
||||
|
||||
Fortune(const Fortune& f) : id(f.id), message(100U)
|
||||
Fortune(const Fortune& f) : id(f.id), message(f.message)
|
||||
{
|
||||
U_TRACE_CTOR(5, Fortune, "%p", &f)
|
||||
|
||||
U_MEMORY_TEST_COPY(f)
|
||||
|
||||
UXMLEscape::encode(f.message, message);
|
||||
}
|
||||
|
||||
~Fortune()
|
||||
|
@ -113,33 +108,51 @@ public:
|
|||
stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
|
||||
}
|
||||
|
||||
static char* pwbuffer;
|
||||
static Fortune* pfortune;
|
||||
static Fortune* pfortune2add;
|
||||
static uint32_t uid;
|
||||
static UString* pmessage;
|
||||
static UVector<Fortune*>* pvfortune;
|
||||
|
||||
static UOrmSession* psql_fortune;
|
||||
static UOrmStatement* pstmt_fortune;
|
||||
|
||||
static void replace(uint32_t i, uint32_t _id, const char* msg, uint32_t len)
|
||||
{
|
||||
U_TRACE(0, "Fortune::replace(%u,%u,%.*S,%u)", i, _id, len, msg, len)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
|
||||
Fortune* elem = pvfortune->at(1+i);
|
||||
|
||||
elem->id = _id;
|
||||
|
||||
UXMLEscape::encode(msg, len, elem->message);
|
||||
}
|
||||
|
||||
static void replace(uint32_t i) { replace(i, uid, U_STRING_TO_PARAM(*pmessage)); }
|
||||
static void replace(uint32_t i, uint32_t _id) { replace(i, _id, U_STRING_TO_PARAM(*pmessage)); }
|
||||
static void replace(uint32_t i, const UString& message) { replace(i, i+1, U_STRING_TO_PARAM(message)); }
|
||||
static void replace(uint32_t i, uint32_t _id, const UString& message) { replace(i, _id, U_STRING_TO_PARAM(message)); }
|
||||
|
||||
static void doQuery(vPF handlerQuery)
|
||||
{
|
||||
U_TRACE(0, "Fortune::doQuery(%p)", handlerQuery)
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pfortune2add)
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
|
||||
pwbuffer = UClientImage_Base::wbuffer->pend();
|
||||
char* pwbuffer = UClientImage_Base::wbuffer->pend();
|
||||
|
||||
(void) memcpy(pwbuffer, U_CONSTANT_TO_PARAM("<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>"));
|
||||
pwbuffer += U_CONSTANT_SIZE("<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
|
||||
|
||||
pvfortune->push(pfortune2add);
|
||||
Fortune* elem = pvfortune->at(0);
|
||||
|
||||
elem->id = 0;
|
||||
elem->message.rep->replace(U_CONSTANT_TO_PARAM("Additional fortune added at request time."));
|
||||
|
||||
handlerQuery();
|
||||
|
||||
pvfortune->sort(Fortune::cmp_obj);
|
||||
|
||||
Fortune* elem;
|
||||
|
||||
for (uint32_t sz, i = 0, n = pvfortune->size(); i < n; ++i)
|
||||
{
|
||||
elem = pvfortune->at(i);
|
||||
|
@ -159,12 +172,8 @@ public:
|
|||
u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
|
||||
u_put_unalignedp16(pwbuffer+8, U_MULTICHAR_CONSTANT16('r','>'));
|
||||
pwbuffer += 10;
|
||||
|
||||
if (elem != pfortune2add) U_DELETE(elem)
|
||||
}
|
||||
|
||||
pvfortune->setEmpty();
|
||||
|
||||
(void) memcpy(pwbuffer, U_CONSTANT_TO_PARAM("</table></body></html>"));
|
||||
|
||||
UClientImage_Base::wbuffer->size_adjust(pwbuffer + U_CONSTANT_SIZE("</table></body></html>"));
|
||||
|
@ -176,9 +185,18 @@ public:
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "Fortune::handlerFork()")
|
||||
|
||||
U_NEW_STRING(pmessage, UString(101U));
|
||||
|
||||
U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
|
||||
|
||||
U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
|
||||
Fortune* elem;
|
||||
|
||||
for (uint32_t i = 0; i < 13; ++i)
|
||||
{
|
||||
U_NEW(Fortune, elem, Fortune(i));
|
||||
|
||||
pvfortune->push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
static void handlerForkSql()
|
||||
|
@ -202,11 +220,9 @@ public:
|
|||
|
||||
U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
|
||||
|
||||
U_NEW(Fortune, pfortune, Fortune);
|
||||
|
||||
pstmt_fortune->into(*pfortune);
|
||||
|
||||
handlerFork();
|
||||
|
||||
pstmt_fortune->into(uid, *pmessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +231,11 @@ public:
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "Fortune::handlerEnd()")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(pmessage)
|
||||
U_INTERNAL_ASSERT_POINTER(pvfortune)
|
||||
U_INTERNAL_ASSERT_POINTER(pfortune2add)
|
||||
|
||||
U_DELETE(pmessage)
|
||||
U_DELETE(pvfortune)
|
||||
U_DELETE(pfortune2add)
|
||||
}
|
||||
|
||||
static void handlerEndSql()
|
||||
|
@ -230,7 +246,6 @@ public:
|
|||
{
|
||||
handlerEnd();
|
||||
|
||||
U_DELETE(pfortune)
|
||||
U_DELETE(psql_fortune)
|
||||
U_DELETE(pstmt_fortune)
|
||||
|
||||
|
@ -244,7 +259,4 @@ public:
|
|||
private:
|
||||
U_DISALLOW_ASSIGN(Fortune)
|
||||
};
|
||||
|
||||
// override the default...
|
||||
template <> inline void u_destroy(const Fortune** ptr, uint32_t n) { U_TRACE(0,"u_destroy<Fortune*>(%p,%u)", ptr, n) }
|
||||
#endif
|
||||
|
|
|
@ -5,28 +5,75 @@ TechEmpower Web Framework Benchmarks
|
|||
<!--#declaration
|
||||
#include "fortune.h"
|
||||
|
||||
static vPF handle_query;
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
static UOrmDriver* pdrv;
|
||||
static USqlStatement* pstmt;
|
||||
#endif
|
||||
|
||||
static void handlerQuery()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::handlerQuery()")
|
||||
|
||||
Fortune* elem;
|
||||
uint32_t i = 0;
|
||||
|
||||
Fortune::pstmt_fortune->execute();
|
||||
|
||||
do {
|
||||
U_NEW(Fortune, elem, Fortune(*Fortune::pfortune));
|
||||
|
||||
Fortune::pvfortune->push(elem);
|
||||
Fortune::replace(i++);
|
||||
}
|
||||
while (Fortune::pstmt_fortune->nextRow());
|
||||
}
|
||||
|
||||
static void usp_fork_fortune() { Fortune::handlerForkSql(); }
|
||||
static void handlerQueryPGSQL()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::handlerQueryPGSQL()")
|
||||
|
||||
#ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
int sz;
|
||||
char* id;
|
||||
char* ptr;
|
||||
PGresult* res = ((UOrmDriverPgSql*)pdrv)->execPrepared(pstmt);
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 2)
|
||||
|
||||
for (uint32_t i = 0, n = U_SYSCALL(PQntuples, "%p", res); i < n; ++i)
|
||||
{
|
||||
id = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, i, 0);
|
||||
ptr = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, i, 1);
|
||||
sz = U_SYSCALL(PQgetlength, "%p,%d,%d", res, i, 1);
|
||||
|
||||
Fortune::replace(i, ntohl(*(uint32_t*)id), ptr, sz);
|
||||
}
|
||||
|
||||
U_SYSCALL_VOID(PQclear, "%p", res);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usp_fork_fortune()
|
||||
{
|
||||
U_TRACE_NO_PARAM(5, "::usp_fork_fortune()")
|
||||
|
||||
Fortune::handlerForkSql();
|
||||
|
||||
if (UOrmDriver::isPGSQL() == false) handle_query = handlerQuery;
|
||||
else
|
||||
{
|
||||
handle_query = handlerQueryPGSQL;
|
||||
|
||||
# ifdef U_STATIC_ORM_DRIVER_PGSQL
|
||||
pdrv = Fortune::psql_fortune->getDriver();
|
||||
pstmt = Fortune::pstmt_fortune->getStatement();
|
||||
|
||||
((UPgSqlStatement*)pstmt)->prepareStatement(pdrv);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void usp_end_fortune() { Fortune::handlerEndSql(); }
|
||||
#endif
|
||||
-->
|
||||
<!--#code
|
||||
Fortune::doQuery(handlerQuery);
|
||||
Fortune::doQuery(handle_query);
|
||||
-->
|
||||
|
|
|
@ -23,19 +23,18 @@ public:
|
|||
{
|
||||
U_TRACE(0, "FortuneNoSql::handlerQueryMongoDB()")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(Fortune::pmessage)
|
||||
|
||||
# ifdef USE_MONGODB
|
||||
(void) mc->findAll();
|
||||
|
||||
for (uint32_t i = 0, n = mc->vitem.size(); i < n; ++i)
|
||||
{
|
||||
Fortune* item;
|
||||
UString result;
|
||||
(void) U_JFIND(mc->vitem[i], "message", *Fortune::pmessage);
|
||||
|
||||
(void) U_JFIND(mc->vitem[i], "message", result);
|
||||
Fortune::replace(i, i+1);
|
||||
|
||||
U_NEW(Fortune, item, Fortune(i+1, result));
|
||||
|
||||
Fortune::pvfortune->push(item);
|
||||
Fortune::pmessage->clear();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
@ -84,14 +83,7 @@ public:
|
|||
|
||||
(void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
|
||||
|
||||
for (uint32_t i = 0, n = rc->vitem.size(); i < n; ++i)
|
||||
{
|
||||
Fortune* item;
|
||||
|
||||
U_NEW(Fortune, item, Fortune(i+1, rc->vitem[i]));
|
||||
|
||||
Fortune::pvfortune->push(item);
|
||||
}
|
||||
for (uint32_t i = 0, n = rc->vitem.size(); i < n; ++i) Fortune::replace(i, rc->vitem[i]);
|
||||
}
|
||||
|
||||
static void handlerForkREDIS()
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
#include "fortune.h"
|
||||
|
||||
char* Fortune::pwbuffer;
|
||||
Fortune* Fortune::pfortune;
|
||||
Fortune* Fortune::pfortune2add;
|
||||
uint32_t Fortune::uid;
|
||||
UString* Fortune::pmessage;
|
||||
UOrmSession* Fortune::psql_fortune;
|
||||
UOrmStatement* Fortune::pstmt_fortune;
|
||||
UVector<Fortune*>* Fortune::pvfortune;
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
if (str_rnumber == U_NULLPTR) U_NEW_STRING(str_rnumber, UString);
|
||||
|
||||
World::handlerFork();
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(str_rnumber)
|
||||
}
|
||||
|
||||
#ifdef USE_MONGODB
|
||||
|
|
|
@ -4,8 +4,8 @@ Four Debian releases are available on the main site:
|
|||
Debian 7.11, or wheezy. Access this release through dists/oldoldstable
|
||||
Debian 7.11 was released Saturday, 4th June 2016.
|
||||
|
||||
Debian 8.10, or jessie. Access this release through dists/oldstable
|
||||
Debian 8.10 was released Saturday, 9th December 2017.
|
||||
Debian 8.11, or jessie. Access this release through dists/oldstable
|
||||
Debian 8.11 was released Saturday, 23rd June 2018.
|
||||
|
||||
Debian 9.4, or stretch. Access this release through dists/stable
|
||||
Debian 9.4 was released Saturday, 10th March 2018.
|
||||
|
|
|
@ -403,7 +403,12 @@ U_EXPORT main (int argc, char* argv[])
|
|||
uint32_t i = y.findSorted(U_STRING_FROM_CONSTANT("NULL"));
|
||||
U_INTERNAL_ASSERT( i == U_NOT_FOUND )
|
||||
|
||||
for (i = 0, n = y.size(); i < n; ++i) { U_ASSERT( i == y.findSorted(y[i]) ) }
|
||||
for (i = 0, n = y.size(); i < n; ++i)
|
||||
{
|
||||
uint32_t j = y.findSorted(y[i]);
|
||||
|
||||
U_INTERNAL_ASSERT( j == i )
|
||||
}
|
||||
|
||||
ofstream outf("vector.sort");
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user