2014-11-22
2014-11-22 02:09:29 by Stephen R. van den Berg <srb@cuci.nl>
-
192acdf8ae9e145b66eccab5f0e5f2f4a2d6ab05
(133 lines)
(+52/-81)
[
Show
| Annotate
]
Branch: 8.0
pgsql: Rebalance threads, cut away some fat and unnecessary mutexes.
The benchmark performance is now within spitting distance of the
old pgsql driver for the unbatched single queries.
For large batches (>20), the new driver beats everyone pants down.
For single batches (==1), the new driver is about 2% slower than
the old 7.8 version.
430:
private int rowsreceived;
private int inflight;
private int portalbuffersize;
- private Stdio.Buffer prepbuffer;
- private Thread.Condition prepbufferready;
- private Thread.Mutex prepbuffermux;
+
private Thread.Mutex closemux;
private Thread.Queue datarows;
private array(mapping(string:mixed)) datarowdesc;
-
+ private array(int) datarowtypes; // cached types from datarowdesc
private string statuscmdcomplete;
private int bytesreceived;
final int _synctransact;
457:
" laststatus: %s\n",
_state,rowsreceived,eoffound,inflight,
_query,c?->socket?->query_fd(),
- _portalname,datarowdesc&&sizeof(datarowdesc),
+ _portalname,datarowtypes&&sizeof(datarowtypes),
statuscmdcomplete||(_unnamedstatementkey?"*parsing*":""));
break;
}
473:
_ddescribe=Thread.Condition();
_ddescribemux=Thread.Mutex();
closemux=Thread.Mutex();
- prepbufferready=Thread.Condition();
- prepbuffermux=Thread.Mutex();
+
portalbuffersize=_portalbuffersize;
alltext = !alltyped;
_params = params;
519:
private void waitfordescribe() {
Thread.MutexKey lock=_ddescribemux->lock();
- if(!datarowdesc)
+ if(!datarowtypes)
_ddescribe->wait(lock);
lock=0;
}
527:
//! @seealso
//! @[Sql.sql_result()->num_fields()]
int num_fields() {
- if(!datarowdesc)
+ if(!datarowtypes)
waitfordescribe();
trydelayederror();
- return sizeof(datarowdesc);
+ return sizeof(datarowtypes);
}
//! @seealso
555:
//! @seealso
//! @[Sql.sql_result()->fetch_fields()]
array(mapping(string:mixed)) fetch_fields() {
- if(!datarowdesc)
+ if(!datarowtypes)
waitfordescribe();
trydelayederror();
return datarowdesc+({});
575: Inside #if defined(PG_DEBUG)
#ifdef PG_DEBUG
msglen-=2+4*cols;
#endif
- foreach(datarowdesc;int i;mapping m) {
+ foreach(datarowtypes;int i;int typ) {
int collen=cr->read_sint(4);
if(collen>0) {
#ifdef PG_DEBUG
msglen-=collen;
#endif
mixed value;
- switch(int typ=m.type) {
+ switch(typ) {
case FLOAT4OID:
#if SIZEOF_FLOAT>=8
case FLOAT8OID:
647:
final void _setrowdesc(array(mapping(string:mixed)) drowdesc) {
Thread.MutexKey lock=_ddescribemux->lock();
- datarowdesc=drowdesc;
+ datarowtypes=map(datarowdesc=drowdesc,lambda(mapping m){return m.type;});
_ddescribe->broadcast();
lock=0;
}
657:
if(sizeof(dtoid)!=sizeof(paramValues))
SUSERERROR("Invalid number of bindings, expected %d, got %d\n",
sizeof(dtoid),sizeof(paramValues));
- Thread.MutexKey lock=prepbuffermux->lock();
+ Thread.MutexKey lock=_ddescribemux->lock();
if(!_portalname) {
_portalname=(_unnamedportalkey=pgsqlsess._unnamedportalmux->trylock(1))
? "" : PORTALPREFIX
788:
break;
}
}
- if(_tprepared)
- if(_tprepared.datarowdesc)
- gotdatarowdesc(plugbuffer);
- else if(dontcacheprefix->match(_query)) // Don't cache FETCH/COPY
+ if(!datarowtypes) {
+ if(_tprepared && dontcacheprefix->match(_query))
m_delete(pgsqlsess->_prepareds,_query),_tprepared=0;
- if(prepbufferready) {
- lock=prepbuffermux->lock();
- prepbuffer=plugbuffer;
- if(prepbufferready)
- prepbufferready->signal();
+ waitfordescribe();
}
- }
- lock=0;
- }
-
- final void _processrowdesc(array(mapping(string:mixed)) datarowdesc) {
- _setrowdesc(datarowdesc);
- if(_tprepared)
- _tprepared.datarowdesc=datarowdesc;
- if(prepbufferready)
- Thread.Thread(gotdatarowdesc); // Do not use callout, it deadlocks
- }
-
- private void gotdatarowdesc(void|Stdio.Buffer plugbuffer) {
- Thread.MutexKey lock=prepbuffermux->lock();
- if(!plugbuffer) {
- if(!prepbuffer && prepbufferready)
- prepbufferready->wait(lock);
- plugbuffer=prepbuffer;
- prepbuffer=0; // Free memory when plugbuffer leaves scope
- }
- if(!prepbufferready || _state>=CLOSING)
+ if(_state>=CLOSING)
lock=_unnamedstatementkey=0;
else {
- prepbufferready->signal();
- prepbufferready=0; // Make sure we do this exactly once
- lock=0;
- plugbuffer->add_int16(sizeof(datarowdesc));
- if(sizeof(datarowdesc))
- foreach(datarowdesc;;mapping col)
- plugbuffer->add_int16(oidformat(col.type));
+ plugbuffer->add_int16(sizeof(datarowtypes));
+ if(sizeof(datarowtypes))
+ foreach(datarowtypes;;int typ)
+ plugbuffer->add_int16(oidformat(typ));
else if(commitprefix->match(_query)) {
-
+
lock=pgsqlsess->_shortmux->lock();
if(pgsqlsess->_portalsinflight) {
pgsqlsess->_waittocommit++;
837:
pgsqlsess->_readyforcommit->wait(lock);
pgsqlsess->_waittocommit--;
}
- lock=0;
+
}
-
+ lock=0;
PD("Bind portal %O statement %O\n",_portalname,_preparedname);
_fetchlimit=pgsqlsess->_fetchlimit;
_openportal();
853:
execfetchlimit->match(_query))
&& _fetchlimit,bindbuffer);
}
+ } else
+ lock=0;
}
-
+ final void _processrowdesc(array(mapping(string:mixed)) datarowdesc) {
+ _setrowdesc(datarowdesc);
+ if(_tprepared)
+ _tprepared.datarowdesc=datarowdesc;
+ }
+
final void _openportal() {
pgsqlsess->_portalsinflight++;
Thread.MutexKey lock=closemux->lock();
946:
private void releaseconditions() {
pgsqlsess=0;
- Thread.MutexKey lock;
- if(prepbufferready) {
- lock=prepbuffermux->lock();
- if(prepbufferready)
- prepbufferready->signal();
- }
- if(!datarowdesc) {
- lock=_ddescribemux->lock();
- datarowdesc=({});
+ if(!datarowtypes) {
+ Thread.MutexKey lock=_ddescribemux->lock();
+ datarowtypes=datarowdesc=({});
_ddescribe->broadcast();
- }
+
lock=0;
}
-
+ }
final void _releasesession(void|string statusccomplete) {
if(statusccomplete && !statuscmdcomplete)