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.GeneratorContext;
30  import com.rapiddweller.benerator.InvalidGeneratorSetupException;
31  import com.rapiddweller.benerator.primitive.number.AbstractNonNullNumberGenerator;
32  
33  /**
34   * Long Generator that implements a 'shuffle' Long Sequence:
35   * It starts with min and produced numbers by continuously incrementing the cursor
36   * by a fix <code>increment</code> value; when <code>max</code> is reached, it
37   * repeats the procedure starting by min+granularity, later min+2*granularity and so on.
38   * The generated numbers are unique as long as the generator is not reset.<br/>
39   * <br/>
40   * Created: 18.06.2006 14:40:29
41   *
42   * @author Volker Bergmann
43   * @since 0.1
44   */
45  public class ShuffleLongGenerator extends AbstractNonNullNumberGenerator<Long> {
46  
47    private long increment;
48    private Long next;
49  
50    /**
51     * Instantiates a new Shuffle long generator.
52     */
53    public ShuffleLongGenerator() {
54      this(Long.MIN_VALUE, Long.MAX_VALUE);
55    }
56  
57    /**
58     * Instantiates a new Shuffle long generator.
59     *
60     * @param min the min
61     * @param max the max
62     */
63    public ShuffleLongGenerator(long min, long max) {
64      this(min, max, 2, 1);
65    }
66  
67    /**
68     * Instantiates a new Shuffle long generator.
69     *
70     * @param min         the min
71     * @param max         the max
72     * @param granularity the granularity
73     * @param increment   the increment
74     */
75    public ShuffleLongGenerator(long min, long max, long granularity, long increment) {
76      super(Long.class, min, max, granularity);
77      this.increment = increment;
78      reset();
79    }
80  
81    // config properties -----------------------------------------------------------------------------------------------
82  
83    /**
84     * Gets increment.
85     *
86     * @return the increment
87     */
88    public long getIncrement() {
89      return increment;
90    }
91  
92    /**
93     * Sets increment.
94     *
95     * @param increment the increment
96     */
97    public void setIncrement(long increment) {
98      this.increment = increment;
99    }
100 
101   // Generator interface ---------------------------------------------------------------------------------------------
102 
103   @Override
104   public void init(GeneratorContext context) {
105     assertNotInitialized();
106     if (granularity <= 0) {
107       throw new InvalidGeneratorSetupException("Granularity must be greater than zero, but is " + granularity);
108     }
109     if (min < max && increment <= 0) {
110       throw new InvalidGeneratorSetupException("Unsupported increment value: " + increment);
111     }
112     next = min;
113     super.init(context);
114   }
115 
116   @Override
117   public synchronized Long generate() {
118     assertInitialized();
119     if (next == null) {
120       return null;
121     }
122     long result = next;
123     if (next + increment <= max) {
124       next += increment;
125     } else {
126       long newOffset = (next - min + granularity) % increment;
127       next = (newOffset > 0 ? min + newOffset : null);
128     }
129     return result;
130   }
131 
132   @Override
133   public synchronized void reset() {
134     this.next = min;
135   }
136 
137 }