001/* 002 * Copyright (c) 2016-2017 Chris K Wensel. All Rights Reserved. 003 * 004 * Project and contact information: http://www.cascading.org/ 005 * 006 * This file is part of the Cascading project. 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020 021package cascading.tuple; 022 023import java.io.IOException; 024import java.io.UncheckedIOException; 025import java.util.Objects; 026import java.util.function.Function; 027import java.util.function.Supplier; 028import java.util.function.ToDoubleFunction; 029import java.util.function.ToIntFunction; 030import java.util.function.ToLongFunction; 031import java.util.stream.DoubleStream; 032import java.util.stream.IntStream; 033import java.util.stream.LongStream; 034import java.util.stream.Stream; 035 036import cascading.flow.FlowProcess; 037import cascading.tap.Tap; 038 039/** 040 * TupleStream provides helper methods to create {@link Tuple} {@link Stream} instances from {@link Tap} instances. 041 * <p> 042 * This class is a convenience class over the methods provided on the Tap class that provide the same 043 * functionality. This class exists to help overcome any generics compiler warnings. 044 * <p> 045 * Note, the returned Stream instance must be closed in order to clean up underlying resources. This 046 * is simply accomplished with a try-with-resources statement. 047 */ 048public class TupleStream 049 { 050 /** 051 * Method tupleStream returns a {@link Stream} of {@link Tuple} instances from the given 052 * {@link Tap} instance. 053 * <p> 054 * Also see {@link Tap#tupleStream(FlowProcess)}. 055 * <p> 056 * Note, the returned Stream instance must be closed in order to clean up underlying resources. This 057 * is simply accomplished with a try-with-resources statement. 058 * 059 * @param tap the Tap to open 060 * @param flowProcess represents the current platform configuration 061 * @return a Stream of Tuple instances 062 */ 063 @SuppressWarnings("unchecked") 064 public static Stream<Tuple> tupleStream( Tap tap, FlowProcess flowProcess ) 065 { 066 Objects.requireNonNull( tap ); 067 068 return tap.tupleStream( flowProcess ); 069 } 070 071 /** 072 * Method tupleStreamCopy returns a {@link Stream} of {@link Tuple} instances from the given 073 * {@link Tap} instance. 074 * <p> 075 * This method returns an Tuple instance suitable for caching. 076 * <p> 077 * Also see {@link Tap#tupleStreamCopy(FlowProcess)}. 078 * <p> 079 * Note, the returned Stream instance must be closed in order to clean up underlying resources. This 080 * is simply accomplished with a try-with-resources statement. 081 * 082 * @param tap the Tap to open 083 * @param flowProcess represents the current platform configuration 084 * @return a Stream of TupleEntry instances 085 */ 086 @SuppressWarnings("unchecked") 087 public static Stream<Tuple> tupleStreamCopy( Tap tap, FlowProcess flowProcess ) 088 { 089 Objects.requireNonNull( tap ); 090 091 return tap.tupleStreamCopy( flowProcess ); 092 } 093 094 /** 095 * Method tupleStream returns a {@link Stream} of {@link Tuple} instances from the given 096 * {@link Tap} instance. 097 * <p> 098 * Also see {@link Tap#tupleStream(FlowProcess)}. 099 * <p> 100 * Note, the returned Stream instance must be closed in order to clean up underlying resources. This 101 * is simply accomplished with a try-with-resources statement. 102 * 103 * @param tap the Tap to open 104 * @param flowProcess represents the current platform configuration 105 * @param selector the fields to select from the underlying Tuple 106 * @return a Stream of TupleE instances 107 */ 108 @SuppressWarnings("unchecked") 109 public static Stream<Tuple> tupleStream( Tap tap, FlowProcess flowProcess, Fields selector ) 110 { 111 Objects.requireNonNull( tap ); 112 Objects.requireNonNull( selector ); 113 114 return tap.tupleStream( flowProcess, selector ); 115 } 116 117 /** 118 * Method tupleStreamCopy returns a {@link Stream} of {@link Tuple} instances from the given 119 * {@link Tap} instance. 120 * <p> 121 * This method returns an Tuple instance suitable for caching. 122 * <p> 123 * Also see {@link Tap#tupleStreamCopy(FlowProcess)}. 124 * <p> 125 * Note, the returned Stream instance must be closed in order to clean up underlying resources. This 126 * is simply accomplished with a try-with-resources statement. 127 * 128 * @param tap the Tap to open 129 * @param flowProcess represents the current platform configuration 130 * @param selector the fields to select from the underlying Tuple 131 * @return a Stream of Tuple instances 132 */ 133 @SuppressWarnings("unchecked") 134 public static Stream<Tuple> tupleStreamCopy( Tap tap, FlowProcess flowProcess, Fields selector ) 135 { 136 Objects.requireNonNull( tap ); 137 Objects.requireNonNull( selector ); 138 139 return tap.tupleStreamCopy( flowProcess, selector ); 140 } 141 142 /** 143 * Method posToObject returns the object at the given tuple position. 144 * 145 * @param pos the ordinal position to select from 146 * @param <R> the object type 147 * @return the value in the given ordinal position 148 */ 149 @SuppressWarnings("unchecked") 150 public static <R> Function<Tuple, ? extends R> posToObject( int pos ) 151 { 152 return value -> (R) value.getObject( pos ); 153 } 154 155 /** 156 * Method posToInt returns the int value at the given tuple position. 157 * 158 * @param pos the ordinal position to select from 159 * @return the value in the given ordinal position 160 */ 161 public static ToIntFunction<Tuple> posToInt( int pos ) 162 { 163 return value -> value.getInteger( pos ); 164 } 165 166 /** 167 * Method posToLong returns the long value at the given tuple position. 168 * 169 * @param pos the ordinal position to select from 170 * @return the value in the given ordinal position 171 */ 172 public static ToLongFunction<Tuple> posToLong( int pos ) 173 { 174 return value -> value.getLong( pos ); 175 } 176 177 /** 178 * Method posToDouble returns the double value at the given tuple position. 179 * 180 * @param pos the ordinal position to select from 181 * @return the value in the given ordinal position 182 */ 183 public static ToDoubleFunction<Tuple> posToDouble( int pos ) 184 { 185 return value -> value.getDouble( pos ); 186 } 187 188 /** 189 * Method writeTuple will add each {@link Tuple} instance to the {@link TupleEntryCollector} provided 190 * by the given {@link Tap} instance. 191 * 192 * @param stream a Stream of Tuple instances 193 * @param into a Supplier that returns the Tap to sink each entry into 194 * @param flowProcess represents the current platform configuration 195 * @return returns the given Tap 196 */ 197 public static Tap writeTuple( Stream<Tuple> stream, Supplier<Tap> into, FlowProcess flowProcess ) 198 { 199 return writeTuple( stream, into.get(), flowProcess ); 200 } 201 202 /** 203 * Method writeTuple will add each {@link Tuple} instance to the {@link TupleEntryCollector} provided 204 * by the given {@link Tap} instance. 205 * 206 * @param stream a Stream of Tuple instances 207 * @param into the Tap to sink each entry into 208 * @param flowProcess represents the current platform configuration 209 * @return returns the given Tap 210 */ 211 @SuppressWarnings("unchecked") 212 public static Tap writeTuple( Stream<Tuple> stream, Tap into, FlowProcess flowProcess ) 213 { 214 Objects.requireNonNull( into ); 215 Objects.requireNonNull( stream ); 216 217 try 218 { 219 TupleEntryCollector collector = into.openForWrite( flowProcess ); 220 221 stream.forEach( collector::add ); 222 223 collector.close(); 224 } 225 catch( IOException exception ) 226 { 227 throw new UncheckedIOException( exception ); 228 } 229 230 return into; 231 } 232 233 /** 234 * Method writeInt will add each {@code int} instance to the {@link TupleEntryCollector} provided 235 * by the given {@link Tap} instance. 236 * 237 * @param stream a Stream of int values 238 * @param into a Supplier that returns the Tap to sink each value into 239 * @param flowProcess represents the current platform configuration 240 * @return returns the given Tap 241 */ 242 public static Tap writeInt( IntStream stream, Supplier<Tap> into, FlowProcess flowProcess ) 243 { 244 return writeInt( stream, into.get(), flowProcess ); 245 } 246 247 /** 248 * Method writeInt will add each {@code int} instance to the {@link TupleEntryCollector} provided 249 * by the given {@link Tap} instance. 250 * 251 * @param stream a Stream of int values 252 * @param into the Tap to sink each value into 253 * @param flowProcess represents the current platform configuration 254 * @return returns the given Tap 255 */ 256 @SuppressWarnings("unchecked") 257 public static Tap writeInt( IntStream stream, Tap into, FlowProcess flowProcess ) 258 { 259 Objects.requireNonNull( into ); 260 Objects.requireNonNull( stream ); 261 262 Tuple tuple = Tuple.size( 1 ); 263 264 try 265 { 266 TupleEntryCollector collector = into.openForWrite( flowProcess ); 267 268 stream.forEach( i -> collector.add( reset( tuple, i ) ) ); 269 270 collector.close(); 271 } 272 catch( IOException exception ) 273 { 274 throw new UncheckedIOException( exception ); 275 } 276 277 return into; 278 } 279 280 /** 281 * Method writeLong will add each {@code long} instance to the {@link TupleEntryCollector} provided 282 * by the given {@link Tap} instance. 283 * 284 * @param stream a Stream of long values 285 * @param into a Supplier that returns the Tap to sink each value into 286 * @param flowProcess represents the current platform configuration 287 * @return returns the given Tap 288 */ 289 public static Tap writeLong( LongStream stream, Supplier<Tap> into, FlowProcess flowProcess ) 290 { 291 return writeLong( stream, into.get(), flowProcess ); 292 } 293 294 /** 295 * Method writeLong will add each {@code long} instance to the {@link TupleEntryCollector} provided 296 * by the given {@link Tap} instance. 297 * 298 * @param stream a Stream of long values 299 * @param into the Tap to sink each value into 300 * @param flowProcess represents the current platform configuration 301 * @return returns the given Tap 302 */ 303 @SuppressWarnings("unchecked") 304 public static Tap writeLong( LongStream stream, Tap into, FlowProcess flowProcess ) 305 { 306 Objects.requireNonNull( into ); 307 Objects.requireNonNull( stream ); 308 309 Tuple tuple = Tuple.size( 1 ); 310 311 try 312 { 313 TupleEntryCollector collector = into.openForWrite( flowProcess ); 314 315 stream.forEach( i -> collector.add( reset( tuple, i ) ) ); 316 317 collector.close(); 318 } 319 catch( IOException exception ) 320 { 321 throw new UncheckedIOException( exception ); 322 } 323 324 return into; 325 } 326 327 /** 328 * Method writeDouble will add each {@code double} instance to the {@link TupleEntryCollector} provided 329 * by the given {@link Tap} instance. 330 * 331 * @param stream a Stream of double values 332 * @param into a Supplier that returns the Tap to sink each value into 333 * @param flowProcess represents the current platform configuration 334 * @return returns the given Tap 335 */ 336 public static Tap writeDouble( DoubleStream stream, Supplier<Tap> into, FlowProcess flowProcess ) 337 { 338 return writeDouble( stream, into.get(), flowProcess ); 339 } 340 341 /** 342 * Method writeDouble will add each {@code double} instance to the {@link TupleEntryCollector} provided 343 * by the given {@link Tap} instance. 344 * 345 * @param stream a Stream of double values 346 * @param into the Tap to sink each value into 347 * @param flowProcess represents the current platform configuration 348 * @return returns the given Tap 349 */ 350 @SuppressWarnings("unchecked") 351 public static Tap writeDouble( DoubleStream stream, Tap into, FlowProcess flowProcess ) 352 { 353 Objects.requireNonNull( into ); 354 Objects.requireNonNull( stream ); 355 356 Tuple tuple = Tuple.size( 1 ); 357 358 try 359 { 360 TupleEntryCollector collector = into.openForWrite( flowProcess ); 361 362 stream.forEach( i -> collector.add( reset( tuple, i ) ) ); 363 364 collector.close(); 365 } 366 catch( IOException exception ) 367 { 368 throw new UncheckedIOException( exception ); 369 } 370 371 return into; 372 } 373 374 private static Tuple reset( Tuple tuple, Object value ) 375 { 376 tuple.set( 0, value ); 377 return tuple; 378 } 379 }