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 }