You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by he...@apache.org on 2017/03/29 02:53:48 UTC
[07/14] incubator-impala git commit: IMPALA-4758: (1/2) Update gutil/
from Kudu@a1bfd7b
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/map-util.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/map-util.h b/be/src/gutil/map-util.h
index 9368a5a..6fffedf 100644
--- a/be/src/gutil/map-util.h
+++ b/be/src/gutil/map-util.h
@@ -72,7 +72,8 @@ using std::pair;
using std::vector;
#include <glog/logging.h>
-#include "gutil/logging-inl.h"
+
+#include "kudu/gutil/logging-inl.h"
//
// Find*()
@@ -94,29 +95,29 @@ using std::vector;
// This version assumes the key is printable, and includes it in the fatal log
// message.
template <class Collection>
-const typename Collection::value_type::second_type&
+const typename Collection::mapped_type&
FindOrDie(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
- typename Collection::const_iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found: " << key;
return it->second;
}
// Same as above, but returns a non-const reference.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
FindOrDie(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
- typename Collection::iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found: " << key;
return it->second;
}
// Same as FindOrDie above, but doesn't log the key on failure.
template <class Collection>
-const typename Collection::value_type::second_type&
+const typename Collection::mapped_type&
FindOrDieNoPrint(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
+ const typename Collection::key_type& key) {
typename Collection::const_iterator it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found";
return it->second;
@@ -124,9 +125,9 @@ FindOrDieNoPrint(const Collection& collection,
// Same as above, but returns a non-const reference.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
FindOrDieNoPrint(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
+ const typename Collection::key_type& key) {
typename Collection::iterator it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found";
return it->second;
@@ -142,11 +143,11 @@ FindOrDieNoPrint(Collection& collection, // NOLINT
// string values, and you pass a char* as the default "value," either use the
// returned value immediately or store it in a string (not string&). Details:
template <class Collection>
-const typename Collection::value_type::second_type&
+const typename Collection::mapped_type&
FindWithDefault(const Collection& collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value) {
- typename Collection::const_iterator it = collection.find(key);
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value) {
+ auto it = collection.find(key);
if (it == collection.end()) {
return value;
}
@@ -156,10 +157,10 @@ FindWithDefault(const Collection& collection,
// Returns a pointer to the const value associated with the given key if it
// exists, or NULL otherwise.
template <class Collection>
-const typename Collection::value_type::second_type*
+const typename Collection::mapped_type*
FindOrNull(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
- typename Collection::const_iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
if (it == collection.end()) {
return 0;
}
@@ -168,16 +169,62 @@ FindOrNull(const Collection& collection,
// Same as above but returns a pointer to the non-const value.
template <class Collection>
-typename Collection::value_type::second_type*
+typename Collection::mapped_type*
FindOrNull(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
- typename Collection::iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
if (it == collection.end()) {
return 0;
}
return &it->second;
}
+// Returns a pointer to the const value associated with the greatest key
+// that's less than or equal to the given key, or NULL if no such key exists.
+template <class Collection>
+const typename Collection::mapped_type*
+FindFloorOrNull(const Collection& collection,
+ const typename Collection::key_type& key) {
+ auto it = collection.upper_bound(key);
+ if (it == collection.begin()) {
+ return 0;
+ }
+ return &(--it)->second;
+}
+
+// Same as above but returns a pointer to the non-const value.
+template <class Collection>
+typename Collection::mapped_type*
+FindFloorOrNull(Collection& collection, // NOLINT
+ const typename Collection::key_type& key) {
+ auto it = collection.upper_bound(key);
+ if (it == collection.begin()) {
+ return 0;
+ }
+ return &(--it)->second;
+}
+
+// Returns a const-reference to the value associated with the greatest key
+// that's less than or equal to the given key, or crashes if it does not exist.
+template <class Collection>
+const typename Collection::mapped_type&
+FindFloorOrDie(const Collection& collection,
+ const typename Collection::key_type& key) {
+ auto it = collection.upper_bound(key);
+ CHECK(it != collection.begin());
+ return (--it)->second;
+}
+
+// Same as above, but returns a non-const reference.
+template <class Collection>
+typename Collection::mapped_type&
+FindFloorOrDie(Collection& collection,
+ const typename Collection::key_type& key) {
+ auto it = collection.upper_bound(key);
+ CHECK(it != collection.begin());
+ return (--it)->second;
+}
+
// Returns the pointer value associated with the given key. If none is found,
// NULL is returned. The function is designed to be used with a map of keys to
// pointers.
@@ -185,12 +232,12 @@ FindOrNull(Collection& collection, // NOLINT
// This function does not distinguish between a missing key and a key mapped
// to a NULL value.
template <class Collection>
-typename Collection::value_type::second_type
+typename Collection::mapped_type
FindPtrOrNull(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
- typename Collection::const_iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
if (it == collection.end()) {
- return typename Collection::value_type::second_type(0);
+ return typename Collection::mapped_type(0);
}
return it->second;
}
@@ -200,23 +247,38 @@ FindPtrOrNull(const Collection& collection,
// This function is needed for containers that propagate constness to the
// pointee, such as boost::ptr_map.
template <class Collection>
-typename Collection::value_type::second_type
+typename Collection::mapped_type
FindPtrOrNull(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
- typename Collection::iterator it = collection.find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
if (it == collection.end()) {
- return typename Collection::value_type::second_type(0);
+ return typename Collection::mapped_type(0);
}
return it->second;
}
+// FindPtrOrNull like function for maps whose value is a smart pointer like shared_ptr or
+// unique_ptr.
+// Returns the raw pointer contained in the smart pointer for the first found key, if it exists,
+// or null if it doesn't.
+template <class Collection>
+typename Collection::mapped_type::element_type*
+FindPointeeOrNull(const Collection& collection, // NOLINT,
+ const typename Collection::key_type& key) {
+ auto it = collection.find(key);
+ if (it == collection.end()) {
+ return nullptr;
+ }
+ return it->second.get();
+}
+
// Finds the value associated with the given key and copies it to *value (if not
// NULL). Returns false if the key was not found, true otherwise.
template <class Collection, class Key, class Value>
bool FindCopy(const Collection& collection,
const Key& key,
Value* const value) {
- typename Collection::const_iterator it = collection.find(key);
+ auto it = collection.find(key);
if (it == collection.end()) {
return false;
}
@@ -233,7 +295,7 @@ bool FindCopy(const Collection& collection,
// Returns true iff the given collection contains the given key.
template <class Collection, class Key>
bool ContainsKey(const Collection& collection, const Key& key) {
- typename Collection::const_iterator it = collection.find(key);
+ auto it = collection.find(key);
return it != collection.end();
}
@@ -274,8 +336,8 @@ bool InsertOrUpdate(Collection* const collection,
// Same as above, except that the key and value are passed separately.
template <class Collection>
bool InsertOrUpdate(Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value) {
return InsertOrUpdate(
collection, typename Collection::value_type(key, value));
}
@@ -297,8 +359,8 @@ void InsertOrUpdateMany(Collection* const collection,
template <class Collection>
bool InsertAndDeleteExisting(
Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
if (!ret.second) {
@@ -323,8 +385,8 @@ bool InsertIfNotPresent(Collection* const collection,
template <class Collection>
bool InsertIfNotPresent(
Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value) {
return InsertIfNotPresent(
collection, typename Collection::value_type(key, value));
}
@@ -347,9 +409,8 @@ void InsertOrDieNoPrint(Collection* const collection,
// present.
template <class Collection>
void InsertOrDie(Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& data) {
- typedef typename Collection::value_type value_type;
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& data) {
CHECK(InsertIfNotPresent(collection, key, data))
<< "duplicate key: " << key;
}
@@ -358,9 +419,8 @@ void InsertOrDie(Collection* const collection,
template <class Collection>
void InsertOrDieNoPrint(
Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& data) {
- typedef typename Collection::value_type value_type;
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& data) {
CHECK(InsertIfNotPresent(collection, key, data)) << "duplicate key.";
}
@@ -371,12 +431,12 @@ void InsertOrDieNoPrint(
// SomeProto& proto = InsertKeyOrDie(&m, 3);
// proto.set_field("foo");
template <class Collection>
-typename Collection::value_type::second_type& InsertKeyOrDie(
+typename Collection::mapped_type& InsertKeyOrDie(
Collection* const collection,
- const typename Collection::value_type::first_type& key) {
+ const typename Collection::key_type& key) {
typedef typename Collection::value_type value_type;
pair<typename Collection::iterator, bool> res =
- collection->insert(value_type(key, typename value_type::second_type()));
+ collection->insert(value_type(key, typename Collection::mapped_type()));
CHECK(res.second) << "duplicate key: " << key;
return res.first->second;
}
@@ -389,7 +449,7 @@ typename Collection::value_type::second_type& InsertKeyOrDie(
// pair if it's not already present. Returns a reference to the value associated
// with the key.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsert(Collection* const collection,
const typename Collection::value_type& vt) {
return collection->insert(vt).first->second;
@@ -397,10 +457,10 @@ LookupOrInsert(Collection* const collection,
// Same as above except the key-value are passed separately.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsert(Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value) {
return LookupOrInsert(
collection, typename Collection::value_type(key, value));
}
@@ -418,13 +478,13 @@ LookupOrInsert(Collection* const collection,
template <typename Sequence, typename Collection>
void AddTokenCounts(
const Sequence& sequence,
- const typename Collection::value_type::second_type& increment,
+ const typename Collection::mapped_type& increment,
Collection* const count_map) {
for (typename Sequence::const_iterator it = sequence.begin();
it != sequence.end(); ++it) {
- typename Collection::value_type::second_type& value =
+ typename Collection::mapped_type& value =
LookupOrInsert(count_map, *it,
- typename Collection::value_type::second_type());
+ typename Collection::mapped_type());
value += increment;
}
}
@@ -448,13 +508,13 @@ void MapUtilAssignNewInstance(T** location, const Arg &arg) {
// inserting a new key, value pair involves constructing a new heap-allocated
// Value, and storing a pointer to that in the collection.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsertNew(Collection* const collection,
- const typename Collection::value_type::first_type& key) {
+ const typename Collection::key_type& key) {
pair<typename Collection::iterator, bool> ret =
collection->insert(
typename Collection::value_type(key,
- static_cast<typename Collection::value_type::second_type>(NULL)));
+ static_cast<typename Collection::mapped_type>(NULL)));
if (ret.second) {
// This helper is needed to 'extract' the Value type from the type of the
// container value, which is (Value*).
@@ -466,15 +526,15 @@ LookupOrInsertNew(Collection* const collection,
// Same as above but constructs the value using the single-argument constructor
// and the given "arg".
template <class Collection, class Arg>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsertNew(Collection* const collection,
- const typename Collection::value_type::first_type& key,
+ const typename Collection::key_type& key,
const Arg& arg) {
pair<typename Collection::iterator, bool> ret =
collection->insert(
typename Collection::value_type(
key,
- static_cast<typename Collection::value_type::second_type>(NULL)));
+ static_cast<typename Collection::mapped_type>(NULL)));
if (ret.second) {
// This helper is needed to 'extract' the Value type from the type of the
// container value, which is (Value*).
@@ -497,12 +557,12 @@ LookupOrInsertNew(Collection* const collection,
// LookupOrInsertNewLinkedPtr, this function returns the shared_ptr instead of
// the raw pointer. Value::element_type must be default constructable.
template <class Collection>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsertNewSharedPtr(
Collection* const collection,
- const typename Collection::value_type::first_type& key) {
- typedef typename Collection::value_type::second_type SharedPtr;
- typedef typename Collection::value_type::second_type::element_type Element;
+ const typename Collection::key_type& key) {
+ typedef typename Collection::mapped_type SharedPtr;
+ typedef typename Collection::mapped_type::element_type Element;
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, SharedPtr()));
if (ret.second) {
@@ -517,13 +577,13 @@ LookupOrInsertNewSharedPtr(
// here. On the other hand it does not matter how expensive the construction of
// the actual stored value is, as that only occurs if necessary.
template <class Collection, class Arg>
-typename Collection::value_type::second_type&
+typename Collection::mapped_type&
LookupOrInsertNewSharedPtr(
Collection* const collection,
- const typename Collection::value_type::first_type& key,
+ const typename Collection::key_type& key,
const Arg& arg) {
- typedef typename Collection::value_type::second_type SharedPtr;
- typedef typename Collection::value_type::second_type::element_type Element;
+ typedef typename Collection::mapped_type SharedPtr;
+ typedef typename Collection::mapped_type::element_type Element;
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, SharedPtr()));
if (ret.second) {
@@ -545,9 +605,9 @@ LookupOrInsertNewSharedPtr(
// address of an already existing value, rather than updating it.
template <class Collection>
bool UpdateReturnCopy(Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& value,
- typename Collection::value_type::second_type* previous) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& value,
+ typename Collection::mapped_type* previous) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
if (!ret.second) {
@@ -565,7 +625,7 @@ bool UpdateReturnCopy(Collection* const collection,
template <class Collection>
bool UpdateReturnCopy(Collection* const collection,
const typename Collection::value_type& vt,
- typename Collection::value_type::second_type* previous) {
+ typename Collection::mapped_type* previous) {
pair<typename Collection::iterator, bool> ret =
collection->insert(vt);
if (!ret.second) {
@@ -587,7 +647,7 @@ bool UpdateReturnCopy(Collection* const collection,
// twice. Unlike UpdateReturnCopy this also does not come with the issue of an
// undefined previous* in case new data was inserted.
template <class Collection>
-typename Collection::value_type::second_type* const
+typename Collection::mapped_type* const
InsertOrReturnExisting(Collection* const collection,
const typename Collection::value_type& vt) {
pair<typename Collection::iterator, bool> ret = collection->insert(vt);
@@ -600,11 +660,11 @@ InsertOrReturnExisting(Collection* const collection,
// Same as above, except for explicit key and data.
template <class Collection>
-typename Collection::value_type::second_type* const
+typename Collection::mapped_type* const
InsertOrReturnExisting(
Collection* const collection,
- const typename Collection::value_type::first_type& key,
- const typename Collection::value_type::second_type& data) {
+ const typename Collection::key_type& key,
+ const typename Collection::mapped_type& data) {
return InsertOrReturnExisting(collection,
typename Collection::value_type(key, data));
}
@@ -638,15 +698,17 @@ void ReverseMap(const Collection& collection,
// if (value_ptr.get())
// value_ptr->DoSomething();
//
+// Note: if 'collection' is a multimap, this will only erase and return the
+// first value.
template <class Collection>
-typename Collection::value_type::second_type EraseKeyReturnValuePtr(
+typename Collection::mapped_type EraseKeyReturnValuePtr(
Collection* const collection,
- const typename Collection::value_type::first_type& key) {
- typename Collection::iterator it = collection->find(key);
+ const typename Collection::key_type& key) {
+ auto it = collection->find(key);
if (it == collection->end()) {
- return NULL;
+ return typename Collection::mapped_type();
}
- typename Collection::value_type::second_type v = it->second;
+ typename Collection::mapped_type v = std::move(it->second);
collection->erase(it);
return v;
}
@@ -738,10 +800,59 @@ void AppendValuesFromMap(const MapContainer& map_container,
if (value_container->empty()) {
value_container->reserve(map_container.size());
}
- for (typename MapContainer::const_iterator it = map_container.begin();
- it != map_container.end(); ++it) {
- value_container->push_back(it->second);
+ for (const auto& entry : map_container) {
+ value_container->push_back(entry.second);
}
}
+// Compute and insert new value if it's absent from the map. Return a pair with a reference to the
+// value and a bool indicating whether it was absent at first.
+//
+// This inspired on a similar java construct (url split in two lines):
+// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html
+// #computeIfAbsent-K-java.util.function.Function
+//
+// It takes a reference to the key and a lambda function. If the key exists in the map, returns
+// a pair with a pointer to the current value and 'false'. If the key does not exist in the map,
+// it uses the lambda function to create a value, inserts it into the map, and returns a pair with
+// a pointer to the new value and 'true'.
+//
+// Example usage:
+//
+// auto result = ComputeIfAbsentReturnAbsense(&my_collection,
+// my_key,
+// [] { return new_value; });
+// MyValue* const value = result.first;
+// if (result.second) ....
+//
+template <class MapContainer, typename Function>
+pair<typename MapContainer::mapped_type* const, bool>
+ComputeIfAbsentReturnAbsense(MapContainer* container,
+ const typename MapContainer::key_type& key,
+ Function compute_func) {
+ typename MapContainer::iterator iter = container->find(key);
+ bool new_value = iter == container->end();
+ if (new_value) {
+ pair<typename MapContainer::iterator, bool> result = container->emplace(key, compute_func());
+ DCHECK(result.second) << "duplicate key: " << key;
+ iter = result.first;
+ }
+ return make_pair(&iter->second, new_value);
+};
+
+// Like the above but doesn't return a pair, just returns a pointer to the value.
+// Example usage:
+//
+// MyValue* const value = ComputeIfAbsent(&my_collection,
+// my_key,
+// [] { return new_value; });
+//
+template <class MapContainer, typename Function>
+typename MapContainer::mapped_type* const
+ComputeIfAbsent(MapContainer* container,
+ const typename MapContainer::key_type& key,
+ Function compute_func) {
+ return ComputeIfAbsentReturnAbsense(container, key, compute_func).first;
+};
+
#endif // UTIL_GTL_MAP_UTIL_H_
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/mathlimits.cc
----------------------------------------------------------------------
diff --git a/be/src/gutil/mathlimits.cc b/be/src/gutil/mathlimits.cc
index 0311d0d..dcc261d 100644
--- a/be/src/gutil/mathlimits.cc
+++ b/be/src/gutil/mathlimits.cc
@@ -1,24 +1,29 @@
// Copyright 2005 Google Inc.
//
-// Licensed 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
+// 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
+// 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.
+// 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.
//
// ---
//
//
-#include "gutil/mathlimits.h"
+#include "kudu/gutil/mathlimits.h"
-#include "gutil/integral_types.h"
+#include "kudu/gutil/integral_types.h"
// MSVC++ 2005 thinks the header declaration was a definition, and
// erroneously flags these as a duplicate definition.
@@ -107,9 +112,6 @@ DEF_UNSIGNED_INT_LIMITS(uint16)
DEF_UNSIGNED_INT_LIMITS(uint32)
DEF_UNSIGNED_INT_LIMITS(uint64)
-DEF_SIGNED_INT_LIMITS(long int)
-DEF_UNSIGNED_INT_LIMITS(unsigned long int)
-
DEF_FP_LIMITS(float, FLT)
DEF_FP_LIMITS(double, DBL)
DEF_FP_LIMITS(long double, LDBL);
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/mathlimits.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/mathlimits.h b/be/src/gutil/mathlimits.h
index 48f1d8e..9d69733 100644
--- a/be/src/gutil/mathlimits.h
+++ b/be/src/gutil/mathlimits.h
@@ -1,16 +1,21 @@
// Copyright 2005 Google Inc.
//
-// Licensed 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
+// 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
+// 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.
+// 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.
//
// ---
//
@@ -29,6 +34,7 @@
#include <math.h>
#include <string.h>
#include <cfloat>
+#include <cmath>
// ========================================================================= //
@@ -203,11 +209,11 @@ DECL_UNSIGNED_INT_LIMITS(unsigned long long int)
static bool IsNegInf(const Type x) { return _fpclass(x) == _FPCLASS_NINF; }
#else
#define DECL_FP_LIMIT_FUNCS \
- static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \
- static bool IsNaN(const Type x) { return isnan(x); } \
- static bool IsInf(const Type x) { return isinf(x); } \
- static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \
- static bool IsNegInf(const Type x) { return isinf(x) && x < 0; }
+ static bool IsFinite(const Type x) { return !std::isinf(x) && !std::isnan(x); } \
+ static bool IsNaN(const Type x) { return std::isnan(x); } \
+ static bool IsInf(const Type x) { return std::isinf(x); } \
+ static bool IsPosInf(const Type x) { return std::isinf(x) && x > 0; } \
+ static bool IsNegInf(const Type x) { return std::isinf(x) && x < 0; }
#endif
// We can't put floating-point constant values in the header here because
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/move.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/move.h b/be/src/gutil/move.h
index d2cd3df..1765108 100644
--- a/be/src/gutil/move.h
+++ b/be/src/gutil/move.h
@@ -105,8 +105,8 @@
//
//
// Foo f(MakeFoo()); // R-value so alternate conversion executed.
-// Foo f_copy(f.Pass()); // R-value so alternate conversion executed.
-// f = f_copy.Pass(); // R-value so alternate conversion executed.
+// Foo f_copy(std::move(f)); // R-value so alternate conversion executed.
+// f = std::move(f_copy); // R-value so alternate conversion executed.
//
//
// IMPLEMENTATION SUBTLETIES WITH RValue
@@ -136,6 +136,16 @@
// choose the one that adheres to the standard.
//
//
+// WHY HAVE typedef void MoveOnlyTypeForCPP03
+//
+// Callback<>/Bind() needs to understand movable-but-not-copyable semantics
+// to call .Pass() appropriately when it is expected to transfer the value.
+// The cryptic typedef MoveOnlyTypeForCPP03 is added to make this check
+// easy and automatic in helper templates for Callback<>/Bind().
+// See IsMoveOnlyType template and its usage in base/callback_internal.h
+// for more details.
+//
+//
// COMPARED TO C++11
//
// In C++11, you would implement this functionality using an r-value reference
@@ -202,6 +212,7 @@
public: \
operator rvalue_type() { return rvalue_type(this); } \
type Pass() { return type(rvalue_type(this)); } \
+ typedef void MoveOnlyTypeForCPP03; \
private:
#endif // BASE_MOVE_H_
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/once.cc
----------------------------------------------------------------------
diff --git a/be/src/gutil/once.cc b/be/src/gutil/once.cc
index a50c34a..1b97f8f 100644
--- a/be/src/gutil/once.cc
+++ b/be/src/gutil/once.cc
@@ -1,10 +1,10 @@
// Copyright 2008 Google Inc. All Rights Reserved.
#include <glog/logging.h>
-#include "gutil/logging-inl.h"
-#include "gutil/once.h"
-#include "gutil/dynamic_annotations.h"
-#include "gutil/spinlock_internal.h"
+#include "kudu/gutil/logging-inl.h"
+#include "kudu/gutil/once.h"
+#include "kudu/gutil/dynamic_annotations.h"
+#include "kudu/gutil/spinlock_internal.h"
// All modifications to a GoogleOnceType occur inside GoogleOnceInternalInit.
// The fast path reads the variable with an acquire-load..
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/once.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/once.h b/be/src/gutil/once.h
index c81e871..ff161c5 100644
--- a/be/src/gutil/once.h
+++ b/be/src/gutil/once.h
@@ -24,12 +24,12 @@
#ifndef BASE_ONCE_H_
#define BASE_ONCE_H_
-#include "gutil/atomicops.h"
-#include "gutil/integral_types.h"
-#include "gutil/dynamic_annotations.h"
-#include "gutil/macros.h"
-#include "gutil/port.h"
-#include "gutil/type_traits.h"
+#include "kudu/gutil/atomicops.h"
+#include "kudu/gutil/integral_types.h"
+#include "kudu/gutil/dynamic_annotations.h"
+#include "kudu/gutil/macros.h"
+#include "kudu/gutil/port.h"
+#include "kudu/gutil/type_traits.h"
// The following enum values are not for use by clients
enum {
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/paranoid.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/paranoid.h b/be/src/gutil/paranoid.h
index 53159a0..01f34b7 100644
--- a/be/src/gutil/paranoid.h
+++ b/be/src/gutil/paranoid.h
@@ -7,7 +7,8 @@
#define BASE_PARANOID_H_
#include <glog/logging.h>
-#include "gutil/logging-inl.h"
+
+#include "kudu/gutil/logging-inl.h"
// Sanitize a bool value which might be sour.
//
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/port.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/port.h b/be/src/gutil/port.h
index c9f19f4..6222cca 100644
--- a/be/src/gutil/port.h
+++ b/be/src/gutil/port.h
@@ -18,7 +18,7 @@
#include <malloc.h> // for memalign()
#endif
-#include "gutil/integral_types.h"
+#include "kudu/gutil/integral_types.h"
// Must happens before inttypes.h inclusion */
#if defined(__APPLE__)
@@ -223,66 +223,6 @@ typedef int uid_t;
// Linux has this in <linux/errno.h>
#define EXFULL ENOMEM // not really that great a translation...
-// Mach-O supports sections (albeit with small names), but doesn't have
-// vars at the beginning and end. Instead you should call the function
-// getsectdata("__DATA", name, &size).
-#define HAVE_ATTRIBUTE_SECTION 1
-
-// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
-// be placed into whatever section its caller is placed into.
-#define ATTRIBUTE_SECTION(name) \
- __attribute__ ((section ("__DATA, " #name))) __attribute__ ((noinline))
-
-#define ENUM_DYLD_BOOL // so that we don't pollute the global namespace
-extern "C" {
- #include <mach-o/getsect.h>
- #include <mach-o/dyld.h>
-}
-class AssignAttributeStartEnd {
- public:
- AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {
- // Find out what dynamic library name is defined in
- for (int i = _dyld_image_count() - 1; i >= 0; --i) {
- const mach_header* hdr = _dyld_get_image_header(i);
- uint32_t len;
- *pstart = getsectdatafromheader(hdr, "__DATA", name, &len);
- if (*pstart) { // NULL if not defined in this dynamic library
- *pstart += _dyld_get_image_vmaddr_slide(i); // correct for reloc
- *pend = *pstart + len;
- return;
- }
- }
- // If we get here, not defined in a dll at all. See if defined statically.
- unsigned long len; // don't ask me why this type isn't uint32_t too...
- *pstart = getsectdata("__DATA", name, &len);
- *pend = *pstart + len;
- }
-};
-
-// 1) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique
-// name. You want to make sure this is executed before any
-// DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them
-// in the same .cc file. Put this call at the global level.
-// 2) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in
-// multiple places to help ensure execution before any
-// DECLARE_ATTRIBUTE_SECTION_VARS. You must have at least one
-// DEFINE, but you can have many INITs. Put each in its own scope.
-// 3) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using
-// ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.
-// Put this call at the global level.
-#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
- extern char* __start_##name; \
- extern char* __stop_##name;
-
-#define INIT_ATTRIBUTE_SECTION_VARS(name) \
- DECLARE_ATTRIBUTE_SECTION_VARS(name); \
- static const AssignAttributeStartEnd __assign_##name( \
- #name, &__start_##name, &__stop_##name)
-
-#define DEFINE_ATTRIBUTE_SECTION_VARS(name) \
- char* __start_##name, *__stop_##name; \
- INIT_ATTRIBUTE_SECTION_VARS(name)
-
// Darwin doesn't have strnlen. No comment.
inline size_t strnlen(const char *s, size_t maxlen) {
const char* end = (const char *)memchr(s, '\0', maxlen);
@@ -434,6 +374,17 @@ inline void* memrchr(const void* bytes, int find_char, size_t len) {
#define ATTRIBUTE_WEAK __attribute__ ((weak))
#define HAVE_ATTRIBUTE_WEAK 1
+// For deprecated functions or variables, generate a warning at usage sites.
+// Verified to work as early as GCC 3.1.1 and clang 3.2 (so we'll assume any
+// clang is new enough).
+#if defined(__clang__) || \
+ (defined(COMPILER_GCC) && \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 30200)
+#define ATTRIBUTE_DEPRECATED(msg) __attribute__ ((deprecated (msg) ))
+#else
+#define ATTRIBUTE_DEPRECATED(msg)
+#endif
+
// Tell the compiler to use "initial-exec" mode for a thread-local variable.
// See http://people.redhat.com/drepper/tls.pdf for the gory details.
#define ATTRIBUTE_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
@@ -462,54 +413,20 @@ inline void* memrchr(const void* bytes, int find_char, size_t len) {
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
#endif
+// Tell ThreadSanitizer to ignore a given function. This can dramatically reduce
+// the running time and memory requirements for racy code when TSAN is active.
+// GCC does not support this attribute at the time of this writing (GCC 4.8).
+#if defined(__llvm__)
+#define ATTRIBUTE_NO_SANITIZE_THREAD \
+ __attribute__((no_sanitize_thread))
+#else
+#define ATTRIBUTE_NO_SANITIZE_THREAD
+#endif
#ifndef HAVE_ATTRIBUTE_SECTION // may have been pre-set to 0, e.g. for Darwin
#define HAVE_ATTRIBUTE_SECTION 1
#endif
-#if HAVE_ATTRIBUTE_SECTION // define section support for the case of GCC
-
-//
-// Tell the compiler/linker to put a given function into a section and define
-// "__start_ ## name" and "__stop_ ## name" symbols to bracket the section.
-// Sections can not span more than none compilation unit.
-// This functionality is supported by GNU linker.
-// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
-// be placed into whatever section its caller is placed into.
-//
-#ifndef ATTRIBUTE_SECTION
-#define ATTRIBUTE_SECTION(name) \
- __attribute__ ((section (#name))) __attribute__ ((noinline))
-#endif
-
-//
-// Weak section declaration to be used as a global declaration
-// for ATTRIBUTE_SECTION_START|STOP(name) to compile and link
-// even without functions with ATTRIBUTE_SECTION(name).
-// DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's
-// a no-op on ELF but not on Mach-O.
-//
-#ifndef DECLARE_ATTRIBUTE_SECTION_VARS
-#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
- extern char __start_##name[] ATTRIBUTE_WEAK; \
- extern char __stop_##name[] ATTRIBUTE_WEAK
-#endif
-#ifndef DEFINE_ATTRIBUTE_SECTION_VARS
-#define INIT_ATTRIBUTE_SECTION_VARS(name)
-#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
-#endif
-
-//
-// Return void* pointers to start/end of a section of code with
-// functions having ATTRIBUTE_SECTION(name).
-// Returns 0 if no such functions exits.
-// One must DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and link.
-//
-#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
-#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
-
-#endif // HAVE_ATTRIBUTE_SECTION
-
//
// The legacy prod71 libc does not provide the stack alignment required for use
// of SSE intrinsics. In order to properly use the intrinsics you need to use
@@ -551,6 +468,40 @@ inline void* memrchr(const void* bytes, int find_char, size_t len) {
#define MUST_USE_RESULT
#endif
+// Annotate a virtual method indicating it must be overriding a virtual
+// method in the parent class.
+// Use like:
+// virtual void foo() OVERRIDE;
+#if defined(COMPILER_MSVC)
+#define OVERRIDE override
+#elif defined(__clang__)
+#define OVERRIDE override
+#elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700
+// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled.
+#define OVERRIDE override
+#else
+#define OVERRIDE
+#endif
+
+// Annotate a virtual method indicating that subclasses must not override it,
+// or annotate a class to indicate that it cannot be subclassed.
+// Use like:
+// virtual void foo() FINAL;
+// class B FINAL : public A {};
+#if defined(COMPILER_MSVC)
+// TODO(jered): Change this to "final" when chromium no longer uses MSVC 2010.
+#define FINAL sealed
+#elif defined(__clang__)
+#define FINAL final
+#elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700
+// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled.
+#define FINAL final
+#else
+#define FINAL
+#endif
+
#if defined(__GNUC__)
// Defined behavior on some of the uarchs:
// PREFETCH_HINT_T0:
@@ -570,7 +521,7 @@ enum PrefetchHint {
#endif
extern inline void prefetch(const char *x, int hint) {
-#if defined(__llvm__) || defined(__INTEL_COMPILER)
+#if defined(__llvm__)
// In the gcc version of prefetch(), hint is only a constant _after_ inlining
// (assumed to have been successful). llvm views things differently, and
// checks constant-ness _before_ inlining. This leads to compilation errors
@@ -714,7 +665,6 @@ inline void aligned_free(void *aligned_memory) {
#define ATTRIBUTE_INITIAL_EXEC
#define ATTRIBUTE_NONNULL(arg_index)
#define ATTRIBUTE_NORETURN
-#define HAVE_ATTRIBUTE_SECTION 0
#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#define MUST_USE_RESULT
@@ -798,18 +748,6 @@ struct AlignType { typedef char result[Size]; };
#define ALIGNED_CHAR_ARRAY ALIGNED_CHAR_ARRAY_is_not_available_without_Cplusplus
#endif // __cplusplus
-#if !HAVE_ATTRIBUTE_SECTION // provide dummy definitions
-
-#define ATTRIBUTE_SECTION(name)
-#define INIT_ATTRIBUTE_SECTION_VARS(name)
-#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
-#define DECLARE_ATTRIBUTE_SECTION_VARS(name)
-#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
-#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
-
-#endif // !HAVE_ATTRIBUTE_SECTION
-
-
#ifdef _MSC_VER /* if Visual C++ */
// This compiler flag can be easily overlooked on MSVC.
@@ -998,7 +936,7 @@ inline int isinf(double x) {
return 0;
}
-// #include "conflict-signal.h"
+// #include "kudu/conflict-signal.h"
typedef void (*sig_t)(int);
// These actually belong in errno.h but there's a name confilict in errno
@@ -1042,7 +980,7 @@ typedef short int16_t;
#endif // _MSC_VER
#ifdef STL_MSVC // not always the same as _MSC_VER
-#include "base/port_hash.h"
+#include "kudu/base/port_hash.h"
#else
struct PortableHashBase { };
#endif
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/proto/types.pb.cc
----------------------------------------------------------------------
diff --git a/be/src/gutil/proto/types.pb.cc b/be/src/gutil/proto/types.pb.cc
deleted file mode 100644
index b3ebe01..0000000
--- a/be/src/gutil/proto/types.pb.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-
-#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
-#include "gutil/proto/types.pb.h"
-
-#include <algorithm>
-
-#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_lite_inl.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/reflection_ops.h>
-#include <google/protobuf/wire_format.h>
-// @@protoc_insertion_point(includes)
-
-namespace common {
-
-namespace {
-
-const ::google::protobuf::EnumDescriptor* DataType_descriptor_ = NULL;
-
-} // namespace
-
-
-void protobuf_AssignDesc_gutil_2fproto_2ftypes_2eproto() {
- protobuf_AddDesc_gutil_2fproto_2ftypes_2eproto();
- const ::google::protobuf::FileDescriptor* file =
- ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
- "gutil/proto/types.proto");
- GOOGLE_CHECK(file != NULL);
- DataType_descriptor_ = file->enum_type(0);
-}
-
-namespace {
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
-inline void protobuf_AssignDescriptorsOnce() {
- ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
- &protobuf_AssignDesc_gutil_2fproto_2ftypes_2eproto);
-}
-
-void protobuf_RegisterTypes(const ::std::string&) {
- protobuf_AssignDescriptorsOnce();
-}
-
-} // namespace
-
-void protobuf_ShutdownFile_gutil_2fproto_2ftypes_2eproto() {
-}
-
-void protobuf_AddDesc_gutil_2fproto_2ftypes_2eproto() {
- static bool already_here = false;
- if (already_here) return;
- already_here = true;
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
- "\n\027gutil/proto/types.proto\022\006common*\247\001\n\010Da"
- "taType\022\t\n\005INT32\020\001\022\t\n\005INT64\020\002\022\n\n\006UINT32\020\010"
- "\022\n\n\006UINT64\020\003\022\t\n\005FLOAT\020\t\022\n\n\006DOUBLE\020\005\022\010\n\004B"
- "OOL\020\006\022\010\n\004DATE\020\n\022\014\n\010DATETIME\020\004\022\n\n\006STRING\020"
- "\000\022\n\n\006BINARY\020\007\022\r\n\tDATA_TYPE\020\013\022\r\n\tNULL_TYP"
- "E\020\014B4\n%com.google.datawarehouse.common.p"
- "rotoB\013CommonEnums", 257);
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
- "gutil/proto/types.proto", &protobuf_RegisterTypes);
- ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_gutil_2fproto_2ftypes_2eproto);
-}
-
-// Force AddDescriptors() to be called at static initialization time.
-struct StaticDescriptorInitializer_gutil_2fproto_2ftypes_2eproto {
- StaticDescriptorInitializer_gutil_2fproto_2ftypes_2eproto() {
- protobuf_AddDesc_gutil_2fproto_2ftypes_2eproto();
- }
-} static_descriptor_initializer_gutil_2fproto_2ftypes_2eproto_;
-
-const ::google::protobuf::EnumDescriptor* DataType_descriptor() {
- protobuf_AssignDescriptorsOnce();
- return DataType_descriptor_;
-}
-bool DataType_IsValid(int value) {
- switch(value) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- return true;
- default:
- return false;
- }
-}
-
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace common
-
-// @@protoc_insertion_point(global_scope)
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/proto/types.pb.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/proto/types.pb.h b/be/src/gutil/proto/types.pb.h
deleted file mode 100644
index 88f6551..0000000
--- a/be/src/gutil/proto/types.pb.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: gutil/proto/types.proto
-
-#ifndef PROTOBUF_gutil_2fproto_2ftypes_2eproto__INCLUDED
-#define PROTOBUF_gutil_2fproto_2ftypes_2eproto__INCLUDED
-
-#include <string>
-
-#include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 2004000
-#error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please update
-#error your headers.
-#endif
-#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
-#error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please
-#error regenerate this file with a newer version of protoc.
-#endif
-
-#include <google/protobuf/generated_message_util.h>
-#include <google/protobuf/repeated_field.h>
-#include <google/protobuf/extension_set.h>
-#include <google/protobuf/generated_message_reflection.h>
-// @@protoc_insertion_point(includes)
-
-namespace common {
-
-// Internal implementation detail -- do not call these.
-void protobuf_AddDesc_gutil_2fproto_2ftypes_2eproto();
-void protobuf_AssignDesc_gutil_2fproto_2ftypes_2eproto();
-void protobuf_ShutdownFile_gutil_2fproto_2ftypes_2eproto();
-
-
-enum DataType {
- INT32 = 1,
- INT64 = 2,
- UINT32 = 8,
- UINT64 = 3,
- FLOAT = 9,
- DOUBLE = 5,
- BOOL = 6,
- DATE = 10,
- DATETIME = 4,
- STRING = 0,
- BINARY = 7,
- DATA_TYPE = 11,
- NULL_TYPE = 12
-};
-bool DataType_IsValid(int value);
-const DataType DataType_MIN = STRING;
-const DataType DataType_MAX = NULL_TYPE;
-const int DataType_ARRAYSIZE = DataType_MAX + 1;
-
-const ::google::protobuf::EnumDescriptor* DataType_descriptor();
-inline const ::std::string& DataType_Name(DataType value) {
- return ::google::protobuf::internal::NameOfEnum(
- DataType_descriptor(), value);
-}
-inline bool DataType_Parse(
- const ::std::string& name, DataType* value) {
- return ::google::protobuf::internal::ParseNamedEnum<DataType>(
- DataType_descriptor(), name, value);
-}
-// ===================================================================
-
-
-// ===================================================================
-
-
-// ===================================================================
-
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace common
-
-#ifndef SWIG
-namespace google {
-namespace protobuf {
-
-template <>
-inline const EnumDescriptor* GetEnumDescriptor< common::DataType>() {
- return common::DataType_descriptor();
-}
-
-} // namespace google
-} // namespace protobuf
-#endif // SWIG
-
-// @@protoc_insertion_point(global_scope)
-
-#endif // PROTOBUF_gutil_2fproto_2ftypes_2eproto__INCLUDED
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/proto/types.proto
----------------------------------------------------------------------
diff --git a/be/src/gutil/proto/types.proto b/be/src/gutil/proto/types.proto
deleted file mode 100644
index aae0557..0000000
--- a/be/src/gutil/proto/types.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-
-option java_package = "com.google.datawarehouse.common.proto";
-option java_outer_classname = "CommonEnums";
-
-package common;
-
-// Supported types.
-enum DataType {
- INT32 = 1;
- INT64 = 2;
- UINT32 = 8;
- UINT64 = 3;
- FLOAT = 9;
- DOUBLE = 5;
- BOOL = 6;
- DATE = 10; // Fixed-precision, daily granularity.
- DATETIME = 4; // Fixed-precision, microsecond granularity.
-
- STRING = 0;
- BINARY = 7;
-
- DATA_TYPE = 11; // For representing the DataType enum itself.
- NULL_TYPE = 12; // Untyped NULL literal.
-
- // Note: next available: 13
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/raw_scoped_refptr_mismatch_checker.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/raw_scoped_refptr_mismatch_checker.h b/be/src/gutil/raw_scoped_refptr_mismatch_checker.h
new file mode 100644
index 0000000..63e4e71
--- /dev/null
+++ b/be/src/gutil/raw_scoped_refptr_mismatch_checker.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef KUDU_GUTIL_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#define KUDU_GUTIL_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+
+#include <type_traits>
+
+#include "kudu/gutil/ref_counted.h"
+
+// It is dangerous to post a task with a T* argument where T is a subtype of
+// RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
+// object may already have been deleted since it was not held with a
+// scoped_refptr. Example: http://crbug.com/27191
+// The following set of traits are designed to generate a compile error
+// whenever this antipattern is attempted.
+
+namespace kudu {
+
+// This is a base internal implementation file used by task.h and callback.h.
+// Not for public consumption, so we wrap it in namespace internal.
+namespace internal {
+
+template <typename T>
+struct NeedsScopedRefptrButGetsRawPtr {
+#if defined(OS_WIN)
+ enum {
+ value = base::false_type::value
+ };
+#else
+ enum {
+ // Human readable translation: you needed to be a scoped_refptr if you are a
+ // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
+ // type.
+ value = (std::is_pointer<T>::value &&
+ (std::is_convertible<T, subtle::RefCountedBase*>::value ||
+ std::is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
+ };
+#endif
+};
+
+template <typename Params>
+struct ParamsUseScopedRefptrCorrectly {
+ enum { value = 0 };
+};
+
+template <>
+struct ParamsUseScopedRefptrCorrectly<std::tuple<>> {
+ enum { value = 1 };
+};
+
+template <typename Head, typename... Tail>
+struct ParamsUseScopedRefptrCorrectly<std::tuple<Head, Tail...>> {
+ enum { value = !NeedsScopedRefptrButGetsRawPtr<Head>::value &&
+ ParamsUseScopedRefptrCorrectly<std::tuple<Tail...>>::value };
+};
+
+} // namespace internal
+
+} // namespace kudu
+
+#endif // KUDU_GUTIL_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/ref_counted.cc
----------------------------------------------------------------------
diff --git a/be/src/gutil/ref_counted.cc b/be/src/gutil/ref_counted.cc
new file mode 100644
index 0000000..a15a1e2
--- /dev/null
+++ b/be/src/gutil/ref_counted.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "kudu/gutil/ref_counted.h"
+
+#include <glog/logging.h>
+#include "kudu/gutil/threading/thread_collision_warner.h"
+
+namespace kudu {
+
+namespace subtle {
+
+RefCountedBase::RefCountedBase()
+ : ref_count_(0)
+#ifndef NDEBUG
+ , in_dtor_(false)
+#endif
+ {
+}
+
+RefCountedBase::~RefCountedBase() {
+#ifndef NDEBUG
+ DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
+#endif
+}
+
+void RefCountedBase::AddRef() const {
+ // TODO(maruel): Add back once it doesn't assert 500 times/sec.
+ // Current thread books the critical section "AddRelease" without release it.
+ // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
+#ifndef NDEBUG
+ DCHECK(!in_dtor_);
+#endif
+ ++ref_count_;
+}
+
+bool RefCountedBase::Release() const {
+ // TODO(maruel): Add back once it doesn't assert 500 times/sec.
+ // Current thread books the critical section "AddRelease" without release it.
+ // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
+#ifndef NDEBUG
+ DCHECK(!in_dtor_);
+#endif
+ if (--ref_count_ == 0) {
+#ifndef NDEBUG
+ in_dtor_ = true;
+#endif
+ return true;
+ }
+ return false;
+}
+
+bool RefCountedThreadSafeBase::HasOneRef() const {
+ return base::RefCountIsOne(
+ &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_);
+}
+
+RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) {
+#ifndef NDEBUG
+ in_dtor_ = false;
+#endif
+}
+
+RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
+#ifndef NDEBUG
+ DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
+ "calling Release()";
+#endif
+}
+
+void RefCountedThreadSafeBase::AddRef() const {
+#ifndef NDEBUG
+ DCHECK(!in_dtor_);
+#endif
+ base::RefCountInc(&ref_count_);
+}
+
+bool RefCountedThreadSafeBase::Release() const {
+#ifndef NDEBUG
+ DCHECK(!in_dtor_);
+ DCHECK(!base::RefCountIsZero(&ref_count_));
+#endif
+ if (!base::RefCountDec(&ref_count_)) {
+#ifndef NDEBUG
+ in_dtor_ = true;
+#endif
+ return true;
+ }
+ return false;
+}
+
+} // namespace subtle
+
+} // namespace kudu
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/ref_counted.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/ref_counted.h b/be/src/gutil/ref_counted.h
new file mode 100644
index 0000000..8b6a553
--- /dev/null
+++ b/be/src/gutil/ref_counted.h
@@ -0,0 +1,354 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MEMORY_REF_COUNTED_H_
+#define BASE_MEMORY_REF_COUNTED_H_
+
+#include <cassert>
+
+#include "kudu/gutil/atomic_refcount.h"
+#include "kudu/gutil/port.h"
+#include "kudu/gutil/threading/thread_collision_warner.h"
+
+namespace kudu {
+namespace subtle {
+
+typedef Atomic32 AtomicRefCount;
+
+class RefCountedBase {
+ public:
+ bool HasOneRef() const { return ref_count_ == 1; }
+
+ protected:
+ RefCountedBase();
+ ~RefCountedBase();
+
+ void AddRef() const;
+
+ // Returns true if the object should self-delete.
+ bool Release() const;
+
+ private:
+ mutable int ref_count_;
+#ifndef NDEBUG
+ mutable bool in_dtor_;
+#endif
+
+ DFAKE_MUTEX(add_release_);
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
+};
+
+class RefCountedThreadSafeBase {
+ public:
+ bool HasOneRef() const;
+
+ protected:
+ RefCountedThreadSafeBase();
+ ~RefCountedThreadSafeBase();
+
+ void AddRef() const;
+
+ // Returns true if the object should self-delete.
+ bool Release() const;
+
+ private:
+ mutable AtomicRefCount ref_count_;
+#ifndef NDEBUG
+ mutable bool in_dtor_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
+};
+
+} // namespace subtle
+
+//
+// A base class for reference counted classes. Otherwise, known as a cheap
+// knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
+// class from it like so:
+//
+// class MyFoo : public RefCounted<MyFoo> {
+// ...
+// private:
+// friend class RefCounted<MyFoo>;
+// ~MyFoo();
+// };
+//
+// You should always make your destructor private, to avoid any code deleting
+// the object accidently while there are references to it.
+template <class T>
+class RefCounted : public subtle::RefCountedBase {
+ public:
+ RefCounted() {}
+
+ void AddRef() const {
+ subtle::RefCountedBase::AddRef();
+ }
+
+ void Release() const {
+ if (subtle::RefCountedBase::Release()) {
+ delete static_cast<const T*>(this);
+ }
+ }
+
+ protected:
+ ~RefCounted() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
+};
+
+// Forward declaration.
+template <class T, typename Traits> class RefCountedThreadSafe;
+
+// Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
+// count reaches 0. Overload to delete it on a different thread etc.
+template<typename T>
+struct DefaultRefCountedThreadSafeTraits {
+ static void Destruct(const T* x) {
+ // Delete through RefCountedThreadSafe to make child classes only need to be
+ // friend with RefCountedThreadSafe instead of this struct, which is an
+ // implementation detail.
+ RefCountedThreadSafe<T,
+ DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
+ }
+};
+
+//
+// A thread-safe variant of RefCounted<T>
+//
+// class MyFoo : public RefCountedThreadSafe<MyFoo> {
+// ...
+// };
+//
+// If you're using the default trait, then you should add compile time
+// asserts that no one else is deleting your object. i.e.
+// private:
+// friend class RefCountedThreadSafe<MyFoo>;
+// ~MyFoo();
+template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
+class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
+ public:
+ RefCountedThreadSafe() {}
+
+ void AddRef() const {
+ subtle::RefCountedThreadSafeBase::AddRef();
+ }
+
+ void Release() const {
+ if (subtle::RefCountedThreadSafeBase::Release()) {
+ Traits::Destruct(static_cast<const T*>(this));
+ }
+ }
+
+ protected:
+ ~RefCountedThreadSafe() {}
+
+ private:
+ friend struct DefaultRefCountedThreadSafeTraits<T>;
+ static void DeleteInternal(const T* x) { delete x; }
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
+};
+
+//
+// A thread-safe wrapper for some piece of data so we can place other
+// things in scoped_refptrs<>.
+//
+template<typename T>
+class RefCountedData
+ : public kudu::RefCountedThreadSafe< kudu::RefCountedData<T> > {
+ public:
+ RefCountedData() : data() {}
+ RefCountedData(const T& in_value) : data(in_value) {}
+
+ T data;
+
+ private:
+ friend class kudu::RefCountedThreadSafe<kudu::RefCountedData<T> >;
+ ~RefCountedData() {}
+};
+
+} // namespace kudu
+
+//
+// A smart pointer class for reference counted objects. Use this class instead
+// of calling AddRef and Release manually on a reference counted object to
+// avoid common memory leaks caused by forgetting to Release an object
+// reference. Sample usage:
+//
+// class MyFoo : public RefCounted<MyFoo> {
+// ...
+// };
+//
+// void some_function() {
+// scoped_refptr<MyFoo> foo = new MyFoo();
+// foo->Method(param);
+// // |foo| is released when this function returns
+// }
+//
+// void some_other_function() {
+// scoped_refptr<MyFoo> foo = new MyFoo();
+// ...
+// foo = NULL; // explicitly releases |foo|
+// ...
+// if (foo)
+// foo->Method(param);
+// }
+//
+// The above examples show how scoped_refptr<T> acts like a pointer to T.
+// Given two scoped_refptr<T> classes, it is also possible to exchange
+// references between the two objects, like so:
+//
+// {
+// scoped_refptr<MyFoo> a = new MyFoo();
+// scoped_refptr<MyFoo> b;
+//
+// b.swap(a);
+// // now, |b| references the MyFoo object, and |a| references NULL.
+// }
+//
+// To make both |a| and |b| in the above example reference the same MyFoo
+// object, simply use the assignment operator:
+//
+// {
+// scoped_refptr<MyFoo> a = new MyFoo();
+// scoped_refptr<MyFoo> b;
+//
+// b = a;
+// // now, |a| and |b| each own a reference to the same MyFoo object.
+// }
+//
+template <class T>
+class scoped_refptr {
+ public:
+ typedef T element_type;
+
+ scoped_refptr() : ptr_(NULL) {
+ }
+
+ scoped_refptr(T* p) : ptr_(p) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ template <typename U>
+ scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ template <typename U>
+ scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) {
+ r.ptr_ = nullptr;
+ }
+
+ ~scoped_refptr() {
+ if (ptr_)
+ ptr_->Release();
+ }
+
+ T* get() const { return ptr_; }
+
+// The following is disabled in Cloudera's version of this file since it's
+// relatively dangerous. Chromium is planning on doing the same in their
+// tree, but hasn't done so yet. See http://code.google.com/p/chromium/issues/detail?id=110610
+#if SCOPED_REFPTR_ALLOW_IMPLICIT_CONVERSION_TO_PTR
+ // Allow scoped_refptr<C> to be used in boolean expression
+ // and comparison operations.
+ operator T*() const { return ptr_; }
+#else
+ typedef T* scoped_refptr::*Testable;
+ operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : NULL; }
+#endif
+
+ T* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+
+ scoped_refptr<T>& operator=(T* p) {
+ // AddRef first so that self assignment should work
+ if (p)
+ p->AddRef();
+ T* old_ptr = ptr_;
+ ptr_ = p;
+ if (old_ptr)
+ old_ptr->Release();
+ return *this;
+ }
+
+ scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
+ return *this = r.ptr_;
+ }
+
+ template <typename U>
+ scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
+ return *this = r.get();
+ }
+
+ scoped_refptr<T>& operator=(scoped_refptr<T>&& r) {
+ scoped_refptr<T>(r).swap(*this);
+ return *this;
+ }
+
+ template <typename U>
+ scoped_refptr<T>& operator=(scoped_refptr<U>&& r) {
+ scoped_refptr<T>(r).swap(*this);
+ return *this;
+ }
+
+ void swap(T** pp) {
+ T* p = ptr_;
+ ptr_ = *pp;
+ *pp = p;
+ }
+
+ void swap(scoped_refptr<T>& r) {
+ swap(&r.ptr_);
+ }
+
+ // Like gscoped_ptr::reset(), drops a reference on the currently held object
+ // (if any), and adds a reference to the passed-in object (if not NULL).
+ void reset(T* p = NULL) {
+ *this = p;
+ }
+
+ protected:
+ T* ptr_;
+
+ private:
+ template <typename U> friend class scoped_refptr;
+};
+
+// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
+// having to retype all the template arguments
+template <typename T>
+scoped_refptr<T> make_scoped_refptr(T* t) {
+ return scoped_refptr<T>(t);
+}
+
+// equal_to and hash implementations for templated scoped_refptrs suitable for
+// use with STL unordered_* containers.
+template <class T>
+struct ScopedRefPtrEqualToFunctor {
+ bool operator()(const scoped_refptr<T>& x, const scoped_refptr<T>& y) const {
+ return x.get() == y.get();
+ }
+};
+
+template <class T>
+struct ScopedRefPtrHashFunctor {
+ size_t operator()(const scoped_refptr<T>& p) const {
+ return reinterpret_cast<size_t>(p.get());
+ }
+};
+
+#endif // BASE_MEMORY_REF_COUNTED_H_
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/ref_counted_memory.cc
----------------------------------------------------------------------
diff --git a/be/src/gutil/ref_counted_memory.cc b/be/src/gutil/ref_counted_memory.cc
new file mode 100644
index 0000000..1d695d9
--- /dev/null
+++ b/be/src/gutil/ref_counted_memory.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "kudu/gutil/ref_counted_memory.h"
+
+#include <stdlib.h>
+
+#include <glog/logging.h>
+
+namespace kudu {
+
+bool RefCountedMemory::Equals(
+ const scoped_refptr<RefCountedMemory>& other) const {
+ return other.get() &&
+ size() == other->size() &&
+ (memcmp(front(), other->front(), size()) == 0);
+}
+
+RefCountedMemory::RefCountedMemory() {}
+
+RefCountedMemory::~RefCountedMemory() {}
+
+const unsigned char* RefCountedStaticMemory::front() const {
+ return data_;
+}
+
+size_t RefCountedStaticMemory::size() const {
+ return length_;
+}
+
+RefCountedStaticMemory::~RefCountedStaticMemory() {}
+
+RefCountedBytes::RefCountedBytes() {}
+
+RefCountedBytes::RefCountedBytes(std::vector<unsigned char> initializer)
+ : data_(std::move(initializer)) {}
+
+RefCountedBytes::RefCountedBytes(const unsigned char* p, size_t size)
+ : data_(p, p + size) {}
+
+RefCountedBytes* RefCountedBytes::TakeVector(
+ std::vector<unsigned char>* to_destroy) {
+ auto bytes = new RefCountedBytes;
+ bytes->data_.swap(*to_destroy);
+ return bytes;
+}
+
+const unsigned char* RefCountedBytes::front() const {
+ // STL will assert if we do front() on an empty vector, but calling code
+ // expects a NULL.
+ return size() ? &data_.front() : nullptr;
+}
+
+size_t RefCountedBytes::size() const {
+ return data_.size();
+}
+
+RefCountedBytes::~RefCountedBytes() {}
+
+RefCountedString::RefCountedString() {}
+
+RefCountedString::~RefCountedString() {}
+
+// static
+RefCountedString* RefCountedString::TakeString(std::string* to_destroy) {
+ auto self = new RefCountedString;
+ to_destroy->swap(self->data_);
+ return self;
+}
+
+const unsigned char* RefCountedString::front() const {
+ return data_.empty() ? nullptr :
+ reinterpret_cast<const unsigned char*>(data_.data());
+}
+
+size_t RefCountedString::size() const {
+ return data_.size();
+}
+
+RefCountedMallocedMemory::RefCountedMallocedMemory(
+ void* data, size_t length)
+ : data_(reinterpret_cast<unsigned char*>(data)), length_(length) {
+ DCHECK(data || length == 0);
+}
+
+const unsigned char* RefCountedMallocedMemory::front() const {
+ return length_ ? data_ : nullptr;
+}
+
+size_t RefCountedMallocedMemory::size() const {
+ return length_;
+}
+
+RefCountedMallocedMemory::~RefCountedMallocedMemory() {
+ free(data_);
+}
+
+} // namespace kudu
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/ref_counted_memory.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/ref_counted_memory.h b/be/src/gutil/ref_counted_memory.h
new file mode 100644
index 0000000..550a142
--- /dev/null
+++ b/be/src/gutil/ref_counted_memory.h
@@ -0,0 +1,150 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef KUDU_GUTIL_REF_COUNTED_MEMORY_H_
+#define KUDU_GUTIL_REF_COUNTED_MEMORY_H_
+
+#include <string>
+#include <vector>
+
+#include "kudu/gutil/macros.h"
+#include "kudu/gutil/ref_counted.h"
+#include "kudu/gutil/port.h"
+
+#ifndef BASE_EXPORT
+#define BASE_EXPORT
+#endif
+
+namespace kudu {
+
+// A generic interface to memory. This object is reference counted because one
+// of its two subclasses own the data they carry, and we need to have
+// heterogeneous containers of these two types of memory.
+class BASE_EXPORT RefCountedMemory
+ : public RefCountedThreadSafe<RefCountedMemory> {
+ public:
+ // Retrieves a pointer to the beginning of the data we point to. If the data
+ // is empty, this will return NULL.
+ virtual const unsigned char* front() const = 0;
+
+ // Size of the memory pointed to.
+ virtual size_t size() const = 0;
+
+ // Returns true if |other| is byte for byte equal.
+ bool Equals(const scoped_refptr<RefCountedMemory>& other) const;
+
+ // Handy method to simplify calling front() with a reinterpret_cast.
+ template<typename T> const T* front_as() const {
+ return reinterpret_cast<const T*>(front());
+ }
+
+ protected:
+ friend class RefCountedThreadSafe<RefCountedMemory>;
+ RefCountedMemory();
+ virtual ~RefCountedMemory();
+};
+
+// An implementation of RefCountedMemory, where the ref counting does not
+// matter.
+class BASE_EXPORT RefCountedStaticMemory : public RefCountedMemory {
+ public:
+ RefCountedStaticMemory()
+ : data_(NULL), length_(0) {}
+ RefCountedStaticMemory(const void* data, size_t length)
+ : data_(static_cast<const unsigned char*>(length ? data : NULL)),
+ length_(length) {}
+
+ // Overridden from RefCountedMemory:
+ virtual const unsigned char* front() const OVERRIDE;
+ virtual size_t size() const OVERRIDE;
+
+ private:
+ virtual ~RefCountedStaticMemory();
+
+ const unsigned char* data_;
+ size_t length_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedStaticMemory);
+};
+
+// An implementation of RefCountedMemory, where we own the data in a vector.
+class BASE_EXPORT RefCountedBytes : public RefCountedMemory {
+ public:
+ RefCountedBytes();
+
+ // Constructs a RefCountedBytes object by _copying_ from |initializer|.
+ explicit RefCountedBytes(std::vector<unsigned char> initializer);
+
+ // Constructs a RefCountedBytes object by copying |size| bytes from |p|.
+ RefCountedBytes(const unsigned char* p, size_t size);
+
+ // Constructs a RefCountedBytes object by performing a swap. (To non
+ // destructively build a RefCountedBytes, use the constructor that takes a
+ // vector.)
+ static RefCountedBytes* TakeVector(std::vector<unsigned char>* to_destroy);
+
+ // Overridden from RefCountedMemory:
+ virtual const unsigned char* front() const OVERRIDE;
+ virtual size_t size() const OVERRIDE;
+
+ const std::vector<unsigned char>& data() const { return data_; }
+ std::vector<unsigned char>& data() { return data_; }
+
+ private:
+ virtual ~RefCountedBytes();
+
+ std::vector<unsigned char> data_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedBytes);
+};
+
+// An implementation of RefCountedMemory, where the bytes are stored in an STL
+// string. Use this if your data naturally arrives in that format.
+class BASE_EXPORT RefCountedString : public RefCountedMemory {
+ public:
+ RefCountedString();
+
+ // Constructs a RefCountedString object by performing a swap. (To non
+ // destructively build a RefCountedString, use the default constructor and
+ // copy into object->data()).
+ static RefCountedString* TakeString(std::string* to_destroy);
+
+ // Overridden from RefCountedMemory:
+ virtual const unsigned char* front() const OVERRIDE;
+ virtual size_t size() const OVERRIDE;
+
+ const std::string& data() const { return data_; }
+ std::string& data() { return data_; }
+
+ private:
+ virtual ~RefCountedString();
+
+ std::string data_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedString);
+};
+
+// An implementation of RefCountedMemory that holds a chunk of memory
+// previously allocated with malloc or calloc, and that therefore must be freed
+// using free().
+class BASE_EXPORT RefCountedMallocedMemory : public RefCountedMemory {
+ public:
+ RefCountedMallocedMemory(void* data, size_t length);
+
+ // Overridden from RefCountedMemory:
+ virtual const unsigned char* front() const OVERRIDE;
+ virtual size_t size() const OVERRIDE;
+
+ private:
+ virtual ~RefCountedMallocedMemory();
+
+ unsigned char* data_;
+ size_t length_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedMallocedMemory);
+};
+
+} // namespace kudu
+
+#endif // KUDU_GUTIL_REF_COUNTED_MEMORY_H_
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/02f3e3fc/be/src/gutil/singleton.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/singleton.h b/be/src/gutil/singleton.h
index d1e1667..61e5ea5 100644
--- a/be/src/gutil/singleton.h
+++ b/be/src/gutil/singleton.h
@@ -60,8 +60,9 @@
#include <stddef.h>
#include <glog/logging.h>
-#include "gutil/logging-inl.h"
-#include "gutil/once.h"
+
+#include "kudu/gutil/logging-inl.h"
+#include "kudu/gutil/once.h"
namespace util {
namespace gtl {