├── AUTHORS ├── LICENSE ├── Makefile.am ├── README.md ├── configure.ac ├── contrib ├── bson │ ├── include │ │ └── bson │ │ │ ├── bson.h │ │ │ ├── bson11.h │ │ │ ├── ordering.h │ │ │ └── types.h │ └── src │ │ └── bson.cpp └── syncio │ ├── Makefile.am │ ├── configure.ac │ ├── include │ └── syncio │ │ ├── addr.h │ │ ├── algorithm.h │ │ ├── condvar.h │ │ ├── debug.h │ │ ├── engine.h │ │ ├── error.h │ │ ├── fd.h │ │ ├── id.h │ │ ├── impl │ │ ├── bind.h │ │ ├── future.h │ │ └── utility.h │ │ ├── mutex.h │ │ ├── stream.h │ │ ├── syncio.h │ │ ├── task.h │ │ └── time.h │ ├── m4 │ └── .keep │ ├── src │ ├── addr.cpp │ ├── condvar.cpp │ ├── condvar.h │ ├── ctx.cpp │ ├── ctx.h │ ├── ctx_ucontext.c │ ├── ctx_x86_64.s │ ├── debug.h │ ├── engine.cpp │ ├── fd.cpp │ ├── helper.h │ ├── log.cpp │ ├── log.h │ ├── mutex.cpp │ ├── mutex.h │ ├── platform.h │ ├── poller.cpp │ ├── poller.h │ ├── sched.cpp │ ├── scheduler.h │ ├── stream.cpp │ ├── task.cpp │ ├── tls.cpp │ ├── tls.h │ ├── unwind-cxxabi.cpp │ ├── valgrind.h │ ├── wait.cpp │ └── wait.h │ └── tests │ ├── dblcancel.cpp │ ├── smoke-http.cpp │ ├── smoke.cpp │ ├── stack-overflow.cpp │ └── test-condvar.cpp ├── m4 └── .keep ├── manpage └── src ├── auth.cpp ├── auth.h ├── backend.cpp ├── backend.h ├── cache.cpp ├── cache.h ├── clock.h ├── config.cpp ├── config.h ├── cursor_storage.h ├── error.h ├── http.cpp ├── http.h ├── lazy.h ├── log.h ├── main.cpp ├── monitor.cpp ├── monitor.h ├── operations.h ├── options.h ├── parallel.h ├── proto.h ├── read.cpp ├── read.h ├── session.cpp ├── session.h ├── shard.cpp ├── shard.h ├── sorted_vector.h ├── utility.h ├── version.h ├── write.cpp └── write.h /AUTHORS: -------------------------------------------------------------------------------- 1 | The following authors have created the source code of mongoz 2 | published and distributed by YANDEX LLC as the owner: 3 | 4 | Dmitry Prokoptsev 5 | Andrey Bugaevskiy 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 YANDEX LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | sbin_PROGRAMS = mongoz 4 | 5 | mongoz_SOURCES = \ 6 | src/auth.cpp \ 7 | src/write.cpp \ 8 | src/shard.cpp \ 9 | src/backend.cpp \ 10 | src/http.cpp \ 11 | src/cache.cpp \ 12 | src/monitor.cpp \ 13 | src/config.cpp \ 14 | src/read.cpp \ 15 | src/session.cpp \ 16 | src/main.cpp \ 17 | \ 18 | contrib/bson/src/bson.cpp \ 19 | \ 20 | contrib/syncio/src/ctx.cpp \ 21 | contrib/syncio/src/stream.cpp \ 22 | contrib/syncio/src/unwind-cxxabi.cpp \ 23 | contrib/syncio/src/task.cpp \ 24 | contrib/syncio/src/log.cpp \ 25 | contrib/syncio/src/tls.cpp \ 26 | contrib/syncio/src/engine.cpp \ 27 | contrib/syncio/src/wait.cpp \ 28 | contrib/syncio/src/sched.cpp \ 29 | contrib/syncio/src/addr.cpp \ 30 | contrib/syncio/src/mutex.cpp \ 31 | contrib/syncio/src/fd.cpp \ 32 | contrib/syncio/src/poller.cpp \ 33 | contrib/syncio/src/ctx_x86_64.s 34 | 35 | 36 | dist_noinst_HEADERS = \ 37 | src/cursor_storage.h \ 38 | src/shard.h \ 39 | src/parallel.h \ 40 | src/lazy.h \ 41 | src/monitor.h \ 42 | src/write.h \ 43 | src/proto.h \ 44 | src/auth.h \ 45 | src/http.h \ 46 | src/read.h \ 47 | src/clock.h \ 48 | src/version.h \ 49 | src/cache.h \ 50 | src/session.h \ 51 | src/log.h \ 52 | src/sorted_vector.h \ 53 | src/error.h \ 54 | src/backend.h \ 55 | src/operations.h \ 56 | src/config.h \ 57 | src/utility.h \ 58 | src/options.h \ 59 | \ 60 | contrib/bson/include/bson/bson.h \ 61 | contrib/bson/include/bson/bson11.h \ 62 | contrib/bson/include/bson/types.h \ 63 | contrib/bson/include/bson/ordering.h \ 64 | \ 65 | contrib/syncio/src/scheduler.h \ 66 | contrib/syncio/src/valgrind.h \ 67 | contrib/syncio/src/poller.h \ 68 | contrib/syncio/src/tls.h \ 69 | contrib/syncio/src/wait.h \ 70 | contrib/syncio/src/mutex.h \ 71 | contrib/syncio/src/helper.h \ 72 | contrib/syncio/src/debug.h \ 73 | contrib/syncio/src/log.h \ 74 | contrib/syncio/src/ctx.h \ 75 | \ 76 | contrib/syncio/include/syncio/addr.h \ 77 | contrib/syncio/include/syncio/impl/bind.h \ 78 | contrib/syncio/include/syncio/impl/future.h \ 79 | contrib/syncio/include/syncio/impl/utility.h \ 80 | contrib/syncio/include/syncio/time.h \ 81 | contrib/syncio/include/syncio/fd.h \ 82 | contrib/syncio/include/syncio/id.h \ 83 | contrib/syncio/include/syncio/syncio.h \ 84 | contrib/syncio/include/syncio/mutex.h \ 85 | contrib/syncio/include/syncio/algorithm.h \ 86 | contrib/syncio/include/syncio/stream.h \ 87 | contrib/syncio/include/syncio/debug.h \ 88 | contrib/syncio/include/syncio/error.h \ 89 | contrib/syncio/include/syncio/engine.h \ 90 | contrib/syncio/include/syncio/task.h 91 | 92 | mongoz_CXXFLAGS = -I$(srcdir)/contrib/bson/include -I$(srcdir)/contrib/syncio/include -std=c++0x 93 | mongoz_LDFLAGS = -lpthread -lcrypto 94 | 95 | if DEBUG 96 | mongoz_CXXFLAGS += -DIO_DEBUG -DIO_DEBUG_CIRCULAR 97 | endif 98 | 99 | if CPUPROFILE 100 | mongoz_CXXFLAGS += -DCPUPROFILE 101 | mongoz_LDFLAGS += -lprofiler 102 | endif 103 | 104 | dist_man8_MANS = mongoz.8 105 | 106 | mongoz.8: $(srcdir)/manpage 107 | sed "s/@@DATE@@/`git log --no-walk --format='%ad' --date=short $(srcdir)/manpage`/g" < $(srcdir)/manpage > mongoz.8 108 | 109 | clean-local: 110 | rm -f mongoz.8 111 | 112 | EXTRA_DIST = manpage 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mongoz is a replacement for MongoDB sharding server (mongos) 2 | aimed at higher availability in less-than-absolutely-reliable 3 | network environments at expense of somewhat relaxed 4 | consistency guarantees. 5 | 6 | Some distinguishing features of mongoz include: 7 | 8 | - **Hard timeouts**: each operation has to finish in predefined time. 9 | In case of network failures, clients get their errors early 10 | (i.e. they don't have to wait for i/o timeout from operating system) 11 | and thus are much less likely to face a DoS. 12 | 13 | - **Early request retransmission**: if there's more than one replica 14 | capable of handling a request, mongoz can be configured to retransmit 15 | a request to another replica *before* a timeout occurs and return whichever 16 | reply comes first. That way, even a network failure in the middle 17 | of a performing request does not neccessarily lead to any errors 18 | reported to clients. 19 | 20 | - **Config caching**: mongoz does not query its config servers 21 | upon a specific event (like incoming connection or authentication attempt). 22 | Instead, it keeps its local copy of the whole cluster config and 23 | synchronizes it periodically with config servers. As a result, 24 | unavailable config servers (even all of them) still 25 | don't render the whole cluster unusable. 26 | 27 | Mongoz strictly obeys MongoDB wire protocol and thus can be used 28 | as a drop-in replacement for mongos. Moreover, it can freely coexist 29 | with mongos within a same MongoDB cluster if neccessary. 30 | 31 | More detailed description of mongoz features can be found in its man page. 32 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Mode: -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.65]) 5 | AC_INIT([mongoz], [0.1.7], [bugaevskiy@yandex-team.ru]) 6 | AM_INIT_AUTOMAKE([foreign -Wall]) 7 | AC_CONFIG_SRCDIR([src/main.cpp]) 8 | AC_CONFIG_HEADERS([config.h]) 9 | AC_CONFIG_MACRO_DIR([m4]) 10 | 11 | # Checks for programs. 12 | AC_PROG_CXX 13 | AC_PROG_CC 14 | AM_PROG_AS 15 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 16 | AC_PROG_LIBTOOL 17 | AC_LANG_CPLUSPLUS 18 | 19 | # Checks for libraries. 20 | AC_CHECK_LIB(rt, clock_gettime) 21 | if test "x$ac_cv_lib_rt_clock_gettime" != "xyes"; then 22 | AC_MSG_ERROR([mongoz requires librt.]) 23 | fi 24 | 25 | # Checks for header files. 26 | AC_CHECK_HEADERS( 27 | [arpa/inet.h fcntl.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h], 28 | [], [AC_MSG_ERROR([cannot find all required headers])] 29 | ) 30 | AC_CHECK_HEADERS([valgrind/valgrind.h]) 31 | AC_CHECK_HEADERS([google/profiler.h]) 32 | 33 | # Checks for typedefs, structures, and compiler characteristics. 34 | AC_HEADER_STDBOOL 35 | AC_C_INLINE 36 | AC_TYPE_INT32_T 37 | AC_TYPE_INT64_T 38 | AC_TYPE_INT8_T 39 | AC_TYPE_SIZE_T 40 | AC_TYPE_SSIZE_T 41 | AC_TYPE_UINT32_T 42 | AC_TYPE_UINT64_T 43 | AC_TYPE_UINT8_T 44 | 45 | # Checks for library functions. 46 | AC_FUNC_FORK 47 | AC_CHECK_FUNCS([dup2 gettimeofday localtime_r memset select socket strerror tzset accept4]) 48 | 49 | AC_CACHE_CHECK([whether compiler supports C++11], [mongoz_cv_cxx11_supported], [ 50 | mongoz_saved_CXXFLAGS="$CXXFLAGS" 51 | CXXFLAGS="$CXXFLAGS -std=c++0x" 52 | AC_TRY_COMPILE([ 53 | template void foo(Args&&...) {} // Check for variadic templates 54 | // and rvalue references 55 | void bar() { foo([](int x) { return x + 1; }); } // Check for lambdas 56 | ], [], [mongoz_cv_cxx11_supported=yes], [mongoz_cv_cxx11_supported=no]) 57 | CXXFLAGS="$mongoz_saved_CXXFLAGS" 58 | ]) 59 | if test "x$mongoz_cv_cxx11_supported" != "xyes"; then 60 | AC_MSG_ERROR([mongoz requires compiler supporting C++11. Please upgrade.]) 61 | fi 62 | 63 | 64 | AC_CACHE_CHECK([the value of CLOCK_MONOTONIC_RAW], [mongoz_cv_clock_monotonic_raw_value], [ 65 | AC_TRY_LINK([ 66 | #include 67 | #include 68 | ], [printf("%d\n", CLOCK_MONOTONIC_RAW);], 69 | [mongoz_cv_clock_monotonic_raw_value=`./conftest$ac_exeext`], [mongoz_cv_clock_monotonic_raw_value=undefined]) 70 | ]) 71 | if test "x$mongoz_cv_clock_monotonic_raw_value" != "xundefined"; then 72 | AC_DEFINE_UNQUOTED([CLOCK_MONOTONIC_RAW_VALUE], [$mongoz_cv_clock_monotonic_raw_value], [Define to the value of CLOCK_MONOTONIC_RAW clock ID.]) 73 | AC_CACHE_CHECK([whether CLOCK_MONOTONIC_RAW is supported], [mongoz_cv_clock_monotonic_raw_useful], [ 74 | AC_TRY_RUN([ 75 | #include 76 | int main() { 77 | struct timespec ts; 78 | return (!clock_gettime(CLOCK_MONOTONIC_RAW_VALUE, &ts)) ? 0 : 1; 79 | } 80 | ], [mongoz_cv_clock_monotonic_raw_useful=yes], [mongoz_cv_clock_monotonic_raw_useful=no]) 81 | ]) 82 | if test "x$mongoz_cv_clock_monotonic_raw_useful" = "xyes"; then 83 | AC_DEFINE([HAVE_CLOCK_MONOTONIC_RAW], [1], [Define to 1 if clock_gettime(CLOCK_MONOTONIC_RAW) is supported.]) 84 | fi 85 | fi 86 | 87 | AC_CHECK_FUNCS([epoll_create epoll_ctl epoll_wait]) 88 | if test "x$ac_cv_func_epoll_create" != "xyes" \ 89 | || test "x$ac_cv_func_epoll_ctl" != "xyes" \ 90 | || test "x$ac_cv_func_epoll_wait" != "xyes" 91 | then 92 | AC_MSG_ERROR([mongoz requires epoll.]) 93 | fi 94 | 95 | AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [turn on debugging])], [mongoz_debug=yes], [mongoz_debug=no]) 96 | AC_ARG_ENABLE([profiling], [AS_HELP_STRING([--enable-profiling], [turn on CPU profiling])], [mongoz_cpuprofile=yes], [mongoz_cpuprofile=no]) 97 | AM_CONDITIONAL([DEBUG], [ test "x$mongoz_debug" = "xyes" ]) 98 | AM_CONDITIONAL([CPUPROFILE], [ test "x$mongoz_cpuprofile" = "xyes" ]) 99 | 100 | if test "x$mongoz_cpuprofile" = "xyes" && test "x$ac_cv_header_google_profiler_h" = "x"; then 101 | AC_MSG_ERROR([--enable-profiling option requires google/profiler.h header file.]) 102 | fi 103 | 104 | AC_CONFIG_FILES([Makefile]) 105 | AC_OUTPUT 106 | -------------------------------------------------------------------------------- /contrib/bson/include/bson/bson11.h: -------------------------------------------------------------------------------- 1 | /** 2 | * bson11.h -- a few helpers simplifying BSON objects and arrays creation 3 | * 4 | * This file is part of mongoz, a more sound implementation 5 | * of mongodb sharding server. 6 | * 7 | * Copyright (c) 2016 YANDEX LLC 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | #include "bson.h" 30 | 31 | namespace bson { 32 | namespace impl { 33 | 34 | inline void populateObject(ObjectBuilder&) {} 35 | inline void populateArray(ArrayBuilder&) {} 36 | 37 | template 38 | void populateObject(ObjectBuilder& b, const std::string& key, const T& value, const Args&... args) 39 | { 40 | b[key] = value; 41 | populateObject(b, args...); 42 | } 43 | 44 | template 45 | void populateArray(ArrayBuilder& b, const T& value, const Args&... args) 46 | { 47 | b << value; 48 | populateArray(b, args...); 49 | } 50 | 51 | } // namespace impl 52 | 53 | template 54 | Object object(const Args&... args) 55 | { 56 | ObjectBuilder b; 57 | impl::populateObject(b, args...); 58 | return b.obj(); 59 | } 60 | 61 | template 62 | Array array(const Args&... args) 63 | { 64 | ArrayBuilder b; 65 | impl::populateArray(b, args...); 66 | return b.array(); 67 | } 68 | 69 | } // namespace bson 70 | -------------------------------------------------------------------------------- /contrib/bson/include/bson/ordering.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ordering.h -- a few helpers simplifying definition of totally-ordered types 3 | * 4 | * This file is part of mongoz, a more sound implementation 5 | * of mongodb sharding server. 6 | * 7 | * Copyright (c) 2016 YANDEX LLC 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #include 31 | 32 | namespace bson { 33 | namespace impl { 34 | 35 | struct OrderedBase { 36 | template class Cmp, class T> 37 | static bool cmp(const T& a, const T& b) 38 | { 39 | return T::template cmp(a, b); 40 | } 41 | }; 42 | 43 | template 44 | struct Ordered { 45 | friend bool operator == (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 46 | friend bool operator != (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 47 | friend bool operator < (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 48 | friend bool operator <= (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 49 | friend bool operator > (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 50 | friend bool operator >= (const T& lhs, const T& rhs) { return OrderedBase::cmp(lhs, rhs); } 51 | }; 52 | 53 | template 54 | struct Equal { 55 | friend bool operator == (const T&, const T&) { return true; } 56 | friend bool operator != (const T&, const T&) { return false; } 57 | friend bool operator < (const T&, const T&) { return false; } 58 | friend bool operator <= (const T&, const T&) { return true; } 59 | friend bool operator > (const T&, const T&) { return false; } 60 | friend bool operator >= (const T&, const T&) { return true; } 61 | }; 62 | 63 | } // namespace impl 64 | } // namespace bson 65 | -------------------------------------------------------------------------------- /contrib/bson/include/bson/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * types.h -- a collecton of BSON-related types 3 | * 4 | * This file is part of mongoz, a more sound implementation 5 | * of mongodb sharding server. 6 | * 7 | * Copyright (c) 2016 YANDEX LLC 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #include "ordering.h" 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | namespace bson { 37 | 38 | class Null: public impl::Equal {}; 39 | 40 | class ObjectID: public impl::Ordered { 41 | public: 42 | ObjectID() { ::memset(data_, 0, DataSize); } 43 | 44 | ObjectID(const char* hex); 45 | 46 | ObjectID(const std::string& hex); 47 | 48 | std::string toString() const; 49 | 50 | time_t getTimestamp() const; 51 | 52 | static ObjectID generate(); 53 | 54 | static ObjectID minIdForTimestamp(time_t); 55 | 56 | static ObjectID maxIdForTimestamp(time_t); 57 | 58 | private: 59 | ObjectID(uint32_t time, uint64_t counter); 60 | 61 | enum { DataSize = 12 }; 62 | union { 63 | struct { 64 | uint32_t time_; 65 | uint64_t counter_; 66 | } __attribute__((packed)); 67 | char data_[DataSize]; 68 | }; 69 | 70 | friend class impl::OrderedBase; 71 | template class Cmp> 72 | static bool cmp(const ObjectID& a, const ObjectID& b) { return Cmp()(::memcmp(a.data_, b.data_, DataSize), 0); } 73 | 74 | friend std::ostream& operator << (std::ostream& out, const ObjectID&); 75 | }; 76 | 77 | struct MinKey: public impl::Equal {}; 78 | struct MaxKey: public impl::Equal {}; 79 | 80 | class Time: public impl::Ordered