This is an automated email from the ASF dual-hosted git repository. leerho pushed a commit to branch revert_items_changes_prepare4.1.0 in repository https://gitbox.apache.org/repos/asf/datasketches-java.git
commit e56f0760fdb6aa2e68bd7b9d875bf9deba33e935 Author: Lee Rhodes <[email protected]> AuthorDate: Wed May 31 17:42:18 2023 -0700 Removed partial ItemsSketch work. Left some TODOs as place holders. Left improvements over 4.0.0. This becomes the basis for 3.1.0 changes. Runs all unit tests. --- .../apache/datasketches/hll/DirectCouponList.java | 2 +- .../apache/datasketches/kll/KllGenericProxy.java | 79 ----- .../org/apache/datasketches/kll/KllHelper.java | 39 ++- .../apache/datasketches/kll/KllItemsSketch.java | 320 --------------------- .../org/apache/datasketches/kll/KllSketch.java | 3 +- .../datasketches/quantiles/KolmogorovSmirnov.java | 2 +- .../apache/datasketches/theta/PreambleUtil.java | 1 - .../apache/datasketches/hll/PreambleUtilTest.java | 6 +- .../datasketches/kll/KllMiscDirectFloatsTest.java | 2 +- .../quantiles/KolmogorovSmirnovTest.java | 1 - .../arrayofdoubles/ArrayOfDoublesUnionTest.java | 2 +- 11 files changed, 27 insertions(+), 430 deletions(-) diff --git a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java index b6cc64fd..008aac1d 100644 --- a/src/main/java/org/apache/datasketches/hll/DirectCouponList.java +++ b/src/main/java/org/apache/datasketches/hll/DirectCouponList.java @@ -122,7 +122,7 @@ class DirectCouponList extends AbstractCoupons { insertInt(wmem, LIST_INT_ARR_START + (i << 2), coupon); int couponCount = extractListCount(mem); insertListCount(wmem, ++couponCount); - insertEmptyFlag(wmem, false); //TODO only first time + insertEmptyFlag(wmem, false); //only first time if (couponCount >= len) { //array full if (lgConfigK < 8) { return promoteListOrSetToHll(this);//oooFlag = false diff --git a/src/main/java/org/apache/datasketches/kll/KllGenericProxy.java b/src/main/java/org/apache/datasketches/kll/KllGenericProxy.java deleted file mode 100644 index d424e2c8..00000000 --- a/src/main/java/org/apache/datasketches/kll/KllGenericProxy.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.datasketches.kll; - -import static org.apache.datasketches.kll.KllSketch.Error.TGT_IS_READ_ONLY; -import static org.apache.datasketches.kll.KllSketch.Error.kllSketchThrow; - -abstract class KllGenericProxy<T> extends KllSketch { - - KllGenericProxy() { - super(SketchType.ITEMS_SKETCH, null, null); - } - - /** - * @return full size of internal items array including garbage. - */ - abstract T[] getItemsArray(); - - abstract T getSingleItem(); - - abstract T getMaxItem(); - - abstract T getMinItem(); - - abstract void setItemsArray(T[] Items); - - abstract void setItemsArrayAt(int index, T item); - - abstract void setMaxItem(T item); - - abstract void setMinItem(T item); - - /** - * Merges another sketch into this one. - * Attempting to merge a KllDoublesSketch with a KllFloatsSketch will - * throw an exception. - * @param other sketch to merge into this one - */ - public final void merge(final KllItemsSketch<T> other) { - if (readOnly) { kllSketchThrow(TGT_IS_READ_ONLY); } - //KllItemsHelper.mergeItemImpl((KllItemsSketch)this, other); //TODO - } - - /** - * {@inheritDoc} - * <p>The parameter <i>k</i> will not change.</p> - */ - @SuppressWarnings("unchecked") - @Override - public final void reset() { - if (readOnly) { kllSketchThrow(TGT_IS_READ_ONLY); } - final int k = getK(); - setN(0); - setMinK(k); - setNumLevels(1); - setLevelZeroSorted(false); - setLevelsArray(new int[] {k, k}); - setMinItem(null); - setMaxItem(null); - setItemsArray((T[])(new Object[k])); - } -} diff --git a/src/main/java/org/apache/datasketches/kll/KllHelper.java b/src/main/java/org/apache/datasketches/kll/KllHelper.java index 506836ca..86f37fca 100644 --- a/src/main/java/org/apache/datasketches/kll/KllHelper.java +++ b/src/main/java/org/apache/datasketches/kll/KllHelper.java @@ -250,9 +250,8 @@ final class KllHelper { fltSk.setLevelsArrayAt(lvl, newIndex); } fltSk.setFloatItemsArray(myFloatItemsArr); - } else { - //ITEMS_SKETCH //TODO } + //TODO add items } /** @@ -359,8 +358,7 @@ final class KllHelper { println("Given N : " + gStats.givenN); printf("%10s %10s %20s %13s %15s\n", "NumLevels", "MaxItems", "MaxN", "CompactBytes", "UpdatableBytes"); } - final int typeBytes = sketchType == DOUBLES_SKETCH ? Double.BYTES - : sketchType == FLOATS_SKETCH ? Float.BYTES : 0; //TODO + final int typeBytes = sketchType == DOUBLES_SKETCH ? Double.BYTES : Float.BYTES; do { gStats.numLevels++; // lvlStats = getFinalSketchStatsAtNumLevels(gStats.k, gStats.m, gStats.numLevels, false); @@ -473,8 +471,7 @@ final class KllHelper { final int newItemsArrLen) { final KllSketch.SketchType sketchType = sketch.sketchType; final WritableMemory oldWmem = sketch.wmem; - final int typeBytes = sketchType == DOUBLES_SKETCH ? Double.BYTES - : sketchType == FLOATS_SKETCH ? Float.BYTES : 0; //TODO + final int typeBytes = sketchType == DOUBLES_SKETCH ? Double.BYTES : Float.BYTES; final int requiredSketchBytes = DATA_START_ADR + newLevelsArrLen * Integer.BYTES + 2 * typeBytes @@ -615,7 +612,7 @@ final class KllHelper { if (sketch.getN() == 0) { return byteArr; } //empty final KllDoublesSketch dblSk = (sketch.sketchType == DOUBLES_SKETCH) ? (KllDoublesSketch)sketch : null; final KllFloatsSketch fltSk = (sketch.sketchType == FLOATS_SKETCH) ? (KllFloatsSketch)sketch : null; - //final KllItemsSketch itmSk = (sketch.sketchType == ITEMS_SKETCH) ? (KllItemsSketch)sketch : null; //TODO + //TODO add items //load data int offset = DATA_START_ADR_SINGLE_ITEM; @@ -624,7 +621,7 @@ final class KllHelper { switch (sketch.sketchType) { case DOUBLES_SKETCH : wmem.putDouble(offset, dblSk.getDoubleItemsArray()[myLevelsArr[0]]); break; case FLOATS_SKETCH : wmem.putFloat(offset, fltSk.getFloatItemsArray()[myLevelsArr[0]]); break; - case ITEMS_SKETCH : break; //TODO + //case ITEMS_SKETCH : break; //TODO default: throw new IllegalStateException("Unknown Sketch Type"); } } else { // n > 1 @@ -657,7 +654,7 @@ final class KllHelper { wmem.putFloatArray(offset, fltSk.getFloatItemsArray(), myLevelsArr[0], sketch.getNumRetained()); break; } - case ITEMS_SKETCH : break; //TODO + //case ITEMS_SKETCH : break; //TODO default: throw new IllegalStateException("Unknown Sketch Type"); } @@ -707,10 +704,10 @@ final class KllHelper { ByteArrayUtil.putDoubleLE(byteArr, DATA_START_ADR_SINGLE_ITEM, dblSk.getDoubleSingleItem()); break; } - case ITEMS_SKETCH: { - byteArr = null; //TODO - break; - } +// case ITEMS_SKETCH: { +// byteArr = null; //TODO +// break; +// } default: return null; //can't happen } return byteArr; @@ -859,9 +856,9 @@ final class KllHelper { final float[] floatItemsArr = fltSk.getFloatItemsArray(); wmem.putFloatArray(offset, floatItemsArr, 0, floatItemsArr.length); } - else { - //ITEMS_SKETCH //TODO - } +// else { +// //ITEMS_SKETCH //TODO +// } return byteArr; } @@ -921,9 +918,10 @@ final class KllHelper { maxFloat = fltSk.getMaxFloatItem(); myCurFloatItemsArr = fltSk.getFloatItemsArray(); assert myCurFloatItemsArr.length == myCurTotalItemsCapacity; - } else { - //ITEMS_SKETCH //TODO } +// else { +// //ITEMS_SKETCH //TODO +// } assert myCurLevelsArr[0] == 0; //definition of full is part of the growth scheme final int deltaItemsCap = levelCapacity(sketch.getK(), myCurNumLevels + 1, 0, sketch.getM()); @@ -959,9 +957,10 @@ final class KllHelper { myNewFloatItemsArr = new float[myNewTotalItemsCapacity]; // copy and shift the current items data into the new array System.arraycopy(myCurFloatItemsArr, 0, myNewFloatItemsArr, deltaItemsCap, myCurTotalItemsCapacity); - } else { - //ITEMS_SKETCH // TODO } +// else { +// //ITEMS_SKETCH // TODO +// } //MEMORY SPACE MANAGEMENT if (sketch.updatableMemFormat) { diff --git a/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java b/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java deleted file mode 100644 index 00d44dea..00000000 --- a/src/main/java/org/apache/datasketches/kll/KllItemsSketch.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.datasketches.kll; - -import static java.lang.Math.max; -import static java.lang.Math.min; - -import java.util.Comparator; -import java.util.Objects; - -import org.apache.datasketches.common.ArrayOfItemsSerDe; -import org.apache.datasketches.quantilescommon.GenericSortedView; -import org.apache.datasketches.quantilescommon.QuantileSearchCriteria; -import org.apache.datasketches.quantilescommon.QuantilesGenericAPI; -import org.apache.datasketches.quantilescommon.QuantilesGenericSketchIterator; - -public class KllItemsSketch<T> extends KllGenericProxy<T> implements QuantilesGenericAPI<T> { - private final int k_; // configured size of K. - private final int m_; // configured size of M. - private long n_; // number of items input into this sketch. - private int minK_; // dynamic minK for error estimation after merging with different k. - private boolean isLevelZeroSorted_; - private T maxItem_; - private T minItem_; - Object[] items_; - final Class<T> clazz_; - private final Comparator<? super T> comparator_; - private final ArrayOfItemsSerDe<T> serDe_; - - KllItemsSketch( - final int k, - final int m, - final Class<T> clazz, - final Comparator<? super T> comparator, - final ArrayOfItemsSerDe<T> serDe) { - super(); - Objects.requireNonNull(clazz, "Class<T> must not be null."); - Objects.requireNonNull(comparator, "Comparator must not be null."); - Objects.requireNonNull(serDe, "Serializer/Deserializer must not be null."); - KllHelper.checkM(m); - KllHelper.checkK(k, m); - k_ = k; - m_ = DEFAULT_M; - n_ = 0; - minK_ = k; - isLevelZeroSorted_ = false; - maxItem_ = null; - minItem_ = null; - items_ = new Object[k]; - levelsArr = new int[] {k, k}; - clazz_ = clazz; - comparator_ = comparator; - serDe_ = serDe; - } - - /** - * Create a new heap instance of this sketch with the default <em>k = 200</em>. - * The default <em>k</em> = 200 results in a normalized rank error of about - * 1.65%. Larger K will have smaller error but the sketch will be larger (and slower). - * This will have a rank error of about 1.65%. - * @param <T> The sketch data type - * @param clazz the given class of T - * @param comparator to compare items - * @param serDe Serializer / deserializer for an array of items, <i>T[]</i>. - * @return new KllItemsSketch on the heap. - */ - public static <T> KllItemsSketch<T> newHeapInstance( - final Class<T> clazz, - final Comparator<? super T> comparator, - final ArrayOfItemsSerDe<T> serDe) { - final KllItemsSketch<T> itmSk = new KllItemsSketch<T>(DEFAULT_K, DEFAULT_M, clazz, comparator, serDe); - return itmSk; - } - - /** - * Create a new heap instance of this sketch with a given parameter <em>k</em>. - * <em>k</em> can be between DEFAULT_M and 65535, inclusive. - * The default <em>k</em> = 200 results in a normalized rank error of about - * 1.65%. Larger K will have smaller error but the sketch will be larger (and slower). - * @param k parameter that controls size of the sketch and accuracy of estimates. - * @param <T> The sketch data type - * @param clazz the given class of T - * @param comparator to compare items - * @param serDe Serializer / deserializer for an array of items, <i>T[]</i>. - * @return new KllItemsSketch on the heap. - */ - public static <T> KllItemsSketch<T> newHeapInstance( - final int k, - final Class<T> clazz, - final Comparator<? super T> comparator, - final ArrayOfItemsSerDe<T> serDe) { - final KllItemsSketch<T> itmSk = new KllItemsSketch<T>(k, DEFAULT_M, clazz, comparator, serDe); - return itmSk; - } - - /** - * {@inheritDoc} - * The approximate probability that the true rank is within the confidence interval - * specified by the upper and lower rank bounds for this sketch is 0.99. - */ - @Override - public double getRankLowerBound(final double rank) { - return max(0.0, rank - KllHelper.getNormalizedRankError(getMinK(), false)); - } - - /** - * {@inheritDoc} - * The approximate probability that the true rank is within the confidence interval - * specified by the upper and lower rank bounds for this sketch is 0.99. - */ - @Override - public double getRankUpperBound(final double rank) { - return min(1.0, rank + KllHelper.getNormalizedRankError(getMinK(), false)); - } - - @Override - public double[] getCDF(final T[] splitPoints, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getMaxItem() { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getMinItem() { - // TODO Auto-generated method stub - return null; - } - - @Override - public GenericPartitionBoundaries<T> getPartitionBoundaries(final int numEquallyWeighted, - final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public double[] getPMF(final T[] splitPoints, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getQuantile(final double rank, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getQuantileLowerBound(final double rank) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getQuantileUpperBound(final double rank) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T[] getQuantiles(final double[] ranks, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public double getRank(final T quantile, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public double[] getRanks(final T[] quantiles, final QuantileSearchCriteria searchCrit) { - // TODO Auto-generated method stub - return null; - } - - @Override - public GenericSortedView<T> getSortedView() { - // TODO Auto-generated method stub - return null; - } - - @Override - public QuantilesGenericSketchIterator<T> iterator() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void update(final T item) { - // TODO Auto-generated method stub - - } - - @Override - public int getK() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public long getN() { - // TODO Auto-generated method stub - return 0; - } - - @Override - int getM() { - // TODO Auto-generated method stub - return 0; - } - - @Override - int getMinK() { - // TODO Auto-generated method stub - return 0; - } - - @Override - void incN() { - // TODO Auto-generated method stub - - } - - @Override - void incNumLevels() { - // TODO Auto-generated method stub - - } - - @Override - boolean isLevelZeroSorted() { - // TODO Auto-generated method stub - return false; - } - - @Override - void setLevelZeroSorted(final boolean sorted) { - // TODO Auto-generated method stub - - } - - @Override - void setMinK(final int minK) { - // TODO Auto-generated method stub - - } - - @Override - void setN(final long n) { - // TODO Auto-generated method stub - - } - - @Override - void setNumLevels(final int numLevels) { - // TODO Auto-generated method stub - - } - - @Override - T[] getItemsArray() { - // TODO Auto-generated method stub - return null; - } - - @Override - T getSingleItem() { - // TODO Auto-generated method stub - return null; - } - - @Override - void setItemsArray(final T[] Items) { - // TODO Auto-generated method stub - - } - - @Override - void setItemsArrayAt(final int index, final T item) { - // TODO Auto-generated method stub - - } - - @Override - void setMaxItem(final T item) { - // TODO Auto-generated method stub - - } - - @Override - void setMinItem(final T item) { - // TODO Auto-generated method stub - - } - -} diff --git a/src/main/java/org/apache/datasketches/kll/KllSketch.java b/src/main/java/org/apache/datasketches/kll/KllSketch.java index ed00321f..eb264aa9 100644 --- a/src/main/java/org/apache/datasketches/kll/KllSketch.java +++ b/src/main/java/org/apache/datasketches/kll/KllSketch.java @@ -345,9 +345,8 @@ public abstract class KllSketch implements QuantilesAPI { } else if (sketchType == FLOATS_SKETCH) { if (!other.isFloatsSketch()) { kllSketchThrow(SRC_MUST_BE_FLOAT); } KllFloatsHelper.mergeFloatImpl((KllFloatsSketch)this, other); - } else { - //ITEMS_SKETCH //TODO } + //TODO items } @Override diff --git a/src/main/java/org/apache/datasketches/quantiles/KolmogorovSmirnov.java b/src/main/java/org/apache/datasketches/quantiles/KolmogorovSmirnov.java index ef2b9004..c290b059 100644 --- a/src/main/java/org/apache/datasketches/quantiles/KolmogorovSmirnov.java +++ b/src/main/java/org/apache/datasketches/quantiles/KolmogorovSmirnov.java @@ -25,7 +25,7 @@ package org.apache.datasketches.quantiles; */ final class KolmogorovSmirnov { - //TODO This KS test will have to be redesigned to accomodate REQ sketches. + //TODO This KS test will have to be redesigned to accommodate REQ sketches. /** * Computes the raw delta area between two quantile sketches for the diff --git a/src/main/java/org/apache/datasketches/theta/PreambleUtil.java b/src/main/java/org/apache/datasketches/theta/PreambleUtil.java index 2a6c9790..562be982 100644 --- a/src/main/java/org/apache/datasketches/theta/PreambleUtil.java +++ b/src/main/java/org/apache/datasketches/theta/PreambleUtil.java @@ -477,7 +477,6 @@ final class PreambleUtil { wmem.putLong(UNION_THETA_LONG, unionThetaLong); } - //TODO convert these to set/clear/any bits static void setEmpty(final WritableMemory wmem) { int flags = wmem.getByte(FLAGS_BYTE) & 0XFF; flags |= EMPTY_FLAG_MASK; diff --git a/src/test/java/org/apache/datasketches/hll/PreambleUtilTest.java b/src/test/java/org/apache/datasketches/hll/PreambleUtilTest.java index 2c56b24e..cd1e0cbc 100644 --- a/src/test/java/org/apache/datasketches/hll/PreambleUtilTest.java +++ b/src/test/java/org/apache/datasketches/hll/PreambleUtilTest.java @@ -31,18 +31,18 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; -import org.testng.annotations.Test; import org.apache.datasketches.common.SketchesArgumentException; import org.apache.datasketches.memory.Memory; import org.apache.datasketches.memory.WritableMemory; +import org.testng.annotations.Test; /** * @author Lee Rhodes */ public class PreambleUtilTest { - @Test - public void preambleToString() { //TODO Check Visually + //@Test + public void preambleToString() { // Check Visually int bytes = HllSketch.getMaxUpdatableSerializationBytes(8, TgtHllType.HLL_4); byte[] byteArr1 = new byte[bytes]; WritableMemory wmem1 = WritableMemory.writableWrap(byteArr1); diff --git a/src/test/java/org/apache/datasketches/kll/KllMiscDirectFloatsTest.java b/src/test/java/org/apache/datasketches/kll/KllMiscDirectFloatsTest.java index ed141e7b..4755a4ab 100644 --- a/src/test/java/org/apache/datasketches/kll/KllMiscDirectFloatsTest.java +++ b/src/test/java/org/apache/datasketches/kll/KllMiscDirectFloatsTest.java @@ -391,7 +391,7 @@ public class KllMiscDirectFloatsTest { public void checkSizes() { KllFloatsSketch sk = getDFSketch(20, 0); for (int i = 1; i <= 21; i++) { sk.update(i); } - println(sk.toString(true, true)); //TODO + //println(sk.toString(true, true)); byte[] byteArr1 = KllHelper.toUpdatableByteArrayImpl(sk); int size1 = sk.getCurrentUpdatableSerializedSizeBytes(); assertEquals(size1, byteArr1.length); diff --git a/src/test/java/org/apache/datasketches/quantiles/KolmogorovSmirnovTest.java b/src/test/java/org/apache/datasketches/quantiles/KolmogorovSmirnovTest.java index 20d5f1b3..fd8e4f71 100644 --- a/src/test/java/org/apache/datasketches/quantiles/KolmogorovSmirnovTest.java +++ b/src/test/java/org/apache/datasketches/quantiles/KolmogorovSmirnovTest.java @@ -43,7 +43,6 @@ public class KolmogorovSmirnovTest { s1.update(x + 500); s2.update(x); } - //TODO NEED TO FIX KS Algo, it assumed non-inclusive cumulative weight arrays //assertEquals(KolmogorovSmirnov.computeKSDelta(s1, s2), 1.0, 1E-6); println("D = " + KolmogorovSmirnov.computeKSDelta(s1, s2)); } diff --git a/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/ArrayOfDoublesUnionTest.java b/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/ArrayOfDoublesUnionTest.java index fd530a12..5171c654 100644 --- a/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/ArrayOfDoublesUnionTest.java +++ b/src/test/java/org/apache/datasketches/tuple/arrayofdoubles/ArrayOfDoublesUnionTest.java @@ -467,7 +467,7 @@ public class ArrayOfDoublesUnionTest { WritableMemory mem2 = WritableMemory.writableWrap(new byte[1_000_000]); ArrayOfDoublesCompactSketch dcsk = sketch.compact(mem2); ArrayOfDoublesUnion union = ArrayOfDoublesSketches.wrapUnion(mem); //empty union - union.union(dcsk); //TODO est error + union.union(dcsk); //ArrayOfDoublesSketches.wrapUnion(mem).union(sketch.compact(WritableMemory.writableWrap(new byte[1_000_000]))); final ArrayOfDoublesSketch result = ArrayOfDoublesUnion.wrap(mem).getResult(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
