>From my experience ConcurrentHashMap outperforms
Collections.synchronizedMap(...) only if:
- you know in advance how many maximum threads (MAX_THREADS) could
simultaneously modify the ConcurrentHashMap
- MAX_THREADS is small compared to the number of threads that are
accessing the ConcurrentHashMap (reads)
- the accesses (reads) vastly outnumbers the modifications (writes)
ConcurrentHashMap also consumes more memory (increases proportional
with MAX_THREADS)

Bogdan

On Tue, Jul 22, 2008 at 2:24 AM, Edouard De Oliveira
<[EMAIL PROTECTED]> wrote:
> Perfectly legitimate question Mark :
>
> Stop me if i'm not correct, but i think it would be an error using 
> CopyOnWriteMap in this usecase
> as the map grows when the number of sessions grows and as buffering takes 
> full meaning in long
> lived sessions, then each new session would duplicate a potentially larger 
> map hence
> hitting the bad side of CopyOnWriteMap.
>
>
> So ConcurrentHashMap should be more appropriate.
>
> WDYT ?
>
> ps: i'm commiting right now the proposed fix
> and a test class on trunk to ease any further review
>
> Cordialement, Regards,
> -Edouard De Oliveira-
> http://tedorg.free.fr/en/main.php
>
>
>
> ----- Message d'origine ----
> De : Mark Webb <[EMAIL PROTECTED]>
> À : [email protected]
> Envoyé le : Lundi, 21 Juillet 2008, 2h47mn 54s
> Objet : Re: svn commit: r678238 - in 
> /mina/trunk/core/src/main/java/org/apache/mina/filter/buffer: ./ 
> BufferedWriteFilter.java
>
> I have a question on this class.
>
> Why not use ConcurrentHashMap for this instead of synchronizing?  Or
> CopyOnWriteMap?
>
>
>
>
> On Sat, Jul 19, 2008 at 7:19 PM, <[EMAIL PROTECTED]> wrote:
>
>> Author: edeoliveira
>> Date: Sat Jul 19 16:19:14 2008
>> New Revision: 678238
>>
>> URL: http://svn.apache.org/viewvc?rev=678238&view=rev
>> Log:
>> New IoFilter that implements DIRMINA-519
>>
>> Added:
>>    mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/
>>
>>  
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>>   (with props)
>>
>> Added:
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>> URL:
>> http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java?rev=678238&view=auto
>>
>> ==============================================================================
>> ---
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>> (added)
>> +++
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>> Sat Jul 19 16:19:14 2008
>> @@ -0,0 +1,243 @@
>> +/*
>> + *  Licensed to the Apache Software Foundation (ASF) under one
>> + *  or more contributor license agreements.  See the NOTICE file
>> + *  distributed with this work for additional information
>> + *  regarding copyright ownership.  The ASF licenses this file
>> + *  to you under the Apache License, Version 2.0 (the
>> + *  "License"); you may not use this file except in compliance
>> + *  with the License.  You may obtain a copy of the License at
>> + *
>> + *    http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + *  Unless required by applicable law or agreed to in writing,
>> + *  software distributed under the License is distributed on an
>> + *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>> + *  KIND, either express or implied.  See the License for the
>> + *  specific language governing permissions and limitations
>> + *  under the License.
>> + *
>> + */
>> +package org.apache.mina.filter.buffer;
>> +
>> +import java.io.BufferedOutputStream;
>> +import java.util.HashMap;
>> +import java.util.Map;
>> +
>> +import org.apache.mina.core.buffer.IoBuffer;
>> +import org.apache.mina.core.filterchain.IoFilter;
>> +import org.apache.mina.core.filterchain.IoFilterAdapter;
>> +import org.apache.mina.core.session.IoSession;
>> +import org.apache.mina.core.write.DefaultWriteRequest;
>> +import org.apache.mina.core.write.WriteRequest;
>> +import org.apache.mina.filter.codec.ProtocolCodecFilter;
>> +
>> +/**
>> + * An [EMAIL PROTECTED] IoFilter} implementation used to buffer outgoing 
>> [EMAIL PROTECTED]
>> WriteRequest} almost
>> + * like what [EMAIL PROTECTED] BufferedOutputStream} does. Using this 
>> filter allows
>> to be less dependent
>> + * from network latency. It is also useful when a session is generating
>> very small messages
>> + * too frequently and consequently generating unnecessary traffic
>> overhead.
>> + *
>> + * Please note that it should always be placed before the [EMAIL PROTECTED]
>> ProtocolCodecFilter}
>> + * as it only handles [EMAIL PROTECTED] WriteRequest}'s carrying [EMAIL 
>> PROTECTED] IoBuffer}
>> objects.
>> + *
>> + * @author The Apache MINA Project ([email protected])
>> + * @version $Rev: $, $Date: $
>> + * @since MINA 2.0.0-M2
>> + */
>> +public final class BufferedWriteFilter extends IoFilterAdapter {
>> +
>> +    /**
>> +     * Default buffer size value in bytes.
>> +     */
>> +    public final static int DEFAULT_BUFFER_SIZE = 8192;
>> +
>> +    /**
>> +     * The buffer size allocated for each new session's buffer.
>> +     */
>> +    private int bufferSize = DEFAULT_BUFFER_SIZE;
>> +
>> +    /**
>> +     * The map that matches an [EMAIL PROTECTED] IoSession} and it's [EMAIL 
>> PROTECTED] IoBuffer}
>> +     * buffer.
>> +     */
>> +    protected Map<IoSession, IoBuffer> buffersMap = new HashMap<IoSession,
>> IoBuffer>();
>> +
>> +    /**
>> +     * Default constructor. Sets buffer size to [EMAIL PROTECTED]
>> #DEFAULT_BUFFER_SIZE}
>> +     * bytes.
>> +     */
>> +    public BufferedWriteFilter() {
>> +        this(DEFAULT_BUFFER_SIZE);
>> +    }
>> +
>> +    /**
>> +     * Constructor which sets buffer size to <code>bufferSize</code>.
>> +     *
>> +     * @param bufferSize the new buffer size
>> +     */
>> +    public BufferedWriteFilter(int bufferSize) {
>> +        super();
>> +        this.bufferSize = bufferSize;
>> +    }
>> +
>> +    /**
>> +     * Returns buffer size.
>> +     */
>> +    public int getBufferSize() {
>> +        return bufferSize;
>> +    }
>> +
>> +    /**
>> +     * Sets the buffer size but only for the newly created buffers.
>> +     *
>> +     * @param bufferSize the new buffer size
>> +     */
>> +    public void setBufferSize(int bufferSize) {
>> +        this.bufferSize = bufferSize;
>> +    }
>> +
>> +    /**
>> +     * [EMAIL PROTECTED]
>> +     *
>> +     * @throws Exception if <code>writeRequest.message</code> isn't an
>> +     *                   [EMAIL PROTECTED] IoBuffer} instance.
>> +     */
>> +    @Override
>> +    public void filterWrite(NextFilter nextFilter, IoSession session,
>> +            WriteRequest writeRequest) throws Exception {
>> +
>> +        Object data = writeRequest.getMessage();
>> +
>> +        if (data instanceof IoBuffer) {
>> +            write(session, (IoBuffer) data);
>> +        } else {
>> +            throw new IllegalArgumentException(
>> +                    "This filter should only buffer IoBuffer objects");
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Writes an [EMAIL PROTECTED] IoBuffer} to the session's buffer.
>> +     *
>> +     * @param session the session to which a write is requested
>> +     * @param data the data to buffer
>> +     */
>> +    private void write(IoSession session, IoBuffer data) {
>> +        IoBuffer dest = null;
>> +        synchronized (buffersMap) {
>> +            dest = buffersMap.get(session);
>> +            if (dest == null) {
>> +                // Enforce the creation of a non-expandable buffer
>> +                dest = IoBuffer.allocate(bufferSize).setAutoExpand(false);
>> +                buffersMap.put(session, dest);
>> +            }
>> +        }
>> +
>> +        write(session, data, dest);
>> +    }
>> +
>> +    /**
>> +     * Writes <code>data</code> [EMAIL PROTECTED] IoBuffer} to the 
>> <code>buf</code>
>> +     * [EMAIL PROTECTED] IoBuffer} which buffers write requests for the
>> +     * <code>session</code> {@ link IoSession} until buffer is full
>> +     * or manually flushed.
>> +     *
>> +     * @param session the session where buffer will be written
>> +     * @param data the data to buffer
>> +     * @param buf the buffer where data will be temporarily written
>> +     */
>> +    private void write(IoSession session, IoBuffer data, IoBuffer buf) {
>> +        synchronized (buf) {
>> +            try {
>> +                int len = data.remaining();
>> +                if (len >= buf.capacity()) {
>> +                    /*
>> +                     * If the request length exceeds the size of the
>> output buffer,
>> +                     * flush the output buffer and then write the data
>> directly.
>> +                     */
>> +                    NextFilter nextFilter = session.getFilterChain()
>> +                            .getNextFilter(this);
>> +                    internalFlush(nextFilter, session, buf);
>> +                    nextFilter.filterWrite(session,
>> +                            new DefaultWriteRequest(buf));
>> +                    return;
>> +                }
>> +                if (len > (buf.limit() - buf.position())) {
>> +
>>  internalFlush(session.getFilterChain().getNextFilter(this),
>> +                            session, buf);
>> +                }
>> +                buf.put(data);
>> +            } catch (Throwable e) {
>> +                session.getFilterChain().fireExceptionCaught(e);
>> +            }
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Internal method that actually flushes the buffered data.
>> +     *
>> +     * @param nextFilter the [EMAIL PROTECTED] NextFilter} of this filter
>> +     * @param session the session where buffer will be written
>> +     * @param data the data to write
>> +     * @throws Exception if a write operation fails
>> +     */
>> +    private void internalFlush(NextFilter nextFilter, IoSession session,
>> +            IoBuffer data) throws Exception {
>> +        if (data != null) {
>> +            nextFilter.filterWrite(session, new
>> DefaultWriteRequest(data));
>> +            data.clear();
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Flushes the buffered data.
>> +     *
>> +     * @param session the session where buffer will be written
>> +     */
>> +    public void flush(IoSession session) {
>> +        try {
>> +            IoBuffer data = null;
>> +            synchronized (session) {
>> +                data = buffersMap.get(session);
>> +            }
>> +            internalFlush(session.getFilterChain().getNextFilter(this),
>> +                    session, data);
>> +
>> +        } catch (Throwable e) {
>> +            session.getFilterChain().fireExceptionCaught(e);
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Internal method that actually frees the [EMAIL PROTECTED] IoBuffer} 
>> that
>> contains
>> +     * the buffered data that has not been flushed.
>> +     *
>> +     * @param session the session we operate on
>> +     */
>> +    private void clear(IoSession session) {
>> +        synchronized (session) {
>> +            IoBuffer buf = buffersMap.remove(session);
>> +            if (buf != null) {
>> +                buf.free();
>> +            }
>> +        }
>> +    }
>> +
>> +    /**
>> +     * [EMAIL PROTECTED]
>> +     */
>> +    @Override
>> +    public void exceptionCaught(NextFilter nextFilter, IoSession session,
>> +            Throwable cause) throws Exception {
>> +        clear(session);
>> +    }
>> +
>> +    /**
>> +     * [EMAIL PROTECTED]
>> +     */
>> +    @Override
>> +    public void sessionClosed(NextFilter nextFilter, IoSession session)
>> +            throws Exception {
>> +        clear(session);
>> +    }
>> +}
>> \ No newline at end of file
>>
>> Propchange:
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>>
>> ------------------------------------------------------------------------------
>>    svn:eol-style = native
>>
>> Propchange:
>> mina/trunk/core/src/main/java/org/apache/mina/filter/buffer/BufferedWriteFilter.java
>>
>> ------------------------------------------------------------------------------
>>    svn:mime-type = text/plain
>>
>>
>>
>
>
>
>      
> _____________________________________________________________________________
> Envoyez avec Yahoo! Mail. Une boite mail plus intelligente 
> http://mail.yahoo.fr
>

Reply via email to