diff --git a/.travis.yml b/.travis.yml index 2873dc07543..60c44462f6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,7 @@ matrix: env: - ARROW_TRAVIS_VALGRIND=1 - ARROW_TRAVIS_USE_TOOLCHAIN=1 + - ARROW_TRAVIS_FLIGHT=1 - ARROW_TRAVIS_PLASMA=1 - ARROW_TRAVIS_ORC=1 - ARROW_TRAVIS_PARQUET=1 @@ -86,10 +87,11 @@ matrix: os: linux jdk: openjdk8 env: + - ARROW_TRAVIS_COVERAGE=1 - ARROW_TRAVIS_USE_TOOLCHAIN=1 + - ARROW_TRAVIS_FLIGHT=1 - ARROW_TRAVIS_PLASMA=1 - ARROW_TRAVIS_ORC=1 - - ARROW_TRAVIS_COVERAGE=1 - ARROW_TRAVIS_PARQUET=1 - ARROW_TRAVIS_GANDIVA=1 - ARROW_TRAVIS_GANDIVA_JAVA=1 @@ -181,6 +183,7 @@ matrix: env: - ARROW_TRAVIS_USE_TOOLCHAIN=1 - ARROW_TRAVIS_PLASMA=1 + - ARROW_TRAVIS_FLIGHT=1 - ARROW_TRAVIS_ORC=1 - ARROW_TRAVIS_PARQUET=1 - ARROW_TRAVIS_GANDIVA=1 diff --git a/ci/conda_env_cpp.yml b/ci/conda_env_cpp.yml index 3d50b210ea6..fbe45769a72 100644 --- a/ci/conda_env_cpp.yml +++ b/ci/conda_env_cpp.yml @@ -20,12 +20,14 @@ boost-cpp=1.68.0 brotli bzip2 +c-ares cmake double-conversion flatbuffers gflags glog gmock +grpc-cpp gtest libprotobuf lz4-c diff --git a/ci/travis_before_script_cpp.sh b/ci/travis_before_script_cpp.sh index 6c65cd62ac8..a1e407fe1f9 100755 --- a/ci/travis_before_script_cpp.sh +++ b/ci/travis_before_script_cpp.sh @@ -86,6 +86,10 @@ if [ "$ARROW_TRAVIS_USE_TOOLCHAIN" == "1" ]; then fi fi +if [ "$ARROW_TRAVIS_FLIGHT" == "1" ]; then + CMAKE_COMMON_FLAGS="$CMAKE_COMMON_FLAGS -DARROW_FLIGHT=ON" +fi + if [ "$ARROW_TRAVIS_PLASMA" == "1" ]; then CMAKE_COMMON_FLAGS="$CMAKE_COMMON_FLAGS -DARROW_PLASMA=ON" fi diff --git a/cpp/cmake_modules/Findc-ares.cmake b/cpp/cmake_modules/Findc-ares.cmake index 1366ce33fa7..2b7b58916c6 100644 --- a/cpp/cmake_modules/Findc-ares.cmake +++ b/cpp/cmake_modules/Findc-ares.cmake @@ -42,8 +42,9 @@ if (MSVC) else () set(CARES_LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}cares${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(CARES_STATIC_LIB_NAME - ${CMAKE_STATIC_LIBRARY_PREFIX}cares${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(CARES_STATIC_LIB_NAMES + ${CMAKE_STATIC_LIBRARY_PREFIX}cares${CMAKE_STATIC_LIBRARY_SUFFIX} + ${CMAKE_STATIC_LIBRARY_PREFIX}cares_static${CMAKE_STATIC_LIBRARY_SUFFIX}) endif () # Try the parameterized roots, if they exist @@ -56,7 +57,7 @@ if (_cares_roots) PATHS ${_cares_roots} NO_DEFAULT_PATH PATH_SUFFIXES "lib") find_library(CARES_STATIC_LIB - NAMES ${CARES_STATIC_LIB_NAME} + NAMES ${CARES_STATIC_LIB_NAMES} PATHS ${_cares_roots} NO_DEFAULT_PATH PATH_SUFFIXES "lib") else () diff --git a/cpp/src/arrow/flight/CMakeLists.txt b/cpp/src/arrow/flight/CMakeLists.txt index 3e0323fcfe0..a32a5fa03c0 100644 --- a/cpp/src/arrow/flight/CMakeLists.txt +++ b/cpp/src/arrow/flight/CMakeLists.txt @@ -28,12 +28,11 @@ set(ARROW_FLIGHT_STATIC_LINK_LIBS grpc_address_sorting_static cares_static) -set(ARROW_FLIGHT_TEST_STATIC_LINK_LIBS - arrow_static - arrow_flight_static - arrow_testing_static - ${ARROW_FLIGHT_STATIC_LINK_LIBS} - ${PROTOBUF_LIBRARY}) +set(ARROW_FLIGHT_TEST_LINK_LIBS + arrow_flight_shared + arrow_flight_testing_shared + ${ARROW_TEST_SHARED_LINK_LIBS} + ${ARROW_FLIGHT_STATIC_LINK_LIBS}) # TODO(wesm): Protobuf shared vs static linking @@ -78,25 +77,43 @@ add_arrow_lib(arrow_flight arrow_static ${ARROW_FLIGHT_STATIC_LINK_LIBS}) +# Define arrow_flight_testing library +if(ARROW_BUILD_TESTS OR ARROW_BUILD_BENCHMARKS) + add_arrow_lib(arrow_flight_testing + SOURCES + test-util.cc + DEPENDENCIES + ${GTEST_LIBRARY} + SHARED_LINK_LIBS + arrow_shared + arrow_flight_shared + ${BOOST_FILESYSTEM_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} + ${GTEST_LIBRARY} + STATIC_LINK_LIBS + arrow_static + arrow_flight_static) +endif() + add_arrow_test(flight-test EXTRA_LINK_LIBS - ${ARROW_FLIGHT_TEST_STATIC_LINK_LIBS} + ${ARROW_FLIGHT_TEST_LINK_LIBS} LABELS "arrow_flight") # Build test server for unit tests or benchmarks if(ARROW_BUILD_TESTS OR ARROW_BUILD_BENCHMARKS) add_executable(flight-test-server test-server.cc) - target_link_libraries(flight-test-server ${ARROW_FLIGHT_TEST_STATIC_LINK_LIBS} - gflags_static ${GTEST_LIBRARY}) + target_link_libraries(flight-test-server ${ARROW_FLIGHT_TEST_LINK_LIBS} gflags_static + ${GTEST_LIBRARY}) add_executable(flight-test-integration-server test-integration-server.cc) - target_link_libraries(flight-test-integration-server - ${ARROW_FLIGHT_TEST_STATIC_LINK_LIBS} gflags_static gtest_static) + target_link_libraries(flight-test-integration-server ${ARROW_FLIGHT_TEST_LINK_LIBS} + gflags_static gtest_static) add_executable(flight-test-integration-client test-integration-client.cc) - target_link_libraries(flight-test-integration-client - ${ARROW_FLIGHT_TEST_STATIC_LINK_LIBS} gflags_static gtest_static) + target_link_libraries(flight-test-integration-client ${ARROW_FLIGHT_TEST_LINK_LIBS} + gflags_static gtest_static) # This is needed for the unit tests if(ARROW_BUILD_TESTS) @@ -116,9 +133,9 @@ if(ARROW_BUILD_BENCHMARKS) add_executable(flight-perf-server perf-server.cc perf.pb.cc) target_link_libraries(flight-perf-server - arrow_flight_static - arrow_testing_static - ${ARROW_FLIGHT_STATIC_LINK_LIBS} + arrow_flight_shared + arrow_flight_testing_shared + ${ARROW_FLIGHT_TEST_LINK_LIBS} gflags_static ${GTEST_LIBRARY}) @@ -126,7 +143,7 @@ if(ARROW_BUILD_BENCHMARKS) target_link_libraries(flight-benchmark arrow_flight_static arrow_testing_static - ${ARROW_FLIGHT_STATIC_LINK_LIBS} + ${ARROW_FLIGHT_TEST_LINK_LIBS} gflags_static ${GTEST_LIBRARY}) diff --git a/cpp/src/arrow/flight/client.cc b/cpp/src/arrow/flight/client.cc index a58c2b59332..fd13f79c96b 100644 --- a/cpp/src/arrow/flight/client.cc +++ b/cpp/src/arrow/flight/client.cc @@ -196,8 +196,11 @@ class FlightClient::FlightClientImpl { ss << host << ":" << port; std::string uri = ss.str(); + grpc::ChannelArguments args; + // Try to reconnect quickly at first, in case the server is still starting up + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 100); stub_ = pb::FlightService::NewStub( - grpc::CreateChannel(ss.str(), grpc::InsecureChannelCredentials())); + grpc::CreateCustomChannel(ss.str(), grpc::InsecureChannelCredentials(), args)); return Status::OK(); } diff --git a/cpp/src/arrow/flight/client.h b/cpp/src/arrow/flight/client.h index ef960417b02..334158d3e81 100644 --- a/cpp/src/arrow/flight/client.h +++ b/cpp/src/arrow/flight/client.h @@ -116,7 +116,7 @@ class ARROW_EXPORT FlightClient { /// \brief An interface to upload record batches to a Flight server class ARROW_EXPORT FlightPutWriter : public ipc::RecordBatchWriter { public: - ~FlightPutWriter(); + ~FlightPutWriter() override; Status WriteRecordBatch(const RecordBatch& batch, bool allow_64bit = false) override; Status Close() override; diff --git a/cpp/src/arrow/flight/flight-test.cc b/cpp/src/arrow/flight/flight-test.cc index 12fe5033aa4..9268aecaa2d 100644 --- a/cpp/src/arrow/flight/flight-test.cc +++ b/cpp/src/arrow/flight/flight-test.cc @@ -28,10 +28,10 @@ #include #include #include +#include #include #include -#include #include "arrow/ipc/test-common.h" #include "arrow/status.h" @@ -62,6 +62,7 @@ TEST(TestFlight, StartStopTestServer) { ASSERT_TRUE(server.IsRunning()); int exit_code = server.Stop(); ASSERT_EQ(0, exit_code); + ASSERT_FALSE(server.IsRunning()); } // ---------------------------------------------------------------------- diff --git a/cpp/src/arrow/flight/perf-server.cc b/cpp/src/arrow/flight/perf-server.cc index add544276f5..b4702834439 100644 --- a/cpp/src/arrow/flight/perf-server.cc +++ b/cpp/src/arrow/flight/perf-server.cc @@ -29,9 +29,11 @@ #include "arrow/io/test-common.h" #include "arrow/ipc/writer.h" #include "arrow/record_batch.h" +#include "arrow/testing/util.h" +#include "arrow/flight/api.h" +#include "arrow/flight/internal.h" #include "arrow/flight/perf.pb.h" -#include "arrow/flight/server.h" #include "arrow/flight/test-util.h" DEFINE_int32(port, 31337, "Server port to listen on"); diff --git a/cpp/src/arrow/flight/serialization-internal.h b/cpp/src/arrow/flight/serialization-internal.h index d4254d606d4..06cdcdf5052 100644 --- a/cpp/src/arrow/flight/serialization-internal.h +++ b/cpp/src/arrow/flight/serialization-internal.h @@ -25,6 +25,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/wire_format_lite.h" #include "grpc/byte_buffer_reader.h" #include "grpcpp/grpcpp.h" @@ -66,33 +67,6 @@ namespace internal { using google::protobuf::io::CodedInputStream; using google::protobuf::io::CodedOutputStream; -// More efficient writing of FlightData to gRPC output buffer -// Implementation of ZeroCopyOutputStream that writes to a fixed-size buffer -class FixedSizeProtoWriter : public ::google::protobuf::io::ZeroCopyOutputStream { - public: - explicit FixedSizeProtoWriter(grpc_slice slice) - : slice_(slice), - bytes_written_(0), - total_size_(static_cast(GRPC_SLICE_LENGTH(slice))) {} - - bool Next(void** data, int* size) override { - // Consume the whole slice - *data = GRPC_SLICE_START_PTR(slice_) + bytes_written_; - *size = total_size_ - bytes_written_; - bytes_written_ = total_size_; - return true; - } - - void BackUp(int count) override { bytes_written_ -= count; } - - int64_t ByteCount() const override { return bytes_written_; } - - private: - grpc_slice slice_; - int bytes_written_; - int total_size_; -}; - bool ReadBytesZeroCopy(const std::shared_ptr& source_data, CodedInputStream* input, std::shared_ptr* out); @@ -159,11 +133,11 @@ class GrpcBuffer : public arrow::MutableBuffer { namespace grpc { using arrow::flight::FlightData; -using arrow::flight::internal::FixedSizeProtoWriter; using arrow::flight::internal::GrpcBuffer; using arrow::flight::internal::ReadBytesZeroCopy; using google::protobuf::internal::WireFormatLite; +using google::protobuf::io::ArrayOutputStream; using google::protobuf::io::CodedInputStream; using google::protobuf::io::CodedOutputStream; @@ -298,7 +272,8 @@ class SerializationTraits { // XXX(wesm): for debugging // std::cout << "Writing record batch with total size " << total_size << std::endl; - FixedSizeProtoWriter writer(*reinterpret_cast(&slice)); + ArrayOutputStream writer(const_cast(slice.begin()), + static_cast(slice.size())); CodedOutputStream pb_stream(&writer); // Write header diff --git a/cpp/src/arrow/flight/test-integration-client.cc b/cpp/src/arrow/flight/test-integration-client.cc index 62522833f4b..89ae88cb9ee 100644 --- a/cpp/src/arrow/flight/test-integration-client.cc +++ b/cpp/src/arrow/flight/test-integration-client.cc @@ -29,10 +29,12 @@ #include "arrow/io/test-common.h" #include "arrow/ipc/json.h" +#include "arrow/ipc/writer.h" #include "arrow/record_batch.h" #include "arrow/table.h" +#include "arrow/util/logging.h" -#include "arrow/flight/server.h" +#include "arrow/flight/api.h" #include "arrow/flight/test-util.h" DEFINE_string(host, "localhost", "Server port to connect to"); diff --git a/cpp/src/arrow/flight/test-integration-server.cc b/cpp/src/arrow/flight/test-integration-server.cc index 7e201a03194..0381e90f9f8 100644 --- a/cpp/src/arrow/flight/test-integration-server.cc +++ b/cpp/src/arrow/flight/test-integration-server.cc @@ -28,7 +28,9 @@ #include "arrow/ipc/json.h" #include "arrow/record_batch.h" #include "arrow/table.h" +#include "arrow/util/logging.h" +#include "arrow/flight/internal.h" #include "arrow/flight/server.h" #include "arrow/flight/test-util.h" diff --git a/cpp/src/arrow/flight/test-util.cc b/cpp/src/arrow/flight/test-util.cc new file mode 100644 index 00000000000..7b8a7f33cb8 --- /dev/null +++ b/cpp/src/arrow/flight/test-util.cc @@ -0,0 +1,164 @@ +// 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. + +#ifdef __APPLE__ +#include +#include +#endif + +#include + +#include +#include + +#include + +#include "arrow/ipc/test-common.h" +#include "arrow/testing/gtest_util.h" +#include "arrow/util/logging.h" + +#include "arrow/flight/api.h" +#include "arrow/flight/internal.h" +#include "arrow/flight/test-util.h" + +namespace arrow { +namespace flight { + +namespace bp = boost::process; +namespace fs = boost::filesystem; + +namespace { + +Status ResolveCurrentExecutable(fs::path* out) { + // See https://stackoverflow.com/a/1024937/10194 for various + // platform-specific recipes. + + boost::system::error_code ec; + +#if defined(__linux__) + *out = fs::canonical("/proc/self/exe", ec); +#elif defined(__APPLE__) + char buf[PATH_MAX + 1]; + uint32_t bufsize = sizeof(buf); + if (_NSGetExecutablePath(buf, &bufsize) < 0) { + return Status::Invalid("Can't resolve current exe: path too large"); + } + *out = fs::canonical(buf, ec); +#else + ARROW_UNUSED(ec); + return Status::NotImplemented("Not available on this system"); +#endif + if (ec) { + // XXX fold this into the Status class? + return Status::IOError("Can't resolve current exe: ", ec.message()); + } else { + return Status::OK(); + } +} + +} // namespace + +void TestServer::Start() { + namespace fs = boost::filesystem; + + std::string str_port = std::to_string(port_); + std::vector search_path = ::boost::this_process::path(); + // If possible, prepend current executable directory to search path, + // since it's likely that the test server executable is located in + // the same directory as the running unit test. + fs::path current_exe; + Status st = ResolveCurrentExecutable(¤t_exe); + if (st.ok()) { + search_path.insert(search_path.begin(), current_exe.parent_path()); + } else if (st.IsNotImplemented()) { + ARROW_CHECK(st.IsNotImplemented()) << st.ToString(); + } + + try { + server_process_ = std::make_shared( + bp::search_path(executable_name_, search_path), "-port", str_port); + } catch (...) { + std::stringstream ss; + ss << "Failed to launch test server '" << executable_name_ << "', looked in "; + for (const auto& path : search_path) { + ss << path << " : "; + } + ARROW_LOG(FATAL) << ss.str(); + throw; + } + std::cout << "Server running with pid " << server_process_->id() << std::endl; +} + +int TestServer::Stop() { + if (server_process_ && server_process_->valid()) { + kill(server_process_->id(), SIGTERM); + server_process_->wait(); + return server_process_->exit_code(); + } else { + // Presumably the server wasn't able to start + return -1; + } +} + +bool TestServer::IsRunning() { return server_process_->running(); } + +int TestServer::port() const { return port_; } + +Status MakeFlightInfo(const Schema& schema, const FlightDescriptor& descriptor, + const std::vector& endpoints, + uint64_t total_records, uint64_t total_bytes, + FlightInfo::Data* out) { + out->descriptor = descriptor; + out->endpoints = endpoints; + out->total_records = total_records; + out->total_bytes = total_bytes; + return internal::SchemaToString(schema, &out->schema); +} + +std::vector ExampleFlightInfo() { + FlightEndpoint endpoint1({{"ticket-id-1"}, {{"foo1.bar.com", 92385}}}); + FlightEndpoint endpoint2({{"ticket-id-2"}, {{"foo2.bar.com", 92385}}}); + FlightEndpoint endpoint3({{"ticket-id-3"}, {{"foo3.bar.com", 92385}}}); + FlightDescriptor descr1{FlightDescriptor::PATH, "", {"foo", "bar"}}; + FlightDescriptor descr2{FlightDescriptor::CMD, "my_command", {}}; + + auto schema1 = ExampleSchema1(); + auto schema2 = ExampleSchema2(); + + FlightInfo::Data flight1, flight2; + EXPECT_OK( + MakeFlightInfo(*schema1, descr1, {endpoint1, endpoint2}, 1000, 100000, &flight1)); + EXPECT_OK(MakeFlightInfo(*schema2, descr2, {endpoint3}, 1000, 100000, &flight2)); + return {FlightInfo(flight1), FlightInfo(flight2)}; +} + +Status SimpleIntegerBatches(const int num_batches, BatchVector* out) { + std::shared_ptr batch; + for (int i = 0; i < num_batches; ++i) { + // Make all different sizes, use different random seed + RETURN_NOT_OK(ipc::MakeIntBatchSized(10 + i, &batch, i)); + out->push_back(batch); + } + return Status::OK(); +} + +std::vector ExampleActionTypes() { + return {{"drop", "drop a dataset"}, {"cache", "cache a dataset"}}; +} + +} // namespace flight +} // namespace arrow diff --git a/cpp/src/arrow/flight/test-util.h b/cpp/src/arrow/flight/test-util.h index 5dea008b28d..f955e3d7137 100644 --- a/cpp/src/arrow/flight/test-util.h +++ b/cpp/src/arrow/flight/test-util.h @@ -16,23 +16,21 @@ // under the License. #include -#include -#include -#include #include #include #include -#include - -#include "arrow/ipc/test-common.h" #include "arrow/status.h" -#include "arrow/testing/gtest_util.h" -#include "arrow/flight/api.h" -#include "arrow/flight/internal.h" +#include "arrow/flight/types.h" + +namespace boost { +namespace process { + +class child; -namespace bp = boost::process; +} // namespace process +} // namespace boost namespace arrow { namespace flight { @@ -40,32 +38,23 @@ namespace flight { // ---------------------------------------------------------------------- // Fixture to use for running test servers -struct TestServer { +class ARROW_EXPORT TestServer { public: explicit TestServer(const std::string& executable_name, int port) : executable_name_(executable_name), port_(port) {} - void Start() { - std::string str_port = std::to_string(port_); - server_process_.reset( - new bp::child(bp::search_path(executable_name_), "-port", str_port)); - std::cout << "Server running with pid " << server_process_->id() << std::endl; - } + void Start(); - int Stop() { - kill(server_process_->id(), SIGTERM); - server_process_->wait(); - return server_process_->exit_code(); - } + int Stop(); - bool IsRunning() { return server_process_->running(); } + bool IsRunning(); - int port() const { return port_; } + int port() const; private: std::string executable_name_; int port_; - std::unique_ptr server_process_; + std::shared_ptr<::boost::process::child> server_process_; }; // ---------------------------------------------------------------------- @@ -99,59 +88,32 @@ class BatchIterator : public RecordBatchReader { using BatchVector = std::vector>; -std::shared_ptr ExampleSchema1() { +inline std::shared_ptr ExampleSchema1() { auto f0 = field("f0", int32()); auto f1 = field("f1", int32()); return ::arrow::schema({f0, f1}); } -std::shared_ptr ExampleSchema2() { +inline std::shared_ptr ExampleSchema2() { auto f0 = field("f0", utf8()); auto f1 = field("f1", binary()); return ::arrow::schema({f0, f1}); } +ARROW_EXPORT Status MakeFlightInfo(const Schema& schema, const FlightDescriptor& descriptor, const std::vector& endpoints, uint64_t total_records, uint64_t total_bytes, - FlightInfo::Data* out) { - out->descriptor = descriptor; - out->endpoints = endpoints; - out->total_records = total_records; - out->total_bytes = total_bytes; - return internal::SchemaToString(schema, &out->schema); -} + FlightInfo::Data* out); -std::vector ExampleFlightInfo() { - FlightEndpoint endpoint1({{"ticket-id-1"}, {{"foo1.bar.com", 92385}}}); - FlightEndpoint endpoint2({{"ticket-id-2"}, {{"foo2.bar.com", 92385}}}); - FlightEndpoint endpoint3({{"ticket-id-3"}, {{"foo3.bar.com", 92385}}}); - FlightDescriptor descr1{FlightDescriptor::PATH, "", {"foo", "bar"}}; - FlightDescriptor descr2{FlightDescriptor::CMD, "my_command", {}}; - - auto schema1 = ExampleSchema1(); - auto schema2 = ExampleSchema2(); - - FlightInfo::Data flight1, flight2; - EXPECT_OK( - MakeFlightInfo(*schema1, descr1, {endpoint1, endpoint2}, 1000, 100000, &flight1)); - EXPECT_OK(MakeFlightInfo(*schema2, descr2, {endpoint3}, 1000, 100000, &flight2)); - return {FlightInfo(flight1), FlightInfo(flight2)}; -} +ARROW_EXPORT +std::vector ExampleFlightInfo(); -Status SimpleIntegerBatches(const int num_batches, BatchVector* out) { - std::shared_ptr batch; - for (int i = 0; i < num_batches; ++i) { - // Make all different sizes, use different random seed - RETURN_NOT_OK(ipc::MakeIntBatchSized(10 + i, &batch, i)); - out->push_back(batch); - } - return Status::OK(); -} +ARROW_EXPORT +Status SimpleIntegerBatches(const int num_batches, BatchVector* out); -std::vector ExampleActionTypes() { - return {{"drop", "drop a dataset"}, {"cache", "cache a dataset"}}; -} +ARROW_EXPORT +std::vector ExampleActionTypes(); } // namespace flight } // namespace arrow diff --git a/cpp/src/arrow/gpu/cuda-benchmark.cc b/cpp/src/arrow/gpu/cuda-benchmark.cc index 32b5f1fa7f0..a61eb921e91 100644 --- a/cpp/src/arrow/gpu/cuda-benchmark.cc +++ b/cpp/src/arrow/gpu/cuda-benchmark.cc @@ -24,6 +24,7 @@ #include "arrow/array.h" #include "arrow/memory_pool.h" #include "arrow/testing/gtest_util.h" +#include "arrow/testing/util.h" #include "arrow/gpu/cuda_api.h" diff --git a/cpp/src/arrow/util/stopwatch.h b/cpp/src/arrow/util/stopwatch.h index e90d0ba4f9f..db4e67f59ed 100644 --- a/cpp/src/arrow/util/stopwatch.h +++ b/cpp/src/arrow/util/stopwatch.h @@ -17,34 +17,31 @@ #pragma once -#include -#ifndef _MSC_VER -#include -#endif - -#include -#include +#include +#include namespace arrow { namespace internal { -uint64_t CurrentTime() { - timespec time; - clock_gettime(CLOCK_MONOTONIC, &time); - return 1000000000L * time.tv_sec + time.tv_nsec; -} - class StopWatch { + // This clock should give us wall clock time + using ClockType = std::chrono::steady_clock; + public: StopWatch() {} - void Start() { start_ = CurrentTime(); } + void Start() { start_ = ClockType::now(); } // Returns time in nanoseconds. - uint64_t Stop() { return CurrentTime() - start_; } + uint64_t Stop() { + auto stop = ClockType::now(); + std::chrono::nanoseconds d = stop - start_; + assert(d.count() >= 0); + return static_cast(d.count()); + } private: - uint64_t start_; + std::chrono::time_point start_; }; } // namespace internal