001: /*
002: * (c) Copyright 2007 by Volker Bergmann. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, is permitted under the terms of the
006: * GNU General Public License.
007: *
008: * For redistributing this software or a derivative work under a license other
009: * than the GPL-compatible Free Software License as defined by the Free
010: * Software Foundation or approved by OSI, you must first obtain a commercial
011: * license to this software product from Volker Bergmann.
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
014: * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
015: * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
016: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
017: * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
018: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
019: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
020: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
021: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
022: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
023: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGE.
025: */
026:
027: package org.databene.benerator.primitive;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.databene.benerator.Generator;
032: import org.databene.benerator.InvalidGeneratorSetupException;
033:
034: /**
035: * Combines the output of a 'slow' generator (e.g. a remote hiGenerator)
036: * with quickly generated numbers in a range: value = hi * maxLo + local.
037: * @author Volker Bergmann
038: * @since 0.3.04
039: */
040: public class HiLoGenerator implements Generator<Long> {
041:
042: private static final Log logger = LogFactory
043: .getLog(HiLoGenerator.class);
044:
045: protected static final int DEFAULT_MAX_LO = 100;
046:
047: protected int maxLo;
048:
049: private int lo;
050: private long hi;
051:
052: protected Generator<Long> hiGenerator;
053: protected boolean dirty;
054:
055: public HiLoGenerator() {
056: this (new IncrementGenerator(), DEFAULT_MAX_LO);
057: }
058:
059: public HiLoGenerator(Generator<Long> hiGenerator) {
060: this (hiGenerator, DEFAULT_MAX_LO);
061: }
062:
063: public HiLoGenerator(Generator<Long> hiGenerator, int maxLo) {
064: this .hiGenerator = hiGenerator;
065: setMaxLo(maxLo);
066: this .lo = -1;
067: this .hi = -1;
068: this .dirty = true;
069: }
070:
071: // properties ------------------------------------------------------------------------------------
072:
073: public void setHiGenerator(Generator<Long> hiGenerator) {
074: this .hiGenerator = hiGenerator;
075: }
076:
077: /**
078: * @return the maxLo
079: */
080: public int getMaxLo() {
081: return maxLo;
082: }
083:
084: /**
085: * @param maxLo the maxLo to set
086: */
087: public void setMaxLo(int maxLo) {
088: if (maxLo <= 0)
089: throw new IllegalArgumentException(
090: "maxLo must be greater than 0, was: " + maxLo);
091: this .maxLo = maxLo;
092: this .dirty = true;
093: }
094:
095: // Generator interface -------------------------------------------------------------------
096:
097: public Class<Long> getGeneratedType() {
098: return Long.class;
099: }
100:
101: public void validate() {
102: if (dirty) {
103: if (hiGenerator == null)
104: throw new InvalidGeneratorSetupException("hiGenerator",
105: "is null");
106: hiGenerator.validate();
107: dirty = false;
108: }
109: }
110:
111: public boolean available() {
112: if (dirty)
113: validate();
114: return hiGenerator.available();
115: }
116:
117: public Long generate() {
118: if (dirty)
119: validate();
120: if (hi == -1 || lo >= maxLo) {
121: hi = hiGenerator.generate();
122: if (logger.isDebugEnabled())
123: logger.debug("fetched new hi value: " + hi);
124: lo = 0;
125: } else
126: lo++;
127: return hi * (maxLo + 1) + lo;
128: }
129:
130: public void reset() {
131: if (dirty)
132: validate();
133: hiGenerator.reset();
134: hi = -1;
135: dirty = true;
136: }
137:
138: public void close() {
139: if (dirty)
140: validate();
141: hiGenerator.close();
142: }
143:
144: @Override
145: public String toString() {
146: return getClass().getSimpleName() + '[' + maxLo + ','
147: + hiGenerator + ']';
148: }
149: }
|