1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Fix for CONC79: Performance issue with c client library

Added read-ahed cache for vio to reduce the number of reads
This commit is contained in:
Georg Richter
2014-03-03 11:19:47 +01:00
parent 2ceb2f7ffc
commit 28e7a867f1
3 changed files with 66 additions and 25 deletions

View File

@@ -51,6 +51,10 @@ typedef struct st_vio Vio;
#define HANDLE void * #define HANDLE void *
#endif #endif
/* vio read-ahead cachine */
#define VIO_CACHE_SIZE 16384
#define VIO_CACHE_MIN_SIZE 2048
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
@@ -139,6 +143,9 @@ struct st_vio
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
SSL *ssl; SSL *ssl;
#endif #endif
uchar *cache; /* read-ahead cache to reduce reads (see CONC-79) */
uchar *cache_pos; /* position of read-ahead cached data */
size_t cache_size; /* <= VIO_CACHE_SIZE */
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -148,6 +148,13 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
} }
#endif #endif
} }
if (!(vio->cache= my_malloc(VIO_CACHE_SIZE, MYF(MY_WME))))
{
my_free((gptr)vio, MYF(0));
vio= NULL;
}
vio->cache_size= 0;
vio->cache_pos= vio->cache;
DBUG_RETURN(vio); DBUG_RETURN(vio);
} }
@@ -176,6 +183,7 @@ void vio_delete(Vio * vio)
{ {
if (vio->type != VIO_CLOSED) if (vio->type != VIO_CLOSED)
vio_close(vio); vio_close(vio);
my_free((gptr) vio->cache, MYF(0));
my_free((gptr) vio,MYF(0)); my_free((gptr) vio,MYF(0));
} }
} }
@@ -185,39 +193,65 @@ int vio_errno(Vio *vio __attribute__((unused)))
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
} }
size_t vio_real_read(Vio *vio, gptr buf, size_t size)
{
switch(vio->type) {
#ifdef HAVE_OPENSSL
case VIO_TYPE_SSL:
return my_ssl_read(vio, (char *)buf, size);
break;
#endif
#ifdef _WIN32
case VIO_TYPE_NAMEDPIPE:
{
DWORD length= 0;
if (!ReadFile(vio->hPipe, buf, (DWORD)size, &length, NULL))
return -1;
return length;
}
break;
#endif
default:
return recv(vio->sd, buf,
#ifdef _WIN32
(int)
#endif
size, 0);
break;
}
}
size_t vio_read(Vio * vio, gptr buf, size_t size) size_t vio_read(Vio * vio, gptr buf, size_t size)
{ {
size_t r; size_t r;
DBUG_ENTER("vio_read"); DBUG_ENTER("vio_read");
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size)); DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
#ifdef HAVE_OPENSSL
if (vio->type == VIO_TYPE_SSL)
{
r= my_ssl_read(vio, (uchar *)buf, size);
DBUG_RETURN(r);
}
#endif
#if defined( _WIN32) || defined(OS2) if (vio->cache + vio->cache_size > vio->cache_pos)
if (vio->type == VIO_TYPE_NAMEDPIPE)
{ {
DWORD length; r= MIN(size, vio->cache + vio->cache_size - vio->cache_pos);
#ifdef OS2 memcpy(buf, vio->cache_pos, r);
if (!DosRead((HFILE)vio->hPipe, buf, size, &length)) vio->cache_pos+= r;
DBUG_RETURN(-1);
#else
if (!ReadFile(vio->hPipe, buf, (DWORD)size, &length, NULL))
DBUG_RETURN(-1);
#endif
DBUG_RETURN(length);
} }
r = recv(vio->sd, buf, (int)size,0); else if (size >= VIO_CACHE_MIN_SIZE)
#else {
errno=0; /* For linux */ r= vio_real_read(vio, buf, size);
r = read(vio->sd, buf, size); }
#endif /* _WIN32 */ else
{
r= vio_real_read(vio, vio->cache, VIO_CACHE_SIZE);
if (r > 0)
{
if (size < r)
{
vio->cache_size= r; /* might be < VIO_CACHE_SIZE */
vio->cache_pos= vio->cache + size;
r= size;
}
memcpy(buf, vio->cache, r);
}
}
#ifndef DBUG_OFF #ifndef DBUG_OFF
if ((size_t)r == -1) if ((size_t)r == -1)
{ {

View File

@@ -3859,7 +3859,7 @@ static int test_rename(MYSQL *mysql)
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
rc= mysql_stmt_execute(stmt); rc= mysql_stmt_execute(stmt);
FAIL_IF(!rc, "Errr expected"); FAIL_IF(!rc, "Error expected");
rc= mysql_query(mysql, "create table t3 (a int)"); rc= mysql_query(mysql, "create table t3 (a int)");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);