summaryrefslogtreecommitdiff
path: root/src/interfaces/jdbc/org/postgresql/PG_Stream.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/jdbc/org/postgresql/PG_Stream.java')
-rw-r--r--src/interfaces/jdbc/org/postgresql/PG_Stream.java161
1 files changed, 147 insertions, 14 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/PG_Stream.java b/src/interfaces/jdbc/org/postgresql/PG_Stream.java
index 22c41bdb3a..0e392fca09 100644
--- a/src/interfaces/jdbc/org/postgresql/PG_Stream.java
+++ b/src/interfaces/jdbc/org/postgresql/PG_Stream.java
@@ -22,7 +22,10 @@ public class PG_Stream
private Socket connection;
private InputStream pg_input;
private BufferedOutputStream pg_output;
-
+
+ public PGStatement executingStatement;
+
+
/**
* Constructor: Connect to the PostgreSQL back end and return
* a stream connection.
@@ -45,6 +48,15 @@ public class PG_Stream
}
/**
+ * Set the currently executing statement. This is used to bind cached byte
+ * arrays to a Statement, so the statement can return the to the global
+ * pool of unused byte arrays when they are no longer inuse.
+ */
+ public void setExecutingStatement(PGStatement executingStatement){
+ this.executingStatement = executingStatement;
+ }
+
+ /**
* Sends a single character to the back end
*
* @param val the character to be sent
@@ -70,7 +82,7 @@ public class PG_Stream
*/
public void SendInteger(int val, int siz) throws IOException
{
- byte[] buf = new byte[siz];
+ byte[] buf = allocByteDim1(siz);
while (siz-- > 0)
{
@@ -94,7 +106,7 @@ public class PG_Stream
*/
public void SendIntegerReverse(int val, int siz) throws IOException
{
- byte[] buf = new byte[siz];
+ byte[] buf = allocByteDim1(siz);
int p=0;
while (siz-- > 0)
{
@@ -236,23 +248,52 @@ public class PG_Stream
return n;
}
- public String ReceiveString(int maxsize) throws SQLException {
- return ReceiveString(maxsize, null);
- }
-
+
/**
* Receives a null-terminated string from the backend. Maximum of
* maxsiz bytes - if we don't see a null, then we assume something
* has gone wrong.
*
+ * @param maxsiz maximum length of string
+ * @return string from back end
+ * @exception SQLException if an I/O error occurs
+ */
+ public String ReceiveString(int maxsiz) throws SQLException
+ {
+ return ReceiveString(maxsiz, null);
+ }
+
+ /**
+ * Receives a null-terminated string from the backend. Maximum of
+ * maxsiz bytes - if we don't see a null, then we assume something
+ * has gone wrong.
+ *
+ * @param maxsiz maximum length of string
* @param encoding the charset encoding to use.
- * @param maxsiz maximum length of string in bytes
* @return string from back end
* @exception SQLException if an I/O error occurs
*/
public String ReceiveString(int maxsiz, String encoding) throws SQLException
{
- byte[] rst = new byte[maxsiz];
+ byte[] rst = allocByteDim1(maxsiz);
+ return ReceiveString(rst, maxsiz, encoding);
+ }
+
+ /**
+ * Receives a null-terminated string from the backend. Maximum of
+ * maxsiz bytes - if we don't see a null, then we assume something
+ * has gone wrong.
+ *
+ * @param rst byte array to read the String into. rst.length must
+ * equal to or greater than maxsize.
+ * @param maxsiz maximum length of string in bytes
+ * @param encoding the charset encoding to use.
+ * @return string from back end
+ * @exception SQLException if an I/O error occurs
+ */
+ public String ReceiveString(byte rst[], int maxsiz, String encoding)
+ throws SQLException
+ {
int s = 0;
try
@@ -262,9 +303,10 @@ public class PG_Stream
int c = pg_input.read();
if (c < 0)
throw new PSQLException("postgresql.stream.eof");
- else if (c == 0)
- break;
- else
+ else if (c == 0) {
+ rst[s] = 0;
+ break;
+ } else
rst[s++] = (byte)c;
}
if (s >= maxsiz)
@@ -299,7 +341,7 @@ public class PG_Stream
{
int i, bim = (nf + 7)/8;
byte[] bitmask = Receive(bim);
- byte[][] answer = new byte[nf][0];
+ byte[][] answer = allocByteDim2(nf);
int whichbit = 0x80;
int whichbyte = 0;
@@ -337,7 +379,7 @@ public class PG_Stream
*/
private byte[] Receive(int siz) throws SQLException
{
- byte[] answer = new byte[siz];
+ byte[] answer = allocByteDim1(siz);
Receive(answer,0,siz);
return answer;
}
@@ -395,4 +437,95 @@ public class PG_Stream
pg_input.close();
connection.close();
}
+
+ /**
+ * Deallocate all resources that has been associated with any previous
+ * query.
+ */
+ public void deallocate(PGStatement stmt){
+
+ for(int i = 0; i < maxsize_dim1; i++){
+ synchronized(notusemap_dim1[i]){
+ notusemap_dim1[i].addAll(stmt.inusemap_dim1[i]);
+ }
+ stmt.inusemap_dim1[i].clear();
+ }
+
+ for(int i = 0; i < maxsize_dim2; i++){
+ synchronized(notusemap_dim2[i]){
+ notusemap_dim2[i].addAll(stmt.inusemap_dim2[i]);
+ }
+ stmt.inusemap_dim2[i].clear();
+ }
+ }
+
+ public static final int maxsize_dim1 = 256;
+ public static ObjectPool notusemap_dim1[] = new ObjectPool[maxsize_dim1];
+ public static byte binit[][] = new byte[maxsize_dim1][0];
+ public static final int maxsize_dim2 = 32;
+ public static ObjectPool notusemap_dim2[] = new ObjectPool[maxsize_dim2];
+ public static ObjectPoolFactory factory_dim1;
+ public static ObjectPoolFactory factory_dim2;
+
+ static {
+ for(int i = 0; i < maxsize_dim1; i++){
+ binit[i] = new byte[i];
+ notusemap_dim1[i] = new ObjectPool();
+ }
+ for(int i = 0; i < maxsize_dim2; i++){
+ notusemap_dim2[i] = new ObjectPool();
+ }
+ factory_dim1 = ObjectPoolFactory.getInstance(maxsize_dim1);
+ factory_dim2 = ObjectPoolFactory.getInstance(maxsize_dim2);
+ }
+
+ public byte[] allocByteDim1(int size){
+ if(size >= maxsize_dim1 || executingStatement == null){
+ return new byte[size];
+ }
+ ObjectPool not_usel = notusemap_dim1[size];
+ ObjectPool in_usel = executingStatement.inusemap_dim1[size];
+
+ byte b[] = null;
+
+ synchronized(not_usel){
+ if(!not_usel.isEmpty()) {
+ Object o = not_usel.remove();
+ b = (byte[]) o;
+ } else {
+ b = new byte[size];
+ }
+ }
+ in_usel.add(b);
+
+ return b;
+ }
+
+ public byte[][] allocByteDim2(int size){
+ if(size >= maxsize_dim2 || executingStatement == null){
+ return new byte[size][0];
+ }
+ ObjectPool not_usel = notusemap_dim2[size];
+ ObjectPool in_usel = executingStatement.inusemap_dim2[size];
+
+ byte b[][] = null;
+
+ synchronized(not_usel){
+ if(!not_usel.isEmpty()) {
+ Object o = not_usel.remove();
+ b = (byte[][]) o;
+ } else
+ b = new byte[size][0];
+
+ in_usel.add(b);
+ }
+
+ return b;
+ }
+
}
+
+
+
+
+