View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.distribution.sequence;
28  
29  import com.rapiddweller.benerator.util.RandomUtil;
30  
31  import java.util.ArrayList;
32  
33  /**
34   * Helper class for the {@link ExpandGeneratorProxy}.
35   * It can buffer a number of values provided from a source and provide a randomly selected one.
36   * The class is optimized for performance: As long as the source is available, the client
37   * can fetch a random value by calling randomElement(E feed) providing a new value from the
38   * source. The {@link ValueBucket} will then select a random element from its buffer, return
39   * it and replace the internal value with the new feed value. When the source is no longer
40   * available, a call to randomElement() will return the last value from the buffer and remove
41   * it (avoiding expensive shift operations that would result from choosing value from a random
42   * position).<br/>
43   * <br/>
44   * Created: 10.12.2009 15:10:33
45   *
46   * @param <E> the type parameter
47   * @author Volker Bergmann
48   * @since 0.6.0
49   */
50  class ValueBucket<E> {
51  
52    private final ArrayList<E> buffer;
53  
54    /**
55     * Instantiates a new Value bucket.
56     *
57     * @param capacity the capacity
58     */
59    public ValueBucket(int capacity) {
60      buffer = new ArrayList<>();
61    }
62  
63    // interface -------------------------------------------------------------------------------------------------------
64  
65    /**
66     * Is empty boolean.
67     *
68     * @return the boolean
69     */
70    public boolean isEmpty() {
71      return buffer.isEmpty();
72    }
73  
74    /**
75     * Add.
76     *
77     * @param feed the feed
78     */
79    public void add(E feed) {
80      buffer.add(feed);
81    }
82  
83    /**
84     * Gets random element.
85     *
86     * @return the random element
87     */
88    public synchronized E getRandomElement() {
89      return buffer.get(RandomUtil.randomIndex(buffer));
90    }
91  
92    /**
93     * Gets and replace random element.
94     *
95     * @param feed the feed
96     * @return the and replace random element
97     */
98    public synchronized E getAndReplaceRandomElement(E feed) {
99      int index = RandomUtil.randomIndex(buffer);
100     E result = buffer.get(index);
101     buffer.set(index, feed);
102     return result;
103   }
104 
105   /**
106    * Gets and remove random element.
107    *
108    * @return the and remove random element
109    */
110   public synchronized E getAndRemoveRandomElement() {
111     int lastIndex = buffer.size() - 1;
112     E result = buffer.get(lastIndex);
113     buffer.remove(lastIndex);
114     return result;
115   }
116 
117   /**
118    * Size int.
119    *
120    * @return the int
121    */
122   public int size() {
123     return buffer.size();
124   }
125 
126   // java.lang.Object overrides --------------------------------------------------------------------------------------
127 
128   @Override
129   public String toString() {
130     return getClass().getSimpleName() + buffer;
131   }
132 
133 }