Skip to content

Commit

Permalink
ARROW-6633: [C++] Vendor double-conversion library
Browse files Browse the repository at this point in the history
Since this is both a mandatory dependency and a small-ish library, vendor it to make the build chain simplier. Also, make its use private, because of Windows DLL exports. This incurs a small (~8-10%) performance hit on specific workloads.

Closes apache#5832 from pitrou/ARROW-6633-vendor-double-conversion and squashes the following commits:

b1e12c7 <Antoine Pitrou> Remove unneeded code
8587764 <Antoine Pitrou> Add license
3b89b19 <Antoine Pitrou> Make use of double-conversion private.
9e1da51 <Antoine Pitrou> ARROW-6633:  Vendor double-conversion library

Authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: François Saint-Jacques <fsaintjacques@gmail.com>
  • Loading branch information
pitrou authored and fsaintjacques committed Nov 15, 2019
1 parent b6aa401 commit 767c953
Show file tree
Hide file tree
Showing 55 changed files with 6,648 additions and 337 deletions.
65 changes: 32 additions & 33 deletions LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,38 @@ You can contact the author at :

--------------------------------------------------------------------------------

The files in cpp/src/arrow/vendored/double-conversion/ have the following license
(BSD 3-Clause License)

Copyright 2006-2011, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------

The files under dev/tasks/conda-recipes have the following license

BSD 3-clause license
Expand Down Expand Up @@ -1326,39 +1358,6 @@ Other dependencies and licenses:

--------------------------------------------------------------------------------

3rdparty dependency double-conversion is statically linked in certain binary
distributions, like the python wheels. double-conversion has the following
license:

Copyright 2006-2011, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------

3rdparty dependency snappy is statically linked in certain binary
distributions, like the python wheels. snappy has the following license:

Expand Down
7 changes: 3 additions & 4 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,9 @@ set(ARROW_SHARED_INSTALL_INTERFACE_LIBS)
set(ARROW_STATIC_INSTALL_INTERFACE_LIBS)

# Libraries to link statically with libarrow.so
set(ARROW_LINK_LIBS ${double-conversion_LIBRARIES})
set(ARROW_STATIC_LINK_LIBS ${double-conversion_LIBRARIES})
set(ARROW_STATIC_INSTALL_INTERFACE_LIBS ${double-conversion_LIBRARIES})
set(ARROW_LINK_LIBS)
set(ARROW_STATIC_LINK_LIBS)
set(ARROW_STATIC_INSTALL_INTERFACE_LIBS)

if(ARROW_WITH_URIPARSER)
list(APPEND ARROW_STATIC_LINK_LIBS uriparser::uriparser)
Expand Down Expand Up @@ -711,7 +711,6 @@ set(ARROW_TEST_SHARED_LINK_LIBS
arrow_testing_shared
arrow_shared
${ARROW_LINK_LIBS}
${double-conversion_LIBRARIES}
${BOOST_FILESYSTEM_LIBRARY}
${BOOST_SYSTEM_LIBRARY}
${ARROW_TEST_LINK_TOOLCHAIN})
Expand Down
45 changes: 0 additions & 45 deletions cpp/cmake_modules/FindDoubleConversion.cmake

This file was deleted.

