EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[all classes][org.springframework.batch.repeat.support]

COVERAGE SUMMARY FOR SOURCE FILE [ThrottleLimitResultQueue.java]

nameclass, %method, %block, %line, %
ThrottleLimitResultQueue.java100% (1/1)100% (6/6)91%  (96/106)98%  (24.6/25)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ThrottleLimitResultQueue100% (1/1)100% (6/6)91%  (96/106)98%  (24.6/25)
expect (): void 100% (1/1)78%  (18/23)95%  (4.8/5)
take (): Object 100% (1/1)85%  (28/33)97%  (6.8/7)
ThrottleLimitResultQueue (int): void 100% (1/1)100% (22/22)100% (6/6)
isEmpty (): boolean 100% (1/1)100% (4/4)100% (1/1)
isExpecting (): boolean 100% (1/1)100% (7/7)100% (1/1)
put (Object): void 100% (1/1)100% (17/17)100% (5/5)

1/*
2 * Copyright 2002-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.repeat.support;
18 
19import java.util.NoSuchElementException;
20import java.util.concurrent.BlockingQueue;
21import java.util.concurrent.LinkedBlockingQueue;
22import java.util.concurrent.Semaphore;
23 
24/**
25 * An implementation of the {@link ResultQueue} that throttles the number of
26 * expected results, limiting it to a maximum at any given time.
27 * 
28 * @author Dave Syer
29 */
30public class ThrottleLimitResultQueue<T> implements ResultQueue<T> {
31 
32        // Accumulation of result objects as they finish.
33        private final BlockingQueue<T> results;
34 
35        // Accumulation of dummy objects flagging expected results in the future.
36        private final Semaphore waits;
37 
38        private final Object lock = new Object();
39 
40        private volatile int count = 0;
41 
42        /**
43         * @param throttleLimit the maximum number of results that can be expected
44         * at any given time.
45         */
46        public ThrottleLimitResultQueue(int throttleLimit) {
47                results = new LinkedBlockingQueue<T>();
48                waits = new Semaphore(throttleLimit);
49        }
50 
51        public boolean isEmpty() {
52                return results.isEmpty();
53        }
54 
55        /*
56         * (non-Javadoc)
57         * 
58         * @see org.springframework.batch.repeat.support.ResultQueue#isExpecting()
59         */
60        public boolean isExpecting() {
61                // Base the decision about whether we expect more results on a
62                // counter of the number of expected results actually collected.
63                // Do not synchronize!  Otherwise put and expect can deadlock.
64                return count > 0;
65        }
66 
67        /**
68         * Tell the queue to expect one more result. Blocks until a new result is
69         * available if already expecting too many (as determined by the throttle
70         * limit).
71         * 
72         * @see ResultQueue#expect()
73         */
74        public void expect() throws InterruptedException {
75                synchronized (lock) {
76                        waits.acquire();
77                        count++;
78                }
79        }
80 
81        public void put(T holder) throws IllegalArgumentException {
82                if (!isExpecting()) {
83                        throw new IllegalArgumentException("Not expecting a result.  Call expect() before put().");
84                }
85                // There should be no need to block here, or to use offer()
86                results.add(holder);
87                // Take from the waits queue now to allow another result to
88                // accumulate. But don't decrement the counter.
89                waits.release();
90        }
91 
92        public T take() throws NoSuchElementException, InterruptedException {
93                if (!isExpecting()) {
94                        throw new NoSuchElementException("Not expecting a result.  Call expect() before take().");
95                }
96                T value;
97                synchronized (lock) {
98                        value = results.take();
99                        // Decrement the counter only when the result is collected.
100                        count--;
101                }
102                return value;
103        }
104 
105}

[all classes][org.springframework.batch.repeat.support]
EMMA 2.0.5312 (C) Vladimir Roubtsov