Repository: jena Updated Branches: refs/heads/master 6fbecf1e3 -> d36034820
JENA-1107: Rework Tuple Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/571e9755 Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/571e9755 Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/571e9755 Branch: refs/heads/master Commit: 571e97553c9d5ccb29818ed85afb70e4fe0318c2 Parents: c81557a Author: Andy Seaborne <[email protected]> Authored: Mon Dec 28 16:27:01 2015 +0000 Committer: Andy Seaborne <[email protected]> Committed: Mon Dec 28 16:27:01 2015 +0000 ---------------------------------------------------------------------- .../java/org/apache/jena/atlas/lib/FileOps.java | 7 +- .../java/org/apache/jena/atlas/lib/Tuple.java | 131 ------ .../org/apache/jena/atlas/lib/tuple/Tuple.java | 63 +++ .../org/apache/jena/atlas/lib/tuple/Tuple0.java | 37 ++ .../org/apache/jena/atlas/lib/tuple/Tuple1.java | 42 ++ .../org/apache/jena/atlas/lib/tuple/Tuple2.java | 46 +++ .../org/apache/jena/atlas/lib/tuple/Tuple3.java | 49 +++ .../org/apache/jena/atlas/lib/tuple/Tuple4.java | 52 +++ .../org/apache/jena/atlas/lib/tuple/Tuple5.java | 55 +++ .../org/apache/jena/atlas/lib/tuple/Tuple6.java | 58 +++ .../org/apache/jena/atlas/lib/tuple/Tuple7.java | 61 +++ .../org/apache/jena/atlas/lib/tuple/Tuple8.java | 64 +++ .../apache/jena/atlas/lib/tuple/TupleBase.java | 73 ++++ .../jena/atlas/lib/tuple/TupleFactory.java | 122 ++++++ .../apache/jena/atlas/lib/tuple/TupleList.java | 43 ++ .../apache/jena/atlas/lib/tuple/TupleMap.java | 404 +++++++++++++++++++ .../org/apache/jena/atlas/lib/tuple/TupleN.java | 55 +++ .../jena/atlas/lib/tuple/package-info.java | 34 ++ .../java/org/apache/jena/atlas/TC_Atlas.java | 2 + .../org/apache/jena/atlas/lib/TestFileOps.java | 2 +- .../apache/jena/atlas/lib/tuple/TS_Tuple.java | 32 ++ .../apache/jena/atlas/lib/tuple/TestTuple.java | 201 +++++++++ .../jena/atlas/lib/tuple/TestTupleMap.java | 186 +++++++++ 23 files changed, 1685 insertions(+), 134 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java index cf2e6ee..8ede725 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java @@ -21,8 +21,11 @@ package org.apache.jena.atlas.lib ; import java.io.File ; import java.io.IOException ; import java.nio.file.Files; + import org.apache.jena.atlas.AtlasException ; import org.apache.jena.atlas.io.IO ; +import org.apache.jena.atlas.lib.tuple.Tuple ; +import org.apache.jena.atlas.lib.tuple.TupleFactory ; import org.apache.jena.atlas.logging.Log ; /** A library of utility operations on files and the filing system */ @@ -146,7 +149,7 @@ public class FileOps { basename = basename.substring(0, i) ; } - return Tuple.createTuple(path, basename, ext) ; + return TupleFactory.tuple(path, basename, ext) ; } /** @@ -165,7 +168,7 @@ public class FileOps { path = filename.substring(0, j) ; fn = filename.substring(j + 1) ; } - return Tuple.createTuple(path, fn) ; + return TupleFactory.tuple(path, fn) ; } /** Return the basename (no path, no extension) */ http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java deleted file mode 100644 index ec0e420..0000000 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java +++ /dev/null @@ -1,131 +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.jena.atlas.lib ; - -import java.util.Arrays ; -import java.util.Iterator ; -import java.util.List ; -import java.util.Objects; -import java.util.function.Function; - -import org.apache.jena.atlas.iterator.Iter ; - -/** Tuple class - tuples are immutable and must be created initialized */ -public class Tuple<T> implements Iterable<T> { - // Interface this? - // Classes: TupleImpl, TupleSlice - public static <X> Tuple<X> createTuple(@SuppressWarnings("unchecked") X... elements) { - X[] els = elements ; // ArrayUtils.copy(elements) ; - return create(els) ; - } - - /** - * Create a tuple from an array of elements. The array is not copied and - * should not be modified after this call. - */ - public static <X> Tuple<X> create(X[] elements) { - return new Tuple<>(elements) ; - } - - // TupleLib?? - public static <T> Iterator<T> project(final int slot, Iterator<Tuple<T>> iter) { - return Iter.map(iter, t -> t.get(slot)) ; - } - - public static <T> Iterator<Tuple<T>> prefix(final int prefixLength, Iterator<Tuple<T>> iter) { - Function<Tuple<T>, Tuple<T>> sub = t -> { - T[] x = ArrayUtils.copy(t.tuple, 0, prefixLength) ; - return Tuple.create(x) ; - } ; - return Iter.map(iter, sub) ; - } - - protected final T[] tuple ; - - protected Tuple(@SuppressWarnings("unchecked") T... tuple) { - this.tuple = tuple ; - } - - public T get(int idx) { - return tuple[idx] ; - } - - public int countNotNull() { - int x = 0 ; - for ( T item : tuple ) - if ( item != null ) - x++ ; - return x ; - } - - public List<T> asList() { - return Arrays.asList(tuple) ; - } - - public T[] tuple() { - return tuple ; - } - - public T[] tupleCopy() { - return ArrayUtils.copy(tuple) ; - } - - @Override - public Iterator<T> iterator() { - return Arrays.asList(tuple).iterator() ; - } - - public int size() { - return tuple.length ; - } - - @Override - public int hashCode() { - int x = 99 ; - for ( T n : tuple ) { - if ( n != null ) - x = x << 1 ^ n.hashCode() ; - } - return x ; - } - - /** Equality of tuples is based on equality of the elements in the tuple */ - @Override - public boolean equals(Object other) { - if ( this == other ) - return true ; - if ( !(other instanceof Tuple<? >) ) - return false ; - Tuple<? > x = (Tuple<? >)other ; - if ( x.size() != this.size() ) - return false ; - for ( int i = 0 ; i < tuple.length ; i++ ) { - Object obj1 = tuple[i] ; - Object obj2 = x.tuple[i] ; - if ( !Objects.equals(obj1, obj2) ) - return false ; - } - return true ; - } - - @Override - public String toString() { - return "[" + Iter.asString(iterator(), ", ") + "]" ; - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple.java new file mode 100644 index 0000000..ec818b2 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple.java @@ -0,0 +1,63 @@ +/* + * 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.jena.atlas.lib.tuple; + +import java.util.List ; +import java.util.function.Consumer ; +import java.util.stream.Stream ; + +/** A Tuple is the same class of item */ +public interface Tuple<X> extends Iterable<X> { + /** Get the i'th element, for i in the range 0 to len()-1 + * @throws IndexOutOfBoundsException for i out of range + */ + public X get(int i) ; + + /** length : elements are 0 to len()-1 */ + public int len() ; + + /** Convert to a List */ + public default List<X> asList() { + return new TupleList<>(this) ; + } + + /** stream */ + public default Stream<X> stream() { + return asList().stream() ; + } + + /** forEach */ + @Override + public default void forEach(Consumer<? super X> action) { + asList().forEach(action) ; + } + + /** Copy the Tuple into the array */ + public default void copyInto(X[] array) { + copyInto(array, 0, len()); + } + + /** Copy the Tuple into the array */ + public default void copyInto(X[] array, int start) { + copyInto(array, start, len()); + } + + /** Copy the Tuple into the array */ + public void copyInto(X[] array, int start, int length) ; +} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple0.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple0.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple0.java new file mode 100644 index 0000000..534bd50 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple0.java @@ -0,0 +1,37 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 0 items. + */ +public class Tuple0<X> extends TupleBase<X> { + + protected Tuple0() { } + + @Override + public final X get(int i) { + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 0 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple1.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple1.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple1.java new file mode 100644 index 0000000..9490732 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple1.java @@ -0,0 +1,42 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 1 item. + */ +public class Tuple1<X> extends TupleBase<X> { + protected final X x1 ; + + protected Tuple1(X x1) { + this.x1 = x1 ; + } + + @Override + public final X get(int i) { + if ( i == 0 ) + return x1 ; + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 1 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple2.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple2.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple2.java new file mode 100644 index 0000000..d90b730 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple2.java @@ -0,0 +1,46 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 2 items. + */ +public class Tuple2<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + + protected Tuple2(X x1, X x2) { + this.x1 = x1 ; + this.x2 = x2 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 2 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple3.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple3.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple3.java new file mode 100644 index 0000000..fceac41 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple3.java @@ -0,0 +1,49 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 3 items. + */ +public class Tuple3<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + + protected Tuple3(X x1, X x2, X x3) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 3 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple4.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple4.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple4.java new file mode 100644 index 0000000..04d5fe8 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple4.java @@ -0,0 +1,52 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 4 items. + */ +public class Tuple4<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + protected final X x4 ; + + protected Tuple4(X x1, X x2, X x3, X x4) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + this.x4 = x4 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + case 3: return x4 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 4 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple5.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple5.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple5.java new file mode 100644 index 0000000..5c465464 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple5.java @@ -0,0 +1,55 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 5 items. + */ +public class Tuple5<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + protected final X x4 ; + protected final X x5 ; + + protected Tuple5(X x1, X x2, X x3, X x4, X x5) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + this.x4 = x4 ; + this.x5 = x5 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + case 3: return x4 ; + case 4: return x5 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 5 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple6.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple6.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple6.java new file mode 100644 index 0000000..c3faf3a --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple6.java @@ -0,0 +1,58 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 6 items. + */ +public class Tuple6<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + protected final X x4 ; + protected final X x5 ; + protected final X x6 ; + + protected Tuple6(X x1, X x2, X x3, X x4, X x5, X x6) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + this.x4 = x4 ; + this.x5 = x5 ; + this.x6 = x6 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + case 3: return x4 ; + case 4: return x5 ; + case 5: return x6 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 6 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple7.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple7.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple7.java new file mode 100644 index 0000000..c13d60c --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple7.java @@ -0,0 +1,61 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 7 items. + */ +public class Tuple7<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + protected final X x4 ; + protected final X x5 ; + protected final X x6 ; + protected final X x7 ; + + protected Tuple7(X x1, X x2, X x3, X x4, X x5, X x6, X x7) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + this.x4 = x4 ; + this.x5 = x5 ; + this.x6 = x6 ; + this.x7 = x7 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + case 3: return x4 ; + case 4: return x5 ; + case 5: return x6 ; + case 6: return x7 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 7 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple8.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple8.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple8.java new file mode 100644 index 0000000..c233646 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/Tuple8.java @@ -0,0 +1,64 @@ +/* + * 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.jena.atlas.lib.tuple; + +/** + * A tuple of 8 items. + */ +public class Tuple8<X> extends TupleBase<X> { + protected final X x1 ; + protected final X x2 ; + protected final X x3 ; + protected final X x4 ; + protected final X x5 ; + protected final X x6 ; + protected final X x7 ; + protected final X x8 ; + + protected Tuple8(X x1, X x2, X x3, X x4, X x5, X x6, X x7, X x8) { + this.x1 = x1 ; + this.x2 = x2 ; + this.x3 = x3 ; + this.x4 = x4 ; + this.x5 = x5 ; + this.x6 = x6 ; + this.x7 = x7 ; + this.x8 = x8 ; + } + + @Override + public final X get(int i) { + switch (i) { + case 0: return x1 ; + case 1: return x2 ; + case 2: return x3 ; + case 3: return x4 ; + case 4: return x5 ; + case 5: return x6 ; + case 6: return x7 ; + case 7: return x8 ; + } + throw new IndexOutOfBoundsException() ; + } + + @Override + public final int len() { + return 8 ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleBase.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleBase.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleBase.java new file mode 100644 index 0000000..9291137 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleBase.java @@ -0,0 +1,73 @@ +/* + * 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.jena.atlas.lib.tuple; + +import java.util.Iterator ; +import java.util.Objects ; + +abstract class TupleBase<X> implements Tuple<X> { + protected TupleBase() {} + + /** Iterable */ + @Override + public Iterator<X> iterator() { + return asList().iterator() ; + } + + + @Override + public void copyInto(X[] array, int start, int length) { + for ( int i = 0 ; i < Math.min(length, len()) ; i++ ) + array[i+start] = get(i) ; + } + + @Override + public final + int hashCode() { + final int prime = 31; + int result = 1; + for ( int i = 0 ; i < len() ; i++ ) + result = prime * result + Objects.hashCode(get(i)) ; + return result; + } + + @Override + public final + boolean equals(Object obj) { + if ( this == obj ) + return true; + if ( obj == null ) + return false ; + if ( ! ( obj instanceof Tuple<?> ) ) + return false ; + Tuple<?> other = (Tuple<?>)obj ; + if ( this.len() != other.len() ) + return false ; + for ( int i = 0 ; i < this.len() ; i++ ) + if ( ! Objects.equals(this.get(i), other.get(i)) ) + return false ; + return true; + } + + @Override + public final String toString() { + return asList().toString() ; + } +} + http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleFactory.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleFactory.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleFactory.java new file mode 100644 index 0000000..04ca9c0 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleFactory.java @@ -0,0 +1,122 @@ +/* + * 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.jena.atlas.lib.tuple; + +import java.util.List ; + +/** Tuple creation */ +public class TupleFactory { + + private TupleFactory() {} + + /** Create a Tuple */ + @SafeVarargs + public static <X> Tuple<X> tuple(X...xs) { + switch(xs.length) { + case 0 : return create0() ; + case 1 : return create1(xs[0]) ; + case 2 : return create2(xs[0], xs[1]) ; + case 3 : return create3(xs[0], xs[1], xs[2]) ; + case 4 : return create4(xs[0], xs[1], xs[2], xs[3]) ; + case 5 : return create5(xs[0], xs[1], xs[2], xs[3], xs[4]) ; + case 6 : return create6(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5]) ; + case 7 : return create7(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5], xs[6]) ; + case 8 : return create8(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5], xs[6], xs[7]) ; + default: + // No need to copy. + return asTuple(xs) ; + } + } + + /** Create a Tuple from an array */ + public static <X> Tuple<X> create(X[] xs) { + switch(xs.length) { + case 0 : return create0() ; + case 1 : return create1(xs[0]) ; + case 2 : return create2(xs[0], xs[1]) ; + case 3 : return create3(xs[0], xs[1], xs[2]) ; + case 4 : return create4(xs[0], xs[1], xs[2], xs[3]) ; + case 5 : return create5(xs[0], xs[1], xs[2], xs[3], xs[4]) ; + case 6 : return create6(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5]) ; + case 7 : return create7(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5], xs[6]) ; + case 8 : return create8(xs[0], xs[1], xs[2], xs[3], xs[4], xs[5], xs[6], xs[7]) ; + default: + return TupleN.create(xs) ; + } + } + + /** Treat an array as a Tuple. The array must not be mutated */ + public static <X> Tuple<X> asTuple(X[] xs) { + return TupleN.wrap(xs) ; + } + + /** Create a Tuple from a list */ + public static <X> Tuple<X> create(List<X> xs) { + @SuppressWarnings("unchecked") + X[] xa = (X[])(new Object[xs.size()]) ; + return TupleFactory.tuple(xs.toArray(xa)) ; + } + + /** Create a Tuple of length 0 */ + public static <X> Tuple0<X> create0() { + return new Tuple0<>() ; + } + + /** Create a Tuple of length 1 */ + public static <X> Tuple1<X> create1(X x1) { + return new Tuple1<>(x1) ; + } + + /** Create a Tuple of length 2 */ + public static <X> Tuple2<X> create2(X x1, X x2) { + return new Tuple2<>(x1, x2) ; + } + + /** Create a Tuple of length 3 */ + public static <X> Tuple3<X> create3(X x1, X x2, X x3) { + return new Tuple3<>(x1, x2, x3) ; + } + + /** Create a Tuple of length 4 */ + public static <X> Tuple4<X> create4(X x1, X x2, X x3, X x4) { + return new Tuple4<>(x1, x2, x3, x4) ; + } + + /** Create a Tuple of length 5 */ + public static <X> Tuple5<X> create5(X x1, X x2, X x3, X x4, X x5) { + return new Tuple5<>(x1, x2, x3, x4, x5) ; + } + + /** Create a Tuple of length 6 */ + public static <X> Tuple6<X> create6(X x1, X x2, X x3, X x4, X x5, X x6) { + return new Tuple6<>(x1, x2, x3, x4, x5, x6) ; + } + + /** Create a Tuple of length 7 */ + public static <X> Tuple7<X> create7(X x1, X x2, X x3, X x4, X x5, X x6, X x7) { + return new Tuple7<>(x1, x2, x3, x4, x5, x6, x7) ; + } + + /** Create a Tuple of length 8 */ + public static <X> Tuple8<X> create8(X x1, X x2, X x3, X x4, X x5, X x6, X x7, X x8) { + return new Tuple8<>(x1, x2, x3, x4, x5, x6, x7, x8) ; + } + + +} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleList.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleList.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleList.java new file mode 100644 index 0000000..9e166cd --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleList.java @@ -0,0 +1,43 @@ +/* + * 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.jena.atlas.lib.tuple; + +import java.util.AbstractList ; +import java.util.List ; +import java.util.RandomAccess ; + +/** Wrap a {@link Tuple} as an immutable Java collection {@link List} */ +public class TupleList<X> extends AbstractList<X> implements RandomAccess { + + private final Tuple<X> tuple; + + public TupleList(Tuple<X> tuple) { + this.tuple = tuple ; + } + + @Override + public X get(int index) { + return tuple.get(index) ; + } + + @Override + public int size() { + return tuple.len() ; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleMap.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleMap.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleMap.java new file mode 100644 index 0000000..2a220ed --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleMap.java @@ -0,0 +1,404 @@ +/* + * 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.jena.atlas.lib.tuple; + +import static java.lang.String.format; + +import java.util.ArrayList ; +import java.util.Arrays; +import java.util.Collections ; +import java.util.List; + +import org.apache.jena.atlas.AtlasException; +import org.apache.jena.atlas.lib.ListUtils ; +import org.apache.jena.atlas.lib.StrUtils ; + +/** + * General descriptor of a reordering (mapping) of slots in tuples + * <p> + * Naming: map is convert to the reordered form, unmap is get back. + * <p> + * + * <pre> + * map(tuple) is equivalent to + * create tuple(getSlotIdx(0) , getSlotIdx(1), ... getSlotIdx(n-1)) ; + * </pre> + * + * A {@code TupleMap} holds twp maps: the "getTransform" and the "putTransform". + * The "getTransform" is here to get the item from in the mapper Tuple. + * In the case is {@code SPO->POS} this is + * {@code 0<-1, 1<-2, 2<-0} + * and the "putTransform" is where to place the items: {@code 0->2, 1->0, 2->1}. + */ +final +public class TupleMap { + /* + * Naming. getTransform (from src), putTransform(into dst) + * And these are mutual inverses: unmap process is to swap use of getTransform and putTransform + * See getSlotIdx and putSlotIdx + * + * These are then equivalent + * + * int j = getTransform[i] ; elts[i] = src.get(j) ; + * int j = putTransform[i] ; elts[j] = src.get(i) ; + * + * The code tends to use this style (getTransform) + * int j = getTransform[i] ; + * dst[i] = src[j] ; + * + * See apply and applyArray + * + * Warning : map and unmap here do not correspond to fetch and map in + * ColumnMap. That has confusing/inconsistent usage. + */ + + // SPO->POS: get:{0<-1, 1<-2, 2<-0} put:{0->2, 1->0, 2->1} + + // Map by where to fetch from source. + // For SPO -> POS, get from 1 to go into 0 so (0->, 1->0 2-> + // POS->SPO, is (0->1, 1->2, 2->0) + // i.e. the location to fetch the mapped element from. + private final int[] getTransform ; + + // Map by insertion into destination. + // So SPO->POS is (0->2, 1->0, 2->1) + // i.e. the location of the element after mapping. + private final int[] putTransform ; // putTransform, insertOrder + + private final int len ; + private final String label; + + /** + * Construct a mapping that maps the input (one col, one char) to the output + */ + public static TupleMap create(String input, String output) { + return new TupleMap(input + "->" + output, compileMapping(input, output)); + } + + /** + * Construct a mapping, with label, that maps the input (one col, one char) to the output + */ + public static TupleMap create(String label, String input, String output) { + return new TupleMap(label, compileMapping(input, output)); + } + + /** + * Construct a mapping that maps the input to the output + */ + public static <T> TupleMap create(String label, List<T> input, List<T> output) { + return new TupleMap(label, compileMapping(input, output)); + } + + /** + * Construct a mapping that maps the input to the output + */ + public static <T> TupleMap create(String label, T[] input, T[] output) { + return new TupleMap(label, compileMapping(input, output)); + } + + /** + * Construct a mapping - the elements are the mappings of a tuple + * originally in the order 0,1,2,... so SPO->POS is 2,0,1 (SPO->POS so S->2, + * P->0, O->1) and not 1,2,0 (which is the extraction mapping). The label is + * just a label and is not interpretted here. + */ + private TupleMap(String label, int... elements) { + this.len = elements.length ; + this.label = label; + + this.putTransform = new int[elements.length]; + Arrays.fill(putTransform, -1); + + this.getTransform = new int[elements.length]; + Arrays.fill(getTransform, -1); + + for ( int i = 0 ; i < elements.length ; i++ ) { + int x = elements[i]; + if ( x < 0 || x >= elements.length ) + throw new IllegalArgumentException("Out of range: " + x); + // Checking + if ( putTransform[i] != -1 || getTransform[x] != -1 ) + throw new IllegalArgumentException("Inconsistent: " + ListUtils.str(elements)); + + putTransform[i] = x; // The elements are the putTransform. + getTransform[x] = i; + } + } + + /** Length of mapping */ + public int length() { + return len; + } + + /** + * Get the index of the i'th slot as it appears from a mapping : for + * SPO->POS : 0'th slot is P so 0 returns 1 (the location in the tuple before mapping) + * The 0'th mapped slot is {@code tuple.get(tupleMap.getSlotIdx(0))}. + */ + public int getSlotIdx(int idx) { + return getTransform[idx]; + } + + /** + * Get the index of the i'th slot as it appears after unmapping : SPO->POS : + * 0'th slot is S from POS so 0 returns 2 + */ + public int putSlotIdx(int idx) { + return putTransform[idx]; + } + + /** + * Get the index of the i'th slot as it appears from a mapping : for + * SPO->POS : 0'th slot is P so 0 returns 1 (the location in the tuple before mapping) + * Equivalent to {@link #getSlotIdx}. + * The 0'th mapped slot is {@code tuple.get(tupleMap.mapIdx(0))}. + */ + public int mapIdx(int idx) { + return getSlotIdx(idx) ; + } + + /** + * Get the index of the i'th slot as it appears after unmapping : SPO->POS : + * 0'th slot is S from POS so 0 returns 2 + * Equivalent to {@link #putSlotIdx}. + * The 0'th unmapped slot is {@code tuple.get(tupleMap.unmapIdx(0))}. + */ + public int unmapIdx(int idx) { + return putSlotIdx(idx) ; + } + + /** Apply to an <em>unmapped</em> tuple to get a tuple with the tuple mapping applied. + */ + public <T> Tuple<T> map(Tuple<T> src) { + return apply(src, getTransform) ; + } + + /** Apply to a <em>mapped</em> tuple to get a tuple with the tuple mapping reverse-applied. */ + public <T> Tuple<T> unmap(Tuple<T> src) { + return apply(src, putTransform) ; + } + + // Does not work (java8) - assigning the return causes a runtime case exception +// /** Apply to an <em>unmapped</em> tuple to get a tuple with the tuple mapping applied */ +// public <T> T[] map(T[] src) { +// @SuppressWarnings("unchecked") +// T[]dst = (T[])new Object[src.length] ; +// applyArray(src, dst, getTransform) ; +// return dst ; +// } + + /** Apply to an <em>unmapped</em> tuple to get a tuple with the tuple mapping applied. + * Returns the destination array. + */ + public <T> T[] map(T[] src, T[] dst) { + if ( src == dst ) + throw new IllegalArgumentException("Source and destination are the same array") ; + applyArray(src, dst, getTransform) ; + return dst ; + } + + // Does not work (java8) - assigning the return causes a runtime case exception +// /** Apply to a <em>mapped</em> tuple to get a tuple with the tuple mapping reverse-applied */ +// public <T> T[] unmap(T[] src) { +// @SuppressWarnings("unchecked") +// T[]dst = (T[])new Object[src.length] ; +// applyArray(src, dst, putTransform) ; +// return dst ; +// } + + /** Apply to a <em>mapped</em> tuple to get a tuple with the tuple mapping reverse-applied. + * Returns the destination array. + */ + public <T> T[] unmap(T[] src, T[] dst) { + if ( src == dst ) + throw new IllegalArgumentException("Source and destination are the same array") ; + applyArray(src, dst, putTransform) ; + return dst ; + } + + /** Apply an index transformation + */ + private static <T> Tuple<T> apply(Tuple<T> src, int[] getTransform) { + if ( src.len() != getTransform.length ) + throw new IllegalArgumentException("Lengths do not match: Tuple:"+src.len()+"; transform:"+getTransform.length) ; + // Fast-track 1,2,3,4 ? +// // All this to avoid the temp array. +// switch(src.len()) { +// case 0: return src ; +// case 1: return src ; +// case 2: { +// T x1 = src.get(getTransform[0]); +// T x2 = src.get(getTransform[1]); +// return TupleFactory.create2(x1, x2) ; +// } +// case 3: { +// T x1 = src.get(getTransform[0]); +// T x2 = src.get(getTransform[1]); +// T x3 = src.get(getTransform[2]); +// return TupleFactory.create3(x1, x2, x3) ; +// } +// case 4: { +// T x1 = src.get(getTransform[0]); +// T x2 = src.get(getTransform[1]); +// T x3 = src.get(getTransform[2]); +// T x4 = src.get(getTransform[3]); +// return TupleFactory.create4(x1, x2, x3, x4) ; +// } +// } + + @SuppressWarnings("unchecked") + T[] elts = (T[])new Object[src.len()] ; + + for ( int i = 0 ; i < src.len() ; i++ ) { + int j = getTransform[i] ; + elts[i] = src.get(j) ; + } + return TupleFactory.tuple(elts) ; + } + + /** Apply an index transformation */ + private <T> void applyArray(T[] src, T[] dst, int[] transform) { + for ( int i = 0 ; i < src.length ; i++ ) { + int j = transform[i] ; + dst[i] = src[j] ; + } + } + + /** + * Apply to an <em>unmapped</em> tuple to get the i'th slot after mapping : + * SPO->POS : 0'th slot is P from SPO + */ + public <T> T mapSlot(int idx, Tuple<T> tuple) { + checkLength(tuple) ; + idx = getSlotIdx(idx) ; + return tuple.get(idx) ; + } + + /** + * Apply to a <em>mapped</em> tuple to get the i'th slot as it appears after + * mapping : SPO->POS : 0'th slot is S from POS + */ + public <T> T unmapSlot(int idx, Tuple<T> tuple) { + checkLength(tuple) ; + idx = putSlotIdx(idx) ; + return tuple.get(idx); + } + + /** + * Apply to an <em>unmapped</em> tuple to get the i'th slot after mapping : + * SPO->POS : 0'th slot is P from SPO + */ + public <T> T mapSlot(int idx, T[] tuple) { + return tuple[getSlotIdx(idx)] ; + } + + /** + * Apply to a <em>mapped</em> tuple to get the i'th slot as it appears after + * mapping : SPO->POS : 0'th slot is S from POS + */ + public <T> T unmapSlot(int idx, T[] tuple) { + return tuple[putSlotIdx(idx)] ; + } + + /** Compile a mapping encoded as single charcaters e.g. "SPO", "POS" */ + private static int[] compileMapping(String domain, String range) { + List<Character> input = StrUtils.toCharList(domain); + List<Character> output = StrUtils.toCharList(range); + return compileMapping(input, output); + } + + /** + * Compile a mapping, encoded two list, the domain and range of the mapping + * function + */ + private static <T> int[] compileMapping(T[] domain, T[] range) { + return compileMapping(Arrays.asList(domain), Arrays.asList(range)); + } + + /** Compile a mapping */ + private static <T> int[] compileMapping(List<T> domain, List<T> range) { + if ( domain.size() != range.size() ) + throw new AtlasException("Bad mapping: lengths not the same: " + domain + " -> " + range); + + int[] cols = new int[domain.size()]; + boolean[] mapped = new boolean[domain.size()]; + // Arrays.fill(mapped, false) ; + + for ( int i = 0 ; i < domain.size() ; i++ ) { + T input = domain.get(i); + int j = range.indexOf(input); + if ( j < 0 ) + throw new AtlasException("Bad mapping: missing mapping: " + domain + " -> " + range); + if ( mapped[j] ) + throw new AtlasException("Bad mapping: duplicate: " + domain + " -> " + range); + cols[i] = j; + mapped[j] = true; + } + return cols; + } + + /** Access to the getTransform */ + /*package-testing*/ List<Integer> transformGet() { + return arrayToList(getTransform) ; + } + + /** Access to the putTransform */ + /*package-testing*/ List<Integer> transformPut() { + return arrayToList(putTransform) ; + } + + private List<Integer> arrayToList(int[] array) { + List<Integer> list = new ArrayList<>(array.length) ; + for ( int x : array ) + list.add(x) ; + return Collections.unmodifiableList(list) ; + } + + @Override + public String toString() { + // return label ; + return format("%s:%s:%s", label, mapStr(putTransform, "->"), mapStr(getTransform, "<-")); + } + + private Object mapStr(int[] map, String arrow) { + StringBuilder buff = new StringBuilder(); + String sep = "{"; + + for ( int i = 0 ; i < map.length ; i++ ) { + buff.append(sep); + sep = ", "; + buff.append(format("%d%s%d", i, arrow, map[i])); + } + buff.append("}"); + + return buff.toString(); + } + + public String getLabel() { + return label; + } + + private static boolean CHECKING = true ; + private final void checkLength(Tuple<?> tuple) { + if ( CHECKING ) { + if ( tuple.len() != length() ) + throw new IllegalArgumentException("Tuple length "+tuple.len()+": not of length "+length()) ; + } + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleN.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleN.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleN.java new file mode 100644 index 0000000..58e455e --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/TupleN.java @@ -0,0 +1,55 @@ +/* + * 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.jena.atlas.lib.tuple; + +import java.util.Arrays ; + +/** A Tuple of N items */ +public class TupleN<X> extends TupleBase<X> { + private final X[] tuple ; + + /** Create a TupleN - safely copy the input */ + @SafeVarargs + public static <X> TupleN<X> create(X... xs) { + X[] xs2 = Arrays.copyOf(xs, xs.length) ; + return new TupleN<>(xs2) ; + } + + // When the array will not be modified. + /*package*/ static <X> TupleN<X> wrap(X[] xs) { + return new TupleN<>(xs) ; + } + + /** Put a TupleN wrapper around a X[]. + * The statics {@link #create} and {@link wrap} determine whether to copy or not. + */ + private TupleN(X[] xs) { + tuple = xs ; + } + + @Override + public final X get(int i) { + return tuple[i] ; + } + + @Override + public int len() { + return tuple.length; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/package-info.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/package-info.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/package-info.java new file mode 100644 index 0000000..4028b2d --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/tuple/package-info.java @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/** + * Tuples. + * <p> + * A Tuple is a fixed length sequence of the objects of the same type. They are + * immutable and provide value-based {@code hashCode} and {@code .equals()}. + * <p> + * There are space-saving implementations for tuples of length 0 to small N and + * a general purpose implementation. + * <ul> + * <li>{@code Tuple} -- the interface + * <li>{@code TupleFactory} -- creates {@code Tuples} + * <li>{@code TupleMap} -- provides transformations of order of elements + * </ul> + */ + +package org.apache.jena.atlas.lib.tuple; http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/test/java/org/apache/jena/atlas/TC_Atlas.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/TC_Atlas.java b/jena-base/src/test/java/org/apache/jena/atlas/TC_Atlas.java index cbe2b33..1f3ddc5 100644 --- a/jena-base/src/test/java/org/apache/jena/atlas/TC_Atlas.java +++ b/jena-base/src/test/java/org/apache/jena/atlas/TC_Atlas.java @@ -22,6 +22,7 @@ import org.apache.jena.atlas.io.TS_IO ; import org.apache.jena.atlas.iterator.TS_Iterator ; import org.apache.jena.atlas.lib.TS_Lib ; import org.apache.jena.atlas.lib.persistent.TS_Persistent; +import org.apache.jena.atlas.lib.tuple.TS_Tuple ; import org.junit.runner.RunWith ; import org.junit.runners.Suite ; @@ -29,6 +30,7 @@ import org.junit.runners.Suite ; @Suite.SuiteClasses( { // Library TS_Lib.class + , TS_Tuple.class , TS_Iterator.class , TS_IO.class , TS_Persistent.class http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java index 92538f7..272d169 100644 --- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java @@ -20,7 +20,7 @@ package org.apache.jena.atlas.lib; import org.apache.jena.atlas.junit.BaseTest ; import org.apache.jena.atlas.lib.FileOps ; -import org.apache.jena.atlas.lib.Tuple ; +import org.apache.jena.atlas.lib.tuple.Tuple ; import org.junit.Test ; public class TestFileOps extends BaseTest http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TS_Tuple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TS_Tuple.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TS_Tuple.java new file mode 100644 index 0000000..30ba125 --- /dev/null +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TS_Tuple.java @@ -0,0 +1,32 @@ +/* + * 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.jena.atlas.lib.tuple; + +import org.junit.runner.RunWith ; +import org.junit.runners.Suite ; + +@RunWith(Suite.class) [email protected]( { + TestTuple.class + , TestTupleMap.class +}) + +public class TS_Tuple { +} + http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTuple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTuple.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTuple.java new file mode 100644 index 0000000..4c31746 --- /dev/null +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTuple.java @@ -0,0 +1,201 @@ +/* + * 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.jena.atlas.lib.tuple; + +import static org.junit.Assert.assertEquals ; +import static org.junit.Assert.assertNotEquals ; +import static org.junit.Assert.fail ; + +import java.util.ArrayList ; +import java.util.List ; + +import org.junit.Test ; + +public class TestTuple { + @Test public void tuple_0() { + Tuple<Integer> tuple = TupleFactory.create0() ; + assertEquals(0, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_1() { + Tuple<Integer> tuple = TupleFactory.create1(9) ; + assertEquals(1, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_2() { + Tuple<Integer> tuple = TupleFactory.create2(9,8) ; + assertEquals(2, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_3() { + Tuple<Integer> tuple = TupleFactory.create3(9,8,7) ; + assertEquals(3, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_4() { + Tuple<Integer> tuple = TupleFactory.create4(9,8,7,6) ; + assertEquals(4, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_5() { + Tuple<Integer> tuple = TupleFactory.create5(9,8,7,6,5) ; + assertEquals(5, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_6() { + Tuple<Integer> tuple = TupleFactory.create6(9,8,7,6,5,4) ; + assertEquals(6, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_7() { + Tuple<Integer> tuple = TupleFactory.create7(9,8,7,6,5,4,3) ; + assertEquals(7, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_8() { + Tuple<Integer> tuple = TupleFactory.create8(9,8,7,6,5,4,3,2) ; + assertEquals(8, tuple.len()) ; + check(tuple) ; + } + + @Test public void tuple_N0() { + Tuple<Integer> tuple = TupleFactory.tuple() ; + assertEquals(0, tuple.len()) ; + assertEquals(Tuple0.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N1() { + Tuple<Integer> tuple = TupleFactory.tuple(9) ; + assertEquals(1, tuple.len()) ; + assertEquals(Tuple1.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N2() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8) ; + assertEquals(2, tuple.len()) ; + assertEquals(Tuple2.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N3() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7) ; + assertEquals(3, tuple.len()) ; + assertEquals(Tuple3.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N4() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6) ; + assertEquals(4, tuple.len()) ; + assertEquals(Tuple4.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N5() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6,5) ; + assertEquals(5, tuple.len()) ; + assertEquals(Tuple5.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N6() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6,5,4) ; + assertEquals(6, tuple.len()) ; + assertEquals(Tuple6.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N7() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6,5,4,3) ; + assertEquals(7, tuple.len()) ; + assertEquals(Tuple7.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N8() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6,5,4,3,2) ; + assertEquals(8, tuple.len()) ; + assertEquals(Tuple8.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_N() { + Tuple<Integer> tuple = TupleFactory.tuple(9,8,7,6,5,4,3,2,1,0) ; + assertEquals(10, tuple.len()) ; + assertEquals(TupleN.class, tuple.getClass()) ; + check(tuple) ; + } + + @Test public void tuple_equals_1() { + Tuple<Integer> tuple1 = TupleFactory.tuple(9,8,7) ; + Tuple<Integer> tuple2 = TupleN.create(9,8,7) ; + assertEquals(tuple1.hashCode(), tuple2.hashCode()) ; + assertEquals(tuple1, tuple2) ; + } + + @Test public void tuple_not_equals_1() { + Tuple<Integer> tuple1 = TupleFactory.tuple(9,8,7) ; + Tuple<Integer> tuple2 = TupleFactory.tuple(7,8,9) ; + assertNotEquals(tuple1.hashCode(), tuple2.hashCode()) ; + assertNotEquals(tuple1, tuple2) ; + } + + @Test public void tuple_not_equals_2() { + Tuple<Integer> tuple1 = TupleFactory.tuple(9,8,7) ; + Tuple<Integer> tuple2 = TupleFactory.tuple(9,8) ; + assertNotEquals(tuple1.hashCode(), tuple2.hashCode()) ; + assertNotEquals(tuple1, tuple2) ; + } + + private void check(Tuple<Integer> tuple) { + int val = 9 ; + for ( int i = 0 ; i < tuple.len() ; i++ ) { + assertEquals(val-i, tuple.get(i).intValue()) ; + } + List<Integer> list = tuple.asList() ; + for ( int i = 0 ; i < tuple.len() ; i++ ) { + assertEquals(val-i, list.get(i).intValue()) ; + } + try { tuple.get(-1) ; fail("Index -1 did not throw an exception") ; } + catch(IndexOutOfBoundsException ex) {} + try { tuple.get(tuple.len()) ; fail("Index len() did not throw an exception") ; } + catch(IndexOutOfBoundsException ex) {} + + // Other constructors + List<Integer> list2 = new ArrayList<>(list) ; + Tuple<Integer> tuple2 = TupleFactory.create(list2) ; + assertEquals(tuple.hashCode(), tuple2.hashCode()) ; + assertEquals(tuple, tuple2) ; + + // Other constructors + List<Integer> list3 = new ArrayList<>(list) ; + Tuple<Integer> tuple3 = TupleFactory.tuple(list3.toArray(new Integer[0])) ; + assertEquals(tuple, tuple3) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/571e9755/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTupleMap.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTupleMap.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTupleMap.java new file mode 100644 index 0000000..75e1a05 --- /dev/null +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/tuple/TestTupleMap.java @@ -0,0 +1,186 @@ +/* + * 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.jena.atlas.lib.tuple; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays ; +import java.util.List ; + +import org.apache.jena.atlas.lib.tuple.Tuple ; +import org.apache.jena.atlas.lib.tuple.TupleFactory ; +import org.apache.jena.atlas.lib.tuple.TupleMap ; +import org.junit.Test; + +public class TestTupleMap { + // Check coverage + + @Test + public void map_tuple_01() { + TupleMap tmap = TupleMap.create("SPO", "POS"); + Tuple<String> tuple = TupleFactory.tuple("S", "P", "O"); + Tuple<String> tuple2 = tmap.map(tuple); + assertEquals(tuple2.get(0), "P"); + assertEquals(tuple2.get(1), "O"); + assertEquals(tuple2.get(2), "S"); + + Tuple<String> tuple3 = tmap.unmap(tuple2); + assertEquals(tuple, tuple3); + } + + + @Test + public void map_tuple_02() { + TupleMap x = TupleMap.create("SPO", "POS"); + Tuple<String> tuple = TupleFactory.tuple("S", "P", "O"); + Tuple<String> mapped = x.map(tuple); + Tuple<String> expected = TupleFactory.tuple("P", "O", "S"); + assertEquals(expected, mapped); + } + + @Test + public void map_tuple_03() { + TupleMap tmap = TupleMap.create("GSPO", "OSPG"); + Tuple<String> tuple = TupleFactory.tuple("G", "S", "P", "O"); + Tuple<String> mapped = tmap.map(tuple); + Tuple<String> expected = TupleFactory.tuple("O", "S", "P", "G"); + assertEquals(expected, mapped); + Tuple<String> unmapped = tmap.unmap(mapped); + assertEquals(TupleFactory.tuple("G", "S", "P", "O"), unmapped); + } + + @Test + public void map_tuple_04() { + String[] x = {"G", "S", "P", "O"}; + String[] y = {"O", "S", "P", "G"}; + + TupleMap tmap = TupleMap.create("Test", x, y); + Tuple<String> tuple = TupleFactory.tuple(x); + Tuple<String> mapped = tmap.map(tuple); + + Tuple<String> expected = TupleFactory.tuple(y); + assertEquals(expected, mapped); + Tuple<String> unmapped = tmap.unmap(mapped); + assertEquals(TupleFactory.tuple(x), unmapped); + } + + @Test + public void compile1() { + TupleMap map = TupleMap.create("SPO", "POS"); + // SPO -> POS + // col 0 goes to col 2 + // col 1 goes to col 0 + // col 2 goes to col 1 + Integer[] expectedPut = {2, 0, 1}; + assertEquals(Arrays.asList(expectedPut), map.transformPut()); + Integer[] expectedGet = {1, 2, 0}; + assertEquals(Arrays.asList(expectedGet), map.transformGet()); + } + + @Test + public void compile2() { + TupleMap map = TupleMap.create("SPOG", "GOPS"); + Integer[] expected = {3, 2, 1, 0}; + assertEquals(Arrays.asList(expected), map.transformPut()); + } + + @Test + public void map_slot_01() { + TupleMap tmap = TupleMap.create("SPO", "POS"); + Tuple<String> tuple = TupleFactory.tuple("S", "P", "O"); + assertEquals("P", tmap.mapSlot(0, tuple)); + assertEquals("O", tmap.mapSlot(1, tuple)); + assertEquals("S", tmap.mapSlot(2, tuple)); + + Tuple<String> tuple1 = tmap.map(tuple); + assertEquals("S", tmap.unmapSlot(0, tuple1)); + assertEquals("P", tmap.unmapSlot(1, tuple1)); + assertEquals("O", tmap.unmapSlot(2, tuple1)); + } + + @Test + public void map_slot_02() { + TupleMap tmap = TupleMap.create("SPO", "POS"); + Tuple<String> tuple = TupleFactory.tuple("S", "P", "O"); + Tuple<String> tuple1 = TupleFactory.tuple + (tuple.get(tmap.mapIdx(0)) + ,tuple.get(tmap.mapIdx(1)) + ,tuple.get(tmap.mapIdx(2)) ) ; + Tuple<String> tuple2 = tmap.map(tuple); + assertEquals(tuple2, tuple1) ; + } + + @Test + public void map_slot_03() { + TupleMap tmap = TupleMap.create("POS", "SPO"); + Tuple<String> tuple = TupleFactory.tuple("P", "O", "S"); + Tuple<String> tuple1 = TupleFactory.tuple + (tuple.get(tmap.unmapIdx(0)) + ,tuple.get(tmap.unmapIdx(1)) + ,tuple.get(tmap.unmapIdx(2)) ) ; + Tuple<String> tuple2 = tmap.unmap(tuple); + assertEquals(tuple2, tuple1) ; + } + + @Test + public void map_transforms() { + TupleMap x = TupleMap.create("SPO","POS"); + List<Integer> listGet = x.transformPut() ; + List<Integer> listGetExpected = Arrays.asList(2, 0, 1) ; + assertEquals(listGetExpected, listGet) ; + + List<Integer> listPut = x.transformGet() ; + List<Integer> listPutExpected = Arrays.asList(1, 2, 0) ; + assertEquals(listGetExpected, listGet) ; + + } + + @Test + public void map_array_01() { + TupleMap x = TupleMap.create("SPO","POS"); + Tuple<Integer> t = TupleFactory.tuple(2, 0, 1); + Tuple<Integer> t1 = x.map(t); + + String[] array = {"X", "Y", "Z"}; + + assertEquals("Y", x.mapSlot(0, array)); // The 0th item after mapping is the "1" + assertEquals("Z", x.mapSlot(1, array)); + assertEquals("X", x.mapSlot(2, array)); + + String[] array2 = new String[array.length] ; + x.map(array, array2) ; + assertArrayEquals(new String[] {"Y", "Z", "X"}, array2) ; + String[] array3 = new String[array.length] ; + x.unmap(array2, array3) ; + + assertArrayEquals(array, array3) ; + } + + @Test + public void map_array_02() { + // (0,1,2) -> (2,0,1) S->2 etc + // so (0,1,2) <- (1,2,0) + TupleMap x = TupleMap.create("SPO","POS"); + String[] array = {"Y", "Z", "X"}; + assertEquals("X", x.unmapSlot(0, array)); // The index 0 comes from position 3. + assertEquals("Y", x.unmapSlot(1, array)); + assertEquals("Z", x.unmapSlot(2, array)); + } +}
