| From: | thhal at mailblocks(dot)com (Thomas Hallgren) | 
|---|---|
| To: | |
| Subject: | [Pljava-dev] advice needed | 
| Date: | 2005-02-16 16:53:46 | 
| Message-ID: | thhal-0IRPvAjWJxicEk4lsNP3uqVJU2q8J7u@mailblocks.com | 
| Views: | Whole Thread | Raw Message | Download mbox | Resend email | 
| Thread: | |
| Lists: | pljava-dev | 
info at wyse-systems.ltd.uk wrote:
>1. I assume the main class is created (and the class constructor is called)
>upon a direct call to the function and then instance is left to be
>destroyed by the gc. 
>If that is the case this wouldn't be the most wise thing to do because of
>(at least) 2 reasons: 1. Class cleanup (in my example I have to perform
>connection shutdown as well as Resultset and Statement close upon
>'completion' or exception event of each task), and 2: there is no way on
>Earth you can manage multiple instances and synchorization (unless you
>synchronise all methods - way too slow). 
>  
>
Keep in mind that the PostgreSQL backend is inherently single threaded. 
You have one JVM per session. This means two things. 1) you hardly ever 
need to worry about synchronization. The only time you'll need it is 
when you expect finalizers to do something that might conflict with the 
main thread. 2) Since you hardly ever will encounter a contended 
synchronization locks, the overhead of using synchronizers will be 
almost none at all. A modern JVM is extremely fast when it comes to 
uncontendend synchronizations.
Don't rely on finalizers to do cleanup. Do that just prior to returning 
false in the assignRowValues.
>Wouldn't it be better for pljava to create a pool of instances and present
>them to the caller each time a call to the function is made. If you adopt
>this approach and extend the ResultSetProvider class to include at least
>two more methods for managing class 'activate' and 'deactivate' events
>while keeping/recycle the class instance that would bring a performance
>boost (not to mention the memory management improvements). You can then add
>a few more set of options in postgresql.conf file to configure the object
>pool. I am using a similar pool here on our system (it deals with between
>30 and 120 different class instances existing in the pool at any point in
>time, each of which has an independent network connection to a client) and
>by using a pool of objects (as oppose to class instances
>creation/destruction upon every call) this brings a performance boost
>between 17 and 28% of the entire system.
>  
>
Yes, using a pool is an excellent idea. Stay tuned for next release ;-)
Meanwhile, try something like this (replace PooledProvider with a name 
of choice):
public class PooledProvider implements ResultSetProvider
{
    private static PooledProvider s_pool;   
    private PooledProvider m_next;
    public boolean assignRowValues(ResultSet receiver, int currentRow)
    throws SQLException
    {
        // Code that returns true omitted. This happens just before you 
return false.
        this.deactivate();
        m_next = s_pool;
        s_pool = this;
        return false;
    }
    public static ResultSetProvider getPooledProvider()
    throws SQLException
    {
        PooledProvider ret = s_pool;
        if(ret != null)
            s_pool = ret.m_next;
        else
            ret =  new PooledProvider();
        ret.activate();
        return ret;
    }
    void activate() {}
    void deactivate() {}
}
>2. I am no expert in PostgreSQL internals (in fact I don't know anything
>about that at all), but with the above class (DetailsView) wouldn't be
>wiser to call 'a method' once and get the result in one go, instead of
>calling assignRowValues for each individual row. I think I know the answer
>to that one, but it is worth asking and give it a go anyway (;
>  
>
The reason is a combination of factors:
1. The PostgreSQL backend function interface stipulates that you 
implement a function that returns one row at a time.
2. Returning all in one go implies that you either build everything up 
in memory (not an option for you), or that you create some kind of
implementation that in turn can return one row at a time. Then you've 
gained nothing since that's exactly what the ResultSetProvider does.
3. A lot of implementations will return data that doesn't origin from an 
SQL query.
Having said that, perhaps PLJava should provide a variant that allowes 
you to return a ResultSet and thereby bypass the transfer between 
ResultSet's that has to take place today. We are currently adding 
DatabaseMetaData support to PLJava and in that addition a new 
SyntheticResultSet is included that would make such an approach even 
more valuable.
>Once I clarify the above questions I am willing to contribute.
>  
>
Super!
Regards,
Thomas Hallgren
| From | Date | Subject | |
|---|---|---|---|
| Next Message | WYSE Systems Limited Information | 2005-02-16 21:09:55 | [Pljava-dev] advice needed | 
| Previous Message | Thomas Hallgren | 2005-02-16 15:44:31 | [Pljava-dev] what's the difference between the linux & windows versions |