@@ -189,6 +189,12 @@ public class Generator {
189
189
* {@link #ITERATION_PROP_RESTART} is less than the value for {@link #ITERATION_PROP_START}.
190
190
*/
191
191
public static final String ITERATION_PROP_STEP = "step" ;
192
+ /**
193
+ * The name of the attribute for specifying the initial value in a schema with iterative
194
+ * generation. If given, must be a numeric type that is integral if the given schema is as well.
195
+ * If not given, defaults to the value for {@link #ITERATION_PROP_START}.
196
+ */
197
+ public static final String ITERATION_PROP_INITIAL = "initial" ;
192
198
193
199
static final String DECIMAL_LOGICAL_TYPE_NAME = "decimal" ;
194
200
@@ -650,6 +656,7 @@ private Iterator<Object> getIntegralIterator(
650
656
Long iterationStartField ,
651
657
Long iterationRestartField ,
652
658
Long iterationStepField ,
659
+ Long iterationInitialField ,
653
660
IntegralIterator .Type type ) {
654
661
655
662
if (iterationStartField == null ) {
@@ -750,10 +757,16 @@ private Iterator<Object> getIntegralIterator(
750
757
}
751
758
}
752
759
760
+ long iterationInitial = iterationStart ;
761
+ if (iterationInitialField != null ) {
762
+ iterationInitial = iterationInitialField ;
763
+ }
764
+
753
765
return new IntegralIterator (
754
766
iterationStart ,
755
767
iterationRestart ,
756
768
iterationStep ,
769
+ iterationInitial ,
757
770
generation ,
758
771
type
759
772
);
@@ -763,6 +776,7 @@ private Iterator<Object> getDecimalIterator(
763
776
Double iterationStartField ,
764
777
Double iterationRestartField ,
765
778
Double iterationStepField ,
779
+ Double iterationInitialField ,
766
780
DecimalIterator .Type type ) {
767
781
768
782
if (iterationStartField == null ) {
@@ -863,10 +877,16 @@ private Iterator<Object> getDecimalIterator(
863
877
}
864
878
}
865
879
880
+ double iterationInitial = iterationStart ;
881
+ if (iterationInitialField != null ) {
882
+ iterationInitial = iterationInitialField ;
883
+ }
884
+
866
885
return new DecimalIterator (
867
886
iterationStart ,
868
887
iterationRestart ,
869
888
iterationStep ,
889
+ iterationInitial ,
870
890
generation ,
871
891
type
872
892
);
@@ -927,10 +947,16 @@ private Iterator<Object> getDoubleIterator(final Map iterationProps) {
927
947
ITERATION_PROP_STEP ,
928
948
iterationProps
929
949
);
950
+ Double iterationInitialField = getDecimalNumberField (
951
+ ITERATION_PROP ,
952
+ ITERATION_PROP_INITIAL ,
953
+ iterationProps
954
+ );
930
955
return getDecimalIterator (
931
956
iterationStartField ,
932
957
iterationRestartField ,
933
958
iterationStepField ,
959
+ iterationInitialField ,
934
960
DecimalIterator .Type .DOUBLE
935
961
);
936
962
}
@@ -951,10 +977,16 @@ private Iterator<Object> getFloatIterator(final Map iterationProps) {
951
977
ITERATION_PROP_STEP ,
952
978
iterationProps
953
979
);
980
+ Float iterationInitialField = getFloatNumberField (
981
+ ITERATION_PROP ,
982
+ ITERATION_PROP_INITIAL ,
983
+ iterationProps
984
+ );
954
985
return getDecimalIterator (
955
986
iterationStartField != null ? iterationStartField .doubleValue () : null ,
956
987
iterationRestartField != null ? iterationRestartField .doubleValue () : null ,
957
988
iterationStepField != null ? iterationStepField .doubleValue () : null ,
989
+ iterationInitialField != null ? iterationInitialField .doubleValue () : null ,
958
990
DecimalIterator .Type .FLOAT
959
991
);
960
992
}
@@ -975,10 +1007,16 @@ private Iterator<Object> getLongIterator(final Map iterationProps) {
975
1007
ITERATION_PROP_STEP ,
976
1008
iterationProps
977
1009
);
1010
+ Long iterationInitialField = getIntegralNumberField (
1011
+ ITERATION_PROP ,
1012
+ ITERATION_PROP_INITIAL ,
1013
+ iterationProps
1014
+ );
978
1015
return getIntegralIterator (
979
1016
iterationStartField ,
980
1017
iterationRestartField ,
981
1018
iterationStepField ,
1019
+ iterationInitialField ,
982
1020
IntegralIterator .Type .LONG
983
1021
);
984
1022
}
@@ -1013,10 +1051,16 @@ private Iterator<Object> getIntegerIterator(Map iterationProps) {
1013
1051
ITERATION_PROP_STEP ,
1014
1052
iterationProps
1015
1053
);
1054
+ Integer iterationInitialField = getIntegerNumberField (
1055
+ ITERATION_PROP ,
1056
+ ITERATION_PROP_INITIAL ,
1057
+ iterationProps
1058
+ );
1016
1059
return getIntegralIterator (
1017
1060
iterationStartField != null ? iterationStartField .longValue () : null ,
1018
1061
iterationRestartField != null ? iterationRestartField .longValue () : null ,
1019
1062
iterationStepField != null ? iterationStepField .longValue () : null ,
1063
+ iterationInitialField != null ? iterationInitialField .longValue () : null ,
1020
1064
IntegralIterator .Type .INTEGER
1021
1065
);
1022
1066
}
@@ -1486,18 +1530,19 @@ public enum Type {
1486
1530
private final Type type ;
1487
1531
private BigInteger current ;
1488
1532
1489
- public IntegralIterator (long start , long restart , long step , long count , Type type ) {
1533
+ public IntegralIterator (long start , long restart , long step , long initial , long count , Type type ) {
1490
1534
this .start = BigInteger .valueOf (start );
1491
1535
this .restart = BigInteger .valueOf (restart );
1492
1536
this .step = BigInteger .valueOf (step );
1493
1537
this .type = type ;
1494
- current = BigInteger .ZERO ;
1538
+ current = BigInteger .valueOf ( initial ). subtract ( this . start ) ;
1495
1539
if (count > 0 ) {
1496
1540
// This is essentially the following expression when ignoring negative values:
1497
1541
// current = (count * step) % (restart - start)
1498
1542
// except BigInteger::mod only operates on positive numbers, so remove and re-add the sign after the modulo.
1499
1543
current = BigInteger .valueOf (count )
1500
1544
.multiply (this .step )
1545
+ .add (current )
1501
1546
.abs ()
1502
1547
.mod (this .restart .subtract (this .start ).abs ())
1503
1548
.multiply (this .step .divide (this .step .abs ()));
@@ -1541,16 +1586,17 @@ public enum Type {
1541
1586
private final Type type ;
1542
1587
private BigDecimal current ;
1543
1588
1544
- public DecimalIterator (double start , double restart , double step , long count , Type type ) {
1589
+ public DecimalIterator (double start , double restart , double step , double initial , long count , Type type ) {
1545
1590
this .start = BigDecimal .valueOf (start );
1546
1591
this .restart = BigDecimal .valueOf (restart );
1547
1592
this .modulo = this .restart .subtract (this .start );
1548
1593
this .step = BigDecimal .valueOf (step );
1549
1594
this .type = type ;
1550
- current = BigDecimal .ZERO ;
1595
+ current = BigDecimal .valueOf ( initial ). subtract ( this . start ) ;
1551
1596
if (count > 0 ) {
1552
1597
current = BigDecimal .valueOf (count )
1553
1598
.multiply (this .step )
1599
+ .add (current )
1554
1600
.remainder (this .modulo );
1555
1601
}
1556
1602
}
0 commit comments