91 changes: 0 additions & 91 deletions cpp/cmake_modules/ThirdpartyToolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ set(ARROW_THIRDPARTY_DEPENDENCIES
Brotli
BZip2
c-ares
double-conversion
gflags
GLOG
gRPC
Expand All @@ -87,7 +86,6 @@ endif()

message(STATUS "Using ${ARROW_DEPENDENCY_SOURCE} approach to find dependencies")

# TODO: double-conversion check fails for conda, it should not
if(ARROW_DEPENDENCY_SOURCE STREQUAL "CONDA")
if(MSVC)
set(ARROW_PACKAGE_PREFIX "$ENV{CONDA_PREFIX}/Library")
Expand Down Expand Up @@ -281,15 +279,6 @@ else()
set(CARES_SOURCE_URL "https://c-ares.haxx.se/download/c-ares-${CARES_VERSION}.tar.gz")
endif()

if(DEFINED ENV{ARROW_DOUBLE_CONVERSION_URL})
set(DOUBLE_CONVERSION_SOURCE_URL "$ENV{ARROW_DOUBLE_CONVERSION_URL}")
else()
set(
DOUBLE_CONVERSION_SOURCE_URL
"https://github.com/google/double-conversion/archive/${DOUBLE_CONVERSION_VERSION}.tar.gz"
)
endif()

if(DEFINED ENV{ARROW_GBENCHMARK_URL})
set(GBENCHMARK_SOURCE_URL "$ENV{ARROW_GBENCHMARK_URL}")
else()
Expand Down Expand Up @@ -658,86 +647,6 @@ if(ARROW_BOOST_REQUIRED)
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
endif()

# ----------------------------------------------------------------------
# Google double-conversion

macro(build_double_conversion)
message(STATUS "Building double-conversion from source")
set(DOUBLE_CONVERSION_PREFIX
"${CMAKE_CURRENT_BINARY_DIR}/double-conversion_ep/src/double-conversion_ep")
set(DOUBLE_CONVERSION_LIB_DIR "lib")
set(double-conversion_INCLUDE_DIRS "${DOUBLE_CONVERSION_PREFIX}/include")
set(
DOUBLE_CONVERSION_STATIC_LIB
"${DOUBLE_CONVERSION_PREFIX}/${DOUBLE_CONVERSION_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}double-conversion${CMAKE_STATIC_LIBRARY_SUFFIX}"
)

set(DOUBLE_CONVERSION_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS}
"-DCMAKE_INSTALL_PREFIX=${DOUBLE_CONVERSION_PREFIX}"
"-DCMAKE_INSTALL_LIBDIR=${DOUBLE_CONVERSION_LIB_DIR}")

externalproject_add(double-conversion_ep
${EP_LOG_OPTIONS}
INSTALL_DIR ${DOUBLE_CONVERSION_PREFIX}
URL ${DOUBLE_CONVERSION_SOURCE_URL}
CMAKE_ARGS ${DOUBLE_CONVERSION_CMAKE_ARGS}
BUILD_BYPRODUCTS "${DOUBLE_CONVERSION_STATIC_LIB}")

add_library(double-conversion STATIC IMPORTED)
set_target_properties(double-conversion
PROPERTIES IMPORTED_LOCATION "${DOUBLE_CONVERSION_STATIC_LIB}")
add_dependencies(toolchain double-conversion_ep)
add_dependencies(double-conversion double-conversion_ep)
set(double-conversion_LIBRARIES double-conversion)
endmacro()

macro(double_conversion_config)
# Map the newer target to the old, simpler setting
if(TARGET double-conversion::double-conversion)
set(double-conversion_LIBRARIES double-conversion::double-conversion)
get_target_property(double-conversion_INCLUDE_DIRS
double-conversion::double-conversion
INTERFACE_INCLUDE_DIRECTORIES)
endif()
endmacro()

macro(double_conversion_compability)
check_cxx_source_compiles("
#include <double-conversion/double-conversion.h>
int main() {
const int flags_ = double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY;
}" DOUBLE_CONVERSION_HAS_CASE_INSENSIBILITY)
endmacro()

if(double-conversion_SOURCE STREQUAL "AUTO")
# Debian does not ship cmake configs for double-conversion
# TODO: Make upstream bug
find_package(double-conversion QUIET)
if(NOT double-conversion_FOUND)
find_package(DoubleConversion)
endif()
if(double-conversion_FOUND OR DoubleConversion_FOUND)
double_conversion_config()
else()
build_double_conversion()
endif()
elseif(double-conversion_SOURCE STREQUAL "BUNDLED")
build_double_conversion()
elseif(double-conversion_SOURCE STREQUAL "SYSTEM")
# Debian does not ship cmake configs for double-conversion
# TODO: Make upstream bug
find_package(double-conversion)
if(NOT double-conversion_FOUND)
find_package(DoubleConversion REQUIRED)
endif()

double_conversion_config()
endif()
# TODO: Don't use global includes but rather target_include_directories
include_directories(SYSTEM ${double-conversion_INCLUDE_DIRS})

double_conversion_compability()

# ----------------------------------------------------------------------
# uriparser library

Expand Down
11 changes: 10 additions & 1 deletion cpp/src/arrow/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,23 @@ set(ARROW_SRCS
util/logging.cc
util/key_value_metadata.cc
util/memory.cc
util/parsing.cc
util/string.cc
util/string_builder.cc
util/task_group.cc
util/thread_pool.cc
util/trie.cc
util/utf8.cc
vendored/base64.cpp
vendored/datetime/tz.cpp)
vendored/datetime/tz.cpp
vendored/double-conversion/bignum.cc
vendored/double-conversion/double-conversion.cc
vendored/double-conversion/bignum-dtoa.cc
vendored/double-conversion/fast-dtoa.cc
vendored/double-conversion/cached-powers.cc
vendored/double-conversion/fixed-dtoa.cc
vendored/double-conversion/diy-fp.cc
vendored/double-conversion/strtod.cc)

if(ARROW_WITH_BOOST_FILESYSTEM)
add_definitions(-DARROW_WITH_BOOST_FILESYSTEM)
Expand Down
1 change: 0 additions & 1 deletion cpp/src/arrow/util/config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@
#define ARROW_SO_VERSION "@ARROW_SO_VERSION@"
#define ARROW_FULL_SO_VERSION "@ARROW_FULL_SO_VERSION@"

#cmakedefine DOUBLE_CONVERSION_HAS_CASE_INSENSIBILITY
#cmakedefine GRPCPP_PP_INCLUDE
32 changes: 32 additions & 0 deletions cpp/src/arrow/util/double_conversion.h
Original file line number Diff line number Diff line change
@@ -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.

#pragma once

#include "arrow/vendored/double-conversion/double-conversion.h"

namespace arrow {
namespace util {
namespace double_conversion {

using ::double_conversion::DoubleToStringConverter;
using ::double_conversion::StringBuilder;
using ::double_conversion::StringToDoubleConverter;

} // namespace double_conversion
} // namespace util
} // namespace arrow
40 changes: 40 additions & 0 deletions cpp/src/arrow/util/formatting.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@
// under the License.

#include "arrow/util/formatting.h"
#include "arrow/util/config.h"
#include "arrow/util/double_conversion.h"
#include "arrow/util/logging.h"

namespace arrow {

using util::double_conversion::DoubleToStringConverter;

static constexpr int kMinBufferSize = DoubleToStringConverter::kBase10MaximalLength + 1;

namespace internal {
namespace detail {

Expand All @@ -28,6 +36,38 @@ const char digit_pairs[] =
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";

} // namespace detail

struct FloatToStringFormatter::Impl {
Impl()
: converter_(DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN, "inf", "nan",
'e', -6, 10, 6, 0) {}

DoubleToStringConverter converter_;
};

FloatToStringFormatter::FloatToStringFormatter() : impl_(new Impl()) {}

FloatToStringFormatter::~FloatToStringFormatter() {}

int FloatToStringFormatter::FormatFloat(float v, char* out_buffer, int out_size) {
DCHECK_GE(out_size, kMinBufferSize);
// StringBuilder checks bounds in debug mode for us
util::double_conversion::StringBuilder builder(out_buffer, out_size);
bool result = impl_->converter_.ToShortestSingle(v, &builder);
DCHECK(result);
ARROW_UNUSED(result);
return builder.position();
}

int FloatToStringFormatter::FormatFloat(double v, char* out_buffer, int out_size) {
DCHECK_GE(out_size, kMinBufferSize);
util::double_conversion::StringBuilder builder(out_buffer, out_size);
bool result = impl_->converter_.ToShortest(v, &builder);
DCHECK(result);
ARROW_UNUSED(result);
return builder.position();
}

} // namespace internal
} // namespace arrow

0 comments on commit 767c953

Please sign in to comment.