Commit b43e82dc authored by Olivier Bertrand's avatar Olivier Bertrand

- Make memory allocation of VALBLK's more flexible (can be allocated

  normally when too big to be suballocated) to handle big results.
modified:
  storage/connect/valblk.cpp
  storage/connect/valblk.h

- Add system variable connect_work_size giving the size of the CONNECT
  work area used for memory allocation.
modified:
  storage/connect/ha_connect.cc
  storage/connect/plugutil.c
  storage/connect/user_connect.cc
parent d95e797c
......@@ -163,6 +163,8 @@
/* Initialize the ha_connect static members. */
/***********************************************************************/
#define SZCONV 8192
#define SZWORK 67108864 // Default work area size 64M
#define SZWMIN 4194304 // Minimum work area size 4M
extern "C" {
char version[]= "Version 1.02.0002 March 16, 2014";
......@@ -179,12 +181,14 @@ extern "C" {
bool xmap= false;
#endif // XMAP
ulong ha_connect::num= 0;
uint worksize= SZWORK;
ulong ha_connect::num= 0;
//int DTVAL::Shift= 0;
/* CONNECT system variables */
static int xtrace= 0;
static int conv_size= SZCONV;
static uint work_size= SZWORK;
static ulong type_conv= 0;
#if defined(XMAP)
static my_bool indx_map= 0;
......@@ -228,6 +232,13 @@ static void update_connect_xconv(MYSQL_THD thd,
xconv= (int)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_xconv
static void update_connect_worksize(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
worksize= (uint)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_worksize
#if defined(XMAP)
static void update_connect_xmap(MYSQL_THD thd,
struct st_mysql_sys_var *var,
......@@ -1997,13 +2008,17 @@ bool ha_connect::get_error_message(int error, String* buf)
if (xp && xp->g) {
PGLOBAL g= xp->g;
char *msg= (char*)PlugSubAlloc(g, NULL, strlen(g->Message) * 3);
char msg[3072]; // MAX_STR * 3
uint dummy_errors;
uint32 len= copy_and_convert(msg, strlen(g->Message) * 3,
system_charset_info,
g->Message, strlen(g->Message),
&my_charset_latin1,
&dummy_errors);
if (trace)
htrc("GEM(%u): %s\n", len, g->Message);
msg[len]= '\0';
buf->copy(msg, (uint)strlen(msg), system_charset_info);
} else
......@@ -5268,6 +5283,11 @@ static MYSQL_SYSVAR_BOOL(indx_map, indx_map, PLUGIN_VAR_RQCMDARG,
NULL, update_connect_xmap, 0);
#endif // XMAP
// Size used for g->Sarea_Size
static MYSQL_SYSVAR_UINT(work_size, work_size,
PLUGIN_VAR_RQCMDARG, "Size of the CONNECT work area.",
NULL, update_connect_worksize, SZWORK, SZWMIN, UINT_MAX, 1);
static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace),
MYSQL_SYSVAR(conv_size),
......@@ -5275,6 +5295,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
#if defined(XMAP)
MYSQL_SYSVAR(indx_map),
#endif // XMAP
MYSQL_SYSVAR(work_size),
NULL
};
......
......@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...)
va_list ap;
va_start (ap, fmt);
//if (trace == 0 || (trace == 1 && !debug) || !fmt) {
// printf("In %s wrong trace=%d debug=%p fmt=%p\n",
// __FILE__, trace, debug, fmt);
// trace = 0;
// } // endif trace
//if (trace == 1)
// vfprintf(debug, fmt, ap);
......@@ -490,10 +485,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
#if defined(DEBUG2) || defined(DEBUG3)
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
#endif
if (trace > 2)
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
char *pname = "Work";
......@@ -502,9 +496,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in %s area for request of %u (used=%d free=%d)",
pname, (uint) size, pph->To_Free, pph->FreeBlk);
#if defined(DEBUG2) || defined(DEBUG3)
htrc("%s\n", g->Message);
#endif
if (trace)
htrc("PlugSubAlloc: %s\n", g->Message);
longjmp(g->jumper[g->jump_level], 1);
} /* endif size OS32 code */
......@@ -515,10 +508,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
pph->To_Free += size; /* New offset of pool free block */
pph->FreeBlk -= size; /* New size of pool free block */
#if defined(DEBUG2) || defined(DEBUG3)
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
#endif
if (trace > 2)
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
return (memp);
} /* end of PlugSubAlloc */
......
......@@ -28,7 +28,7 @@
*/
/****************************************************************************/
/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2012 */
/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2014 */
/****************************************************************************/
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
......@@ -48,6 +48,7 @@
#include "mycat.h"
extern "C" int trace;
extern uint worksize;
/****************************************************************************/
/* Initialize the user_connect static member. */
......@@ -94,8 +95,9 @@ bool user_connect::user_init()
PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable
g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete
if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
......@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void)
{
if (thdp->query_id > last_query_id) {
PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
if (g->Sarea)
free(g->Sarea);
// Check whether the work area size was changed
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
worksize = g->Sarea_Size; // Was too big
} else
g->Sarea_Size = worksize; // Ok
} // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
g->Createas = 0;
......
......@@ -44,6 +44,7 @@
#define CheckParms(V, N) ChkIndx(N); ChkTyp(V);
extern "C" int trace;
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/***********************************************************************/
/* AllocValBlock: allocate a VALBLK according to type. */
......@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
return NULL;
} // endswitch Type
blkp->Init(g, check);
return blkp;
return (blkp->Init(g, check)) ? NULL : blkp;
} // end of AllocValBlock
/* -------------------------- Class VALBLK --------------------------- */
......@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
/***********************************************************************/
VALBLK::VALBLK(void *mp, int type, int nval, bool un)
{
Mblk = Nmblk;
Blkp = mp;
To_Nulls = NULL;
Check = true;
......@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b)
} // end of SetNullable
/***********************************************************************/
/* Buffer allocation routine. */
/***********************************************************************/
bool VALBLK::AllocBuff(PGLOBAL g, size_t size)
{
Mblk.Size = size;
if (!(Blkp = PlgDBalloc(g, NULL, Mblk))) {
sprintf(g->Message, MSG(MEM_ALLOC_ERR), "Blkp", Mblk.Size);
fprintf(stderr, "%s\n", g->Message);
return true;
} // endif Blkp
return false;
} // end of AllocBuff
/***********************************************************************/
/* Check functions. */
/***********************************************************************/
......@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un)
/* Initialization routine. */
/***********************************************************************/
template <class TYPE>
void TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(TYPE));
if (AllocBuff(g, Nval * sizeof(TYPE)))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......@@ -576,16 +595,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void CHRBLK::Init(PGLOBAL g, bool check)
bool CHRBLK::Init(PGLOBAL g, bool check)
{
Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valp[Long] = '\0';
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * Long);
if (AllocBuff(g, Nval * Long))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......@@ -936,13 +957,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void STRBLK::Init(PGLOBAL g, bool check)
bool STRBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(PSZ));
if (AllocBuff(g, Nval * sizeof(PSZ)))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......
......@@ -45,7 +45,7 @@ class VALBLK : public BLOCK {
virtual bool IsNull(int n) {return To_Nulls && To_Nulls[n];}
virtual void SetNullable(bool b);
virtual bool IsUnsigned(void) {return Unsigned;}
virtual void Init(PGLOBAL g, bool check) = 0;
virtual bool Init(PGLOBAL g, bool check) = 0;
virtual int GetVlen(void) = 0;
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n) = 0;
......@@ -88,12 +88,14 @@ class VALBLK : public BLOCK {
bool Locate(PVAL vp, int& i);
protected:
bool AllocBuff(PGLOBAL g, size_t size);
void ChkIndx(int n);
void ChkTyp(PVAL v);
void ChkTyp(PVBLK vb);
// Members
PGLOBAL Global; // Used for messages and allocation
MBLOCK Mblk; // Used to allocate buffer
char *To_Nulls; // Null values array
void *Blkp; // To value block
bool Check; // If true SetValue types must match
......@@ -114,7 +116,7 @@ class TYPBLK : public VALBLK {
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
......@@ -179,7 +181,7 @@ class CHRBLK : public VALBLK {
CHRBLK(void *mp, int size, int len, int prec, bool b);
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return Long;}
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n);
......@@ -211,11 +213,11 @@ class CHRBLK : public VALBLK {
protected:
// Members
char* const &Chrp; // Pointer to char buffer
PSZ Valp; // Used to make a zero ended value
bool Blanks; // True for right filling with blanks
bool Ci; // True if case insensitive
int Long; // Length of each string
char* const &Chrp; // Pointer to char buffer
PSZ Valp; // Used to make a zero ended value
bool Blanks; // True for right filling with blanks
bool Ci; // True if case insensitive
int Long; // Length of each string
}; // end of class CHRBLK
/***********************************************************************/
......@@ -232,7 +234,7 @@ class STRBLK : public VALBLK {
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
virtual bool IsNull(int n) {return Strp[n] == NULL;}
virtual void SetNullable(bool b) {} // Always nullable
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(PSZ);}
virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual char GetTinyValue(int n);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment