All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.code.fqueue.FQueue Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
/*
 *  Copyright 2011 sunli [[email protected]][weibo.com@sunli1223]
 *
 *  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 com.google.code.fqueue;

import com.google.common.base.Preconditions;
import me.aifaq.commons.lang.ByteUtil;

import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

/**
 * 基于文件系统的持久化队列
 * 
 * @author sunli
 * @date 2010-8-13
 * @version $Id: FQueue.java 2 2011-07-31 12:25:36Z [email protected] $
 */
public class FQueue extends AbstractQueue implements BlockingQueue,
		java.io.Serializable {
	private static final Logger logger = Logger.getLogger(FQueue.class.getName());
	private static final long serialVersionUID = -5960741434564940154L;

	private FSQueue fsQueue;

	private int count;

	/** Main lock guarding all access */
	private final ReentrantLock lock;
	/** Condition for waiting takes */
	private final Condition notEmpty;
	/** Condition for waiting puts */
	private final Condition notFull;

	public FQueue(String path) throws Exception {
		this(path, ByteUtil.ONE_MB * 300);
	}

	public FQueue(String path, long logsize) throws Exception {
		fsQueue = new FSQueue(path, logsize);
		count = fsQueue.getQueueSize();
		lock = new ReentrantLock();
		notEmpty = lock.newCondition();
		notFull = lock.newCondition();
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				close();
			}
		});
	}

	private void close() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			fsQueue.close();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public Iterator iterator() {
		throw new UnsupportedOperationException();
	}

	@Override
	public byte[] peek() {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean remove(Object o) {
		throw new UnsupportedOperationException();
	}

	@Override
	public int remainingCapacity() {
		throw new UnsupportedOperationException();
	}

	@Override
	public int drainTo(Collection c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public int drainTo(Collection c, int maxElements) {
		throw new UnsupportedOperationException();
	}

	@Override
	public int size() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			return count;
		} finally {
			lock.unlock();
		}
	}

	private void insert(byte[] x) {
		try {
			fsQueue.add(x);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		++count;
		notEmpty.signal();
	}

	private byte[] extract() {
		byte[] x;
		try {
			x = fsQueue.readNextAndRemove();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		--count;
		notFull.signal();
		return x;
	}

	@Override
	public void put(byte[] e) throws InterruptedException {
		Preconditions.checkNotNull(e);

		final ReentrantLock lock = this.lock;
		lock.lockInterruptibly();
		try {
			insert(e);
		} finally {
			lock.unlock();
		}
	}

	@Override
	public boolean offer(byte[] e) {
		Preconditions.checkNotNull(e);

		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			insert(e);
			return true;
		} finally {
			lock.unlock();
		}
	}

	@Override
	public boolean offer(byte[] e, long timeout, TimeUnit unit)
			throws InterruptedException {
		throw new UnsupportedOperationException();
	}

	@Override
	public byte[] poll() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			return (count == 0) ? null : extract();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public byte[] poll(long timeout, TimeUnit unit) throws InterruptedException {
		long nanos = unit.toNanos(timeout);
		final ReentrantLock lock = this.lock;
		lock.lockInterruptibly();
		try {
			while (count == 0) {
				if (nanos <= 0)
					return null;
				nanos = notEmpty.awaitNanos(nanos);
			}
			return extract();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public byte[] take() throws InterruptedException {
		final ReentrantLock lock = this.lock;
		lock.lockInterruptibly();
		try {
			while (count == 0)
				notEmpty.await();
			return extract();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public void clear() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			fsQueue.clear();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public String toString() {
		return "FQueue[" + fsQueue.getPath() + "]";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy