hermes.fix.quickfix.QuickFIXMessageCache.java Source code

Java tutorial

Introduction

Here is the source code for hermes.fix.quickfix.QuickFIXMessageCache.java

Source

/* 
 * Copyright 2003,2004,2005 Colin Crist
 *
 * Licensed 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 hermes.fix.quickfix;

import hermes.fix.FIXMessage;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.collections.map.LRUMap;

import quickfix.Message;
import quickfix.mina.message.FIXMessageDecoder;

/**
 * @author colincrist@hermesjms.com
 * @version $Id: QuickFIXMessageCache.java,v 1.1 2006/07/26 09:47:56 colincrist
 *          Exp $
 */

public class QuickFIXMessageCache {
    private LRUMap messages;
    private Set<FIXMessage> toReset = new HashSet<FIXMessage>();
    private Lock lock = new ReentrantLock();

    private Map<Thread, FIXMessageDecoder> decoders = new HashMap<Thread, FIXMessageDecoder>();

    public QuickFIXMessageCache() {
        this(1024);
    }

    public FIXMessageDecoder getDecoder() throws UnsupportedEncodingException {
        synchronized (decoders) {
            FIXMessageDecoder decoder = decoders.get(Thread.currentThread());

            if (decoder == null) {
                decoder = new FIXMessageDecoder();
                decoders.put(Thread.currentThread(), decoder);
            }

            return decoder;
        }
    }

    public QuickFIXMessageCache(int size) {
        messages = createLRUMap(size);
    }

    private LRUMap createLRUMap(int size) {
        return new LRUMap(size) {
            /**
            * 
            */
            private static final long serialVersionUID = -3353399913762901038L;

            @Override
            protected boolean removeLRU(LinkEntry entry) {
                //
                // When the message is removed from the cache clear its fields.

                final FIXMessage message = (FIXMessage) entry.getKey();

                // We cannot call reset here, the next time a put occurs, we'll
                // reset it.

                synchronized (toReset) {
                    toReset.add(message);
                }

                return super.removeLRU(entry);
            }
        };
    }

    public void setSize(int size) {
        lock.lock();

        try {
            final LRUMap newMessages = createLRUMap(size);

            messages.putAll(newMessages);
            messages = newMessages;
        } finally {
            lock.unlock();
        }
    }

    public int getSize() {
        lock.lock();

        try {
            if (messages == null) {
                return 0;
            } else {
                return messages.maxSize();
            }
        } finally {
            lock.unlock();
        }
    }

    public void close() {
        lock.lock();

        try {
            messages.clear();
            decoders.clear();

        } finally {
            lock.unlock();
        }

        synchronized (toReset) {
            toReset.clear();
        }
    }

    public void lock() {
        lock.lock();
    }

    public void unlock() {
        lock.unlock();
    }

    public boolean contains(FIXMessage key) {
        lock.lock();

        try {
            return messages.containsKey(key);
        } finally {
            lock.unlock();
        }
    }

    public void put(FIXMessage key, Message value) {
        lock.lock();

        try {
            messages.put(key, value);
        } finally {
            lock.unlock();
        }

        synchronized (toReset) {
            if (toReset.contains(key)) {
                toReset.remove(key);
            }

            for (FIXMessage m : toReset) {
                m.reset();
            }

            toReset.clear();
        }

    }

    public Message get(FIXMessage key) {
        lock.lock();

        try {
            return (Message) messages.get(key);
        } finally {
            lock.unlock();
        }
    }
}