├── .gitignore ├── ChangeLog ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── api ├── README.md ├── cpp │ └── README.md ├── cpy │ ├── SSDB.cpy │ └── demo.cpy ├── php │ ├── SSDB.php │ ├── demo.php │ └── perf.php └── python │ ├── SSDB.py │ └── demo.py ├── build.sh ├── deps ├── cpy │ ├── Eval.g │ ├── Eval.py │ ├── Expr.g │ ├── ExprLexer.py │ ├── ExprParser.py │ ├── Makefile │ ├── Readme.txt │ ├── antlr3 │ │ ├── __init__.py │ │ ├── compat.py │ │ ├── constants.py │ │ ├── dfa.py │ │ ├── dottreegen.py │ │ ├── exceptions.py │ │ ├── extras.py │ │ ├── main.py │ │ ├── recognizers.py │ │ ├── streams.py │ │ ├── tokens.py │ │ ├── tree.py │ │ └── treewizard.py │ ├── cpy │ ├── cpy.bat │ ├── cpy.py │ ├── engine.py │ └── samples │ │ ├── class.cpy │ │ ├── extends.cpy │ │ ├── foreach.cpy │ │ ├── function.cpy │ │ ├── hello.cpy │ │ ├── list.cpy │ │ ├── object.cpy │ │ ├── simple_client.cpy │ │ ├── simple_server.cpy │ │ ├── stdin.cpy │ │ └── test.cpy ├── jemalloc-4.1.0 │ ├── .autom4te.cfg │ ├── .gitattributes │ ├── .gitignore │ ├── COPYING │ ├── ChangeLog │ ├── INSTALL │ ├── Makefile.in │ ├── README │ ├── autogen.sh │ ├── bin │ │ ├── jemalloc-config.in │ │ ├── jemalloc.sh.in │ │ └── jeprof.in │ ├── build-aux │ │ ├── config.guess │ │ ├── config.sub │ │ └── install-sh │ ├── config.stamp.in │ ├── configure.ac │ ├── coverage.sh │ ├── doc │ │ ├── html.xsl.in │ │ ├── jemalloc.xml.in │ │ ├── manpages.xsl.in │ │ └── stylesheet.xsl │ ├── include │ │ ├── jemalloc │ │ │ ├── internal │ │ │ │ ├── arena.h │ │ │ │ ├── assert.h │ │ │ │ ├── atomic.h │ │ │ │ ├── base.h │ │ │ │ ├── bitmap.h │ │ │ │ ├── chunk.h │ │ │ │ ├── chunk_dss.h │ │ │ │ ├── chunk_mmap.h │ │ │ │ ├── ckh.h │ │ │ │ ├── ctl.h │ │ │ │ ├── extent.h │ │ │ │ ├── hash.h │ │ │ │ ├── huge.h │ │ │ │ ├── jemalloc_internal.h.in │ │ │ │ ├── jemalloc_internal_decls.h │ │ │ │ ├── jemalloc_internal_defs.h.in │ │ │ │ ├── jemalloc_internal_macros.h │ │ │ │ ├── mb.h │ │ │ │ ├── mutex.h │ │ │ │ ├── nstime.h │ │ │ │ ├── pages.h │ │ │ │ ├── private_namespace.sh │ │ │ │ ├── private_symbols.txt │ │ │ │ ├── private_unnamespace.sh │ │ │ │ ├── prng.h │ │ │ │ ├── prof.h │ │ │ │ ├── public_namespace.sh │ │ │ │ ├── public_unnamespace.sh │ │ │ │ ├── ql.h │ │ │ │ ├── qr.h │ │ │ │ ├── quarantine.h │ │ │ │ ├── rb.h │ │ │ │ ├── rtree.h │ │ │ │ ├── size_classes.sh │ │ │ │ ├── smoothstep.h │ │ │ │ ├── smoothstep.sh │ │ │ │ ├── stats.h │ │ │ │ ├── tcache.h │ │ │ │ ├── ticker.h │ │ │ │ ├── tsd.h │ │ │ │ ├── util.h │ │ │ │ └── valgrind.h │ │ │ ├── jemalloc.sh │ │ │ ├── jemalloc_defs.h.in │ │ │ ├── jemalloc_macros.h.in │ │ │ ├── jemalloc_mangle.sh │ │ │ ├── jemalloc_protos.h.in │ │ │ ├── jemalloc_rename.sh │ │ │ └── jemalloc_typedefs.h.in │ │ └── msvc_compat │ │ │ ├── C99 │ │ │ ├── stdbool.h │ │ │ └── stdint.h │ │ │ ├── strings.h │ │ │ └── windows_extra.h │ ├── jemalloc.pc.in │ ├── msvc │ │ ├── ReadMe.txt │ │ ├── jemalloc_vc2015.sln │ │ └── projects │ │ │ └── vc2015 │ │ │ ├── jemalloc │ │ │ ├── jemalloc.vcxproj │ │ │ └── jemalloc.vcxproj.filters │ │ │ └── test_threads │ │ │ ├── test_threads.cpp │ │ │ ├── test_threads.h │ │ │ ├── test_threads.vcxproj │ │ │ ├── test_threads.vcxproj.filters │ │ │ └── test_threads_main.cpp │ ├── src │ │ ├── arena.c │ │ ├── atomic.c │ │ ├── base.c │ │ ├── bitmap.c │ │ ├── chunk.c │ │ ├── chunk_dss.c │ │ ├── chunk_mmap.c │ │ ├── ckh.c │ │ ├── ctl.c │ │ ├── extent.c │ │ ├── hash.c │ │ ├── huge.c │ │ ├── jemalloc.c │ │ ├── mb.c │ │ ├── mutex.c │ │ ├── nstime.c │ │ ├── pages.c │ │ ├── prng.c │ │ ├── prof.c │ │ ├── quarantine.c │ │ ├── rtree.c │ │ ├── stats.c │ │ ├── tcache.c │ │ ├── ticker.c │ │ ├── tsd.c │ │ ├── util.c │ │ ├── valgrind.c │ │ └── zone.c │ └── test │ │ ├── include │ │ └── test │ │ │ ├── SFMT-alti.h │ │ │ ├── SFMT-params.h │ │ │ ├── SFMT-params11213.h │ │ │ ├── SFMT-params1279.h │ │ │ ├── SFMT-params132049.h │ │ │ ├── SFMT-params19937.h │ │ │ ├── SFMT-params216091.h │ │ │ ├── SFMT-params2281.h │ │ │ ├── SFMT-params4253.h │ │ │ ├── SFMT-params44497.h │ │ │ ├── SFMT-params607.h │ │ │ ├── SFMT-params86243.h │ │ │ ├── SFMT-sse2.h │ │ │ ├── SFMT.h │ │ │ ├── btalloc.h │ │ │ ├── jemalloc_test.h.in │ │ │ ├── jemalloc_test_defs.h.in │ │ │ ├── math.h │ │ │ ├── mq.h │ │ │ ├── mtx.h │ │ │ ├── test.h │ │ │ ├── thd.h │ │ │ └── timer.h │ │ ├── integration │ │ ├── MALLOCX_ARENA.c │ │ ├── aligned_alloc.c │ │ ├── allocated.c │ │ ├── chunk.c │ │ ├── mallocx.c │ │ ├── overflow.c │ │ ├── posix_memalign.c │ │ ├── rallocx.c │ │ ├── sdallocx.c │ │ ├── thread_arena.c │ │ ├── thread_tcache_enabled.c │ │ └── xallocx.c │ │ ├── src │ │ ├── SFMT.c │ │ ├── btalloc.c │ │ ├── btalloc_0.c │ │ ├── btalloc_1.c │ │ ├── math.c │ │ ├── mq.c │ │ ├── mtx.c │ │ ├── test.c │ │ ├── thd.c │ │ └── timer.c │ │ ├── stress │ │ └── microbench.c │ │ ├── test.sh.in │ │ └── unit │ │ ├── SFMT.c │ │ ├── atomic.c │ │ ├── bitmap.c │ │ ├── ckh.c │ │ ├── decay.c │ │ ├── hash.c │ │ ├── junk.c │ │ ├── junk_alloc.c │ │ ├── junk_free.c │ │ ├── lg_chunk.c │ │ ├── mallctl.c │ │ ├── math.c │ │ ├── mq.c │ │ ├── mtx.c │ │ ├── nstime.c │ │ ├── prng.c │ │ ├── prof_accum.c │ │ ├── prof_active.c │ │ ├── prof_gdump.c │ │ ├── prof_idump.c │ │ ├── prof_reset.c │ │ ├── prof_thread_name.c │ │ ├── ql.c │ │ ├── qr.c │ │ ├── quarantine.c │ │ ├── rb.c │ │ ├── rtree.c │ │ ├── run_quantize.c │ │ ├── size_classes.c │ │ ├── smoothstep.c │ │ ├── stats.c │ │ ├── ticker.c │ │ ├── tsd.c │ │ ├── util.c │ │ └── zero.c ├── leveldb-1.20 │ ├── .gitignore │ ├── .travis.yml │ ├── AUTHORS │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── Makefile │ ├── Makefile.bk │ ├── NEWS │ ├── README.md │ ├── TODO │ ├── build_detect_platform │ ├── build_detect_platform.bk │ ├── db │ │ ├── autocompact_test.cc │ │ ├── builder.cc │ │ ├── builder.h │ │ ├── c.cc │ │ ├── c_test.c │ │ ├── corruption_test.cc │ │ ├── db_bench.cc │ │ ├── db_impl.cc │ │ ├── db_impl.cc.bk │ │ ├── db_impl.h │ │ ├── db_iter.cc │ │ ├── db_iter.h │ │ ├── db_test.cc │ │ ├── dbformat.cc │ │ ├── dbformat.h │ │ ├── dbformat.h.bk │ │ ├── dbformat_test.cc │ │ ├── dumpfile.cc │ │ ├── fault_injection_test.cc │ │ ├── filename.cc │ │ ├── filename.h │ │ ├── filename_test.cc │ │ ├── leveldbutil.cc │ │ ├── log_format.h │ │ ├── log_reader.cc │ │ ├── log_reader.h │ │ ├── log_test.cc │ │ ├── log_writer.cc │ │ ├── log_writer.h │ │ ├── memtable.cc │ │ ├── memtable.h │ │ ├── recovery_test.cc │ │ ├── repair.cc │ │ ├── skiplist.h │ │ ├── skiplist_test.cc │ │ ├── snapshot.h │ │ ├── table_cache.cc │ │ ├── table_cache.h │ │ ├── version_edit.cc │ │ ├── version_edit.h │ │ ├── version_edit_test.cc │ │ ├── version_set.cc │ │ ├── version_set.h │ │ ├── version_set_test.cc │ │ ├── write_batch.cc │ │ ├── write_batch_internal.h │ │ └── write_batch_test.cc │ ├── doc │ │ ├── bench │ │ │ ├── db_bench_sqlite3.cc │ │ │ └── db_bench_tree_db.cc │ │ ├── benchmark.html │ │ ├── impl.md │ │ ├── index.md │ │ ├── log_format.md │ │ └── table_format.md │ ├── helpers │ │ └── memenv │ │ │ ├── memenv.cc │ │ │ ├── memenv.h │ │ │ └── memenv_test.cc │ ├── include │ │ └── leveldb │ │ │ ├── c.h │ │ │ ├── cache.h │ │ │ ├── comparator.h │ │ │ ├── db.h │ │ │ ├── dumpfile.h │ │ │ ├── env.h │ │ │ ├── filter_policy.h │ │ │ ├── iterator.h │ │ │ ├── iterator.h.bk │ │ │ ├── options.h │ │ │ ├── slice.h │ │ │ ├── status.h │ │ │ ├── table.h │ │ │ ├── table_builder.h │ │ │ └── write_batch.h │ ├── issues │ │ ├── issue178_test.cc │ │ └── issue200_test.cc │ ├── port │ │ ├── README │ │ ├── atomic_pointer.h │ │ ├── port.h │ │ ├── port_example.h │ │ ├── port_posix.cc │ │ ├── port_posix.h │ │ ├── port_posix_sse.cc │ │ ├── thread_annotations.h │ │ └── win │ │ │ └── stdint.h │ ├── table │ │ ├── block.cc │ │ ├── block.h │ │ ├── block_builder.cc │ │ ├── block_builder.h │ │ ├── filter_block.cc │ │ ├── filter_block.h │ │ ├── filter_block_test.cc │ │ ├── format.cc │ │ ├── format.h │ │ ├── iterator.cc │ │ ├── iterator_wrapper.h │ │ ├── merger.cc │ │ ├── merger.h │ │ ├── table.cc │ │ ├── table_builder.cc │ │ ├── table_test.cc │ │ ├── two_level_iterator.cc │ │ └── two_level_iterator.h │ └── util │ │ ├── arena.cc │ │ ├── arena.h │ │ ├── arena_test.cc │ │ ├── bloom.cc │ │ ├── bloom_test.cc │ │ ├── cache.cc │ │ ├── cache_test.cc │ │ ├── coding.cc │ │ ├── coding.h │ │ ├── coding_test.cc │ │ ├── comparator.cc │ │ ├── crc32c.cc │ │ ├── crc32c.h │ │ ├── crc32c_test.cc │ │ ├── env.cc │ │ ├── env_posix.cc │ │ ├── env_posix_test.cc │ │ ├── env_posix_test_helper.h │ │ ├── env_test.cc │ │ ├── filter_policy.cc │ │ ├── hash.cc │ │ ├── hash.h │ │ ├── hash_test.cc │ │ ├── histogram.cc │ │ ├── histogram.h │ │ ├── logging.cc │ │ ├── logging.h │ │ ├── mutexlock.h │ │ ├── options.cc │ │ ├── posix_logger.h │ │ ├── random.h │ │ ├── status.cc │ │ ├── testharness.cc │ │ ├── testharness.h │ │ ├── testutil.cc │ │ └── testutil.h └── snappy-1.1.0 │ ├── .gitignore │ ├── AUTHORS │ ├── COPYING │ ├── ChangeLog │ ├── INSTALL │ ├── Makefile-ios │ ├── Makefile.am │ ├── Makefile.in │ ├── NEWS │ ├── README │ ├── aclocal.m4 │ ├── autogen.sh │ ├── config.guess │ ├── config.h.in │ ├── config.sub │ ├── configure │ ├── configure.ac │ ├── depcomp │ ├── format_description.txt │ ├── framing_format.txt │ ├── install-sh │ ├── ltmain.sh │ ├── m4 │ └── gtest.m4 │ ├── missing │ ├── snappy-c.cc │ ├── snappy-c.h │ ├── snappy-internal.h │ ├── snappy-sinksource.cc │ ├── snappy-sinksource.h │ ├── snappy-stubs-internal.cc │ ├── snappy-stubs-internal.h │ ├── snappy-stubs-public.h │ ├── snappy-stubs-public.h.in │ ├── snappy-test.cc │ ├── snappy-test.h │ ├── snappy.cc │ ├── snappy.h │ └── snappy_unittest.cc ├── docs ├── README.md ├── logo.png └── logo.svg ├── src ├── Makefile ├── backend_dump.cpp ├── backend_dump.h ├── backend_sync.cpp ├── backend_sync.h ├── client │ ├── Doxyfile │ ├── Makefile │ ├── README.md │ ├── SSDB_client.h │ ├── SSDB_impl.cpp │ ├── SSDB_impl.h │ ├── demo.cpp │ └── hello-ssdb.cpp ├── include.h ├── net │ ├── .gitignore │ ├── Makefile │ ├── fde.cpp │ ├── fde.h │ ├── fde_epoll.cpp │ ├── fde_select.cpp │ ├── link.cpp │ ├── link.h │ ├── link_addr.cpp │ ├── link_addr.h │ ├── link_redis.cpp │ ├── link_redis.h │ ├── proc.cpp │ ├── proc.h │ ├── resp.cpp │ ├── resp.h │ ├── server.cpp │ ├── server.h │ ├── test.conf │ ├── test.cpp │ ├── test2.cpp │ ├── worker.cpp │ └── worker.h ├── proc_hash.cpp ├── proc_hash.h ├── proc_kv.cpp ├── proc_kv.h ├── proc_queue.cpp ├── proc_queue.h ├── proc_sys.cpp ├── proc_sys.h ├── proc_zset.cpp ├── proc_zset.h ├── serv.cpp ├── serv.h ├── slave.cpp ├── slave.h ├── ssdb-server.cpp ├── ssdb │ ├── Makefile │ ├── Makefile-ios │ ├── binlog.cpp │ ├── binlog.h │ ├── const.h │ ├── iterator.cpp │ ├── iterator.h │ ├── options.cpp │ ├── options.h │ ├── ssdb.h │ ├── ssdb_impl.cpp │ ├── ssdb_impl.h │ ├── t_hash.cpp │ ├── t_hash.h │ ├── t_kv.cpp │ ├── t_kv.h │ ├── t_queue.cpp │ ├── t_queue.h │ ├── t_zset.cpp │ ├── t_zset.h │ ├── test.cpp │ ├── ttl.cpp │ └── ttl.h ├── util │ ├── Makefile │ ├── Makefile-ios │ ├── app.cpp │ ├── app.h │ ├── bytes.cpp │ ├── bytes.h │ ├── config.cpp │ ├── config.h │ ├── daemon.h │ ├── file.h │ ├── ip_filter.h │ ├── line.h │ ├── list.h │ ├── log.cpp │ ├── log.h │ ├── sorted_set.cpp │ ├── sorted_set.h │ ├── string_util.h │ ├── test_sorted_set.cpp │ ├── test_thread.cpp │ └── thread.h └── version.h ├── ssdb.conf ├── ssdb_slave.conf ├── tools ├── Makefile ├── leveldb-import.cpp ├── redis-import.php ├── ssdb-bench.cpp ├── ssdb-cli ├── ssdb-cli.bat ├── ssdb-cli.cpy ├── ssdb-dump.cpp ├── ssdb-iterate.php ├── ssdb-migrate.cpp ├── ssdb-repair.cpp ├── ssdb.sh ├── ssdb_cli │ ├── cluster.cpy │ ├── exporter.cpy │ ├── flushdb.cpy │ ├── importer.cpy │ ├── nagios.cpy │ └── util.cpy ├── test_slow_client.php └── unittest.php └── version /.gitignore: -------------------------------------------------------------------------------- 1 | ssdb-server* 2 | ios 3 | 888*.conf 4 | var888* 5 | *.exe 6 | *.o 7 | *.a 8 | *.out 9 | *.class 10 | tmp 11 | .DS_Store 12 | *.pyc 13 | var/* 14 | var_* 15 | var_slave/* 16 | dev_ssdb.conf* 17 | dev_slave.conf 18 | *.swp 19 | *_cpy_* 20 | *.dSYM* 21 | ssdb-server 22 | tools/ssdb-dump 23 | tools/ssdb-bench 24 | tools/ssdb-repair 25 | tools/ssdb-migrate 26 | tools/leveldb-import 27 | _pack 28 | build_config.mk 29 | log.txt 30 | repair.log 31 | log_slave.txt 32 | src/client/demo 33 | src/client/hello-ssdb 34 | api/cpp/SSDB_client.h 35 | api/cpp/test 36 | api/cpp/html 37 | api/php/a.php 38 | api/php/b.php 39 | api/php/c.php 40 | api/java/Test.java 41 | src/util/test_sorted_set 42 | 43 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | MAINTAINER wendal "wendal1985@gmail.com" 3 | 4 | # Set the env variable DEBIAN_FRONTEND to noninteractive 5 | ENV DEBIAN_FRONTEND noninteractive 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y python2.7 && \ 9 | apt-get install -y --force-yes git make gcc g++ autoconf && apt-get clean && \ 10 | git clone --depth 1 https://github.com/ideawu/ssdb.git ssdb && \ 11 | cd ssdb && make && make install && cp ssdb-server /usr/bin && \ 12 | apt-get remove -y --force-yes git make gcc g++ autoconf && \ 13 | apt-get autoremove -y && \ 14 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ 15 | cp ssdb.conf /etc && cd .. && yes | rm -r ssdb 16 | 17 | RUN mkdir -p /var/lib/ssdb && \ 18 | sed \ 19 | -e 's@home.*@home /var/lib@' \ 20 | -e 's/loglevel.*/loglevel info/' \ 21 | -e 's@work_dir = .*@work_dir = /var/lib/ssdb@' \ 22 | -e 's@pidfile = .*@pidfile = /run/ssdb.pid@' \ 23 | -e 's@level:.*@level: info@' \ 24 | -e 's@ip:.*@ip: 0.0.0.0@' \ 25 | -i /etc/ssdb.conf 26 | 27 | 28 | ENV TZ Asia/Shanghai 29 | EXPOSE 8888 30 | VOLUME /var/lib/ssdb 31 | ENTRYPOINT /usr/bin/ssdb-server /etc/ssdb.conf 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 SSDB Authors 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the SSDB nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=/usr/local/ssdb 2 | 3 | $(shell sh build.sh 1>&2) 4 | include build_config.mk 5 | 6 | all: 7 | mkdir -p var var_slave 8 | chmod u+x "${LEVELDB_PATH}/build_detect_platform" 9 | chmod u+x deps/cpy/cpy 10 | chmod u+x tools/ssdb-cli 11 | cd "${LEVELDB_PATH}"; ${MAKE} 12 | cd src/util; ${MAKE} 13 | cd src/net; ${MAKE} 14 | cd src/client; ${MAKE} 15 | cd src/ssdb; ${MAKE} 16 | cd src; ${MAKE} 17 | cd tools; ${MAKE} 18 | 19 | .PHONY: ios 20 | 21 | ios: 22 | cd "${LEVELDB_PATH}"; make clean; CXXFLAGS=-stdlib=libc++ ${MAKE} PLATFORM=IOS 23 | cd "${SNAPPY_PATH}"; make clean; make -f Makefile-ios 24 | mkdir -p ios 25 | mv ${LEVELDB_PATH}/out-ios-universal/libleveldb.a ios/libleveldb-ios.a 26 | mv ${SNAPPY_PATH}/libsnappy-ios.a ios/ 27 | cd src/util; make clean; ${MAKE} -f Makefile-ios 28 | cd src/ssdb; make clean; ${MAKE} -f Makefile-ios 29 | 30 | install: 31 | mkdir -p ${PREFIX} 32 | mkdir -p ${PREFIX}/_cpy_ 33 | mkdir -p ${PREFIX}/deps 34 | mkdir -p ${PREFIX}/var 35 | mkdir -p ${PREFIX}/var_slave 36 | cp -f ssdb-server ssdb.conf ssdb_slave.conf ${PREFIX} 37 | cp -rf api ${PREFIX} 38 | cp -rf \ 39 | tools/ssdb-bench \ 40 | tools/ssdb-cli tools/ssdb_cli \ 41 | tools/ssdb-cli.cpy tools/ssdb-dump \ 42 | tools/ssdb-repair \ 43 | ${PREFIX} 44 | cp -rf deps/cpy ${PREFIX}/deps 45 | chmod 755 ${PREFIX} 46 | rm -f ${PREFIX}/Makefile 47 | 48 | clean: 49 | rm -f *.exe.stackdump 50 | rm -rf api/cpy/_cpy_ 51 | rm -f api/python/SSDB.pyc 52 | rm -rf db_test 53 | cd deps/cpy; ${MAKE} clean 54 | cd src/util; ${MAKE} clean 55 | cd src/ssdb; ${MAKE} clean 56 | cd src/net; ${MAKE} clean 57 | cd src; ${MAKE} clean 58 | cd tools; ${MAKE} clean 59 | 60 | clean_all: clean 61 | cd "${LEVELDB_PATH}"; ${MAKE} clean 62 | rm -f ${JEMALLOC_PATH}/Makefile 63 | cd "${SNAPPY_PATH}"; ${MAKE} clean 64 | rm -f ${SNAPPY_PATH}/Makefile 65 | 66 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | See https://github.com/ssdb 2 | -------------------------------------------------------------------------------- /api/cpp/README.md: -------------------------------------------------------------------------------- 1 | Moved to src/client 2 | 3 | -------------------------------------------------------------------------------- /api/cpy/demo.cpy: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, ideawu 3 | * All rights reserved. 4 | * @author: ideawu 5 | * @link: http://www.ideawu.com/ 6 | * 7 | * SSDB cpy API demo. 8 | */ 9 | 10 | import SSDB.SSDB; 11 | 12 | try{ 13 | ssdb = new SSDB('127.0.0.1', 8888); 14 | }catch(Exception e){ 15 | print e; 16 | sys.exit(0); 17 | } 18 | 19 | print(ssdb.request('set', ['test', '123'])); 20 | print(ssdb.request('get', ['test'])); 21 | print(ssdb.request('incr', ['test', '1'])); 22 | print(ssdb.request('decr', ['test', '1'])); 23 | print(ssdb.request('scan', ['a', 'z', 10])); 24 | print(ssdb.request('rscan', ['z', 'a', 10])); 25 | print(ssdb.request('keys', ['a', 'z', 10])); 26 | print(ssdb.request('del', ['test'])); 27 | print(ssdb.request('get', ['test'])); 28 | print "\n"; 29 | print(ssdb.request('zset', ['test', 'a', 20])); 30 | print(ssdb.request('zget', ['test', 'a'])); 31 | print(ssdb.request('zincr', ['test', 'a', 20])); 32 | print(ssdb.request('zdecr', ['test', 'a', 20])); 33 | print(ssdb.request('zscan', ['test', 'a', 0, 100, 10])); 34 | print(ssdb.request('zrscan', ['test', 'a', 100, 0, 10])); 35 | print(ssdb.request('zkeys', ['test', 'a', 0, 100, 10])); 36 | print(ssdb.request('zdel', ['test', 'a'])); 37 | print(ssdb.request('zget', ['test', 'a'])); 38 | print "\n"; 39 | print(ssdb.request('hset', ['test', 'a', 20])); 40 | print(ssdb.request('hget', ['test', 'a'])); 41 | print(ssdb.request('hincr', ['test', 'a', 20])); 42 | print(ssdb.request('hdecr', ['test', 'a', 20])); 43 | print(ssdb.request('hscan', ['test', '0', 'z', 10])); 44 | print(ssdb.request('hrscan', ['test', 'z', '0', 10])); 45 | print(ssdb.request('hkeys', ['test', '0', 'z', 10])); 46 | print(ssdb.request('hdel', ['test', 'a'])); 47 | print(ssdb.request('hget', ['test', 'a'])); 48 | print "\n"; 49 | -------------------------------------------------------------------------------- /api/php/perf.php: -------------------------------------------------------------------------------- 1 | set('key', $str); 9 | 10 | 11 | $keys = array( 12 | 'seq' => array(), 13 | ); 14 | for($i=0; $i<1000; $i++){ 15 | $key = sprintf('%010s', $i); 16 | $keys['seq'][] = $key; 17 | } 18 | 19 | $REQUESTS = 1000; 20 | $stime = 0; 21 | $etime = 0; 22 | 23 | 24 | start(); 25 | foreach($keys['seq'] as $key){ 26 | $resp = $ssdb->set($key, $str); 27 | } 28 | output('writeseq'); 29 | 30 | $ks = $keys['seq']; 31 | shuffle($ks); 32 | start(); 33 | foreach($ks as $key){ 34 | $resp = $ssdb->set($key, $str); 35 | } 36 | output('writerand'); 37 | 38 | start(); 39 | foreach($keys['seq'] as $key){ 40 | $resp = $ssdb->get($key); 41 | if(strlen($resp) != $DATA_LEN){ 42 | echo "$key ERROR!\n"; 43 | die(); 44 | } 45 | } 46 | output('readseq'); 47 | 48 | 49 | $ks = $keys['seq']; 50 | shuffle($ks); 51 | start(); 52 | foreach($ks as $key){ 53 | $resp = $ssdb->get($key); 54 | if(strlen($resp) != $DATA_LEN){ 55 | echo "$key ERROR!\n"; 56 | die(); 57 | } 58 | } 59 | output('readrand'); 60 | 61 | 62 | 63 | 64 | function start(){ 65 | global $stime, $etime, $DATA_LEN, $REQUESTS; 66 | $stime = microtime(1); 67 | } 68 | 69 | function output($op){ 70 | global $stime, $etime, $DATA_LEN, $REQUESTS; 71 | $etime = microtime(1); 72 | $time_consumed = $etime - $stime; 73 | $tpr = $time_consumed/$REQUESTS * 1000; 74 | $sps = ($REQUESTS * $DATA_LEN)/$time_consumed/1024/1024; 75 | printf("%-10s: %8s ms/op %10.1f MB/s\n", $op, number_format($tpr, 3), $sps);// . "ms/op\n"; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /api/python/demo.py: -------------------------------------------------------------------------------- 1 | # encoding=utf-8 2 | # Generated by cpy 3 | # 2013-01-26 21:04:47.984000 4 | import os, sys 5 | from sys import stdin, stdout 6 | 7 | from SSDB import SSDB 8 | try: 9 | pass 10 | ssdb = SSDB('127.0.0.1', 8888) 11 | except Exception , e: 12 | pass 13 | print e 14 | sys.exit(0) 15 | print ssdb.request('set', ['test', '123']) 16 | print ssdb.request('get', ['test']) 17 | print ssdb.request('incr', ['test', '1']) 18 | print ssdb.request('decr', ['test', '1']) 19 | print ssdb.request('scan', ['a', 'z', 10]) 20 | print ssdb.request('rscan', ['z', 'a', 10]) 21 | print ssdb.request('keys', ['a', 'z', 10]) 22 | print ssdb.request('del', ['test']) 23 | print ssdb.request('get', ['test']) 24 | print "\n" 25 | print ssdb.request('zset', ['test', 'a', 20]) 26 | print ssdb.request('zget', ['test', 'a']) 27 | print ssdb.request('zincr', ['test', 'a', 20]) 28 | print ssdb.request('zdecr', ['test', 'a', 20]) 29 | print ssdb.request('zscan', ['test', 'a', 0, 100, 10]) 30 | print ssdb.request('zrscan', ['test', 'a', 100, 0, 10]) 31 | print ssdb.request('zkeys', ['test', 'a', 0, 100, 10]) 32 | print ssdb.request('zdel', ['test', 'a']) 33 | print ssdb.request('zget', ['test', 'a']) 34 | print "\n" 35 | print ssdb.request('hset', ['test', 'a', 20]) 36 | print ssdb.request('hget', ['test', 'a']) 37 | print ssdb.request('hincr', ['test', 'a', 20]) 38 | print ssdb.request('hdecr', ['test', 'a', 20]) 39 | print ssdb.request('hscan', ['test', '0', 'z', 10]) 40 | print ssdb.request('hrscan', ['test', 'z', '0', 10]) 41 | print ssdb.request('hkeys', ['test', '0', 'z', 10]) 42 | print ssdb.request('hdel', ['test', 'a']) 43 | print ssdb.request('hget', ['test', 'a']) 44 | print "\n" 45 | -------------------------------------------------------------------------------- /deps/cpy/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: antlr test 3 | 4 | antlr: 5 | java -jar ../antlr-3.4-complete.jar Expr.g Eval.g 6 | 7 | lexer: 8 | java -jar ../antlr-3.4-complete.jar Expr.g 9 | python test_lexer.py test.cpy 10 | 11 | test: 12 | python cpy.py test.cpy 13 | 14 | run: 15 | python a.py 16 | 17 | clean: 18 | rm -rf _cpy_ 19 | rm -f *.pyc 20 | rm -f antlr3/*.pyc 21 | -------------------------------------------------------------------------------- /deps/cpy/Readme.txt: -------------------------------------------------------------------------------- 1 | ********************************************** 2 | * Author: ideawu 3 | * Link: http://www.ideawu.net/ 4 | * Cpy - Cpy provides you a way to write Python 5 | * codes in C syntax! 6 | ********************************************** 7 | 8 | * Run the samples 9 | $ ./cpy samples/hello.cpy 10 | 11 | * Compile Antlr grammar files 12 | $ make antlr 13 | -------------------------------------------------------------------------------- /deps/cpy/antlr3/compat.py: -------------------------------------------------------------------------------- 1 | """Compatibility stuff""" 2 | 3 | # begin[licence] 4 | # 5 | # [The "BSD licence"] 6 | # Copyright (c) 2005-2008 Terence Parr 7 | # All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions 11 | # are met: 12 | # 1. Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # 2. Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # 3. The name of the author may not be used to endorse or promote products 18 | # derived from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | # 31 | # end[licence] 32 | 33 | try: 34 | set = set 35 | frozenset = frozenset 36 | except NameError: 37 | from sets import Set as set, ImmutableSet as frozenset 38 | 39 | 40 | try: 41 | reversed = reversed 42 | except NameError: 43 | def reversed(l): 44 | l = l[:] 45 | l.reverse() 46 | return l 47 | 48 | 49 | -------------------------------------------------------------------------------- /deps/cpy/cpy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=`dirname $0` 4 | 5 | which python2.7 > /dev/null 2>&1 6 | [ $? -eq 0 ] && { python2.7 $DIR/cpy.py $@; exit $?;} 7 | which python2 > /dev/null 2>&1 8 | [ $? -eq 0 ] && { python2 $DIR/cpy.py $@; exit $?;} 9 | 10 | python $DIR/cpy.py $@ 11 | exit $? 12 | -------------------------------------------------------------------------------- /deps/cpy/cpy.bat: -------------------------------------------------------------------------------- 1 | 2 | @echo off 3 | python %~dp0cpy.py %1 %2 %3 %4 %5 %6 %7 %8 %9 4 | -------------------------------------------------------------------------------- /deps/cpy/cpy.py: -------------------------------------------------------------------------------- 1 | # encoding=utf-8 2 | ################################# 3 | # Author: ideawu 4 | # Link: http://www.ideawu.net/ 5 | ################################# 6 | 7 | import sys, os 8 | import signal 9 | def __sigint__(n, f): 10 | sys.exit(0) 11 | signal.signal(signal.SIGINT, __sigint__); 12 | 13 | def usage(): 14 | print ('Cpy - A C-like scripting language.') 15 | print ('Copyright (c) 2012 ideawu.com') 16 | print ('') 17 | print ('Usage:') 18 | print (' cpy source_file') 19 | 20 | # 不然管道时报错 21 | reload(sys) 22 | sys.setdefaultencoding('utf-8') 23 | 24 | from engine import CpyEngine 25 | cpy = CpyEngine() 26 | 27 | if len(sys.argv) < 2: 28 | usage() 29 | sys.exit(0) 30 | 31 | is_compile = False; 32 | if sys.argv[1] == '-c': 33 | is_compile = True 34 | if len(sys.argv) >= 3: 35 | srcfile = sys.argv[2] 36 | else: 37 | usage() 38 | sys.exit(0) 39 | else: 40 | srcfile = sys.argv[1] 41 | 42 | if not srcfile.endswith('.cpy'): 43 | srcfile += '.cpy' 44 | if not os.path.exists(srcfile): 45 | print ("File not found!: " + srcfile) 46 | sys.exit(0) 47 | 48 | base_dir, tail = os.path.split(srcfile) 49 | if len(base_dir) == 0: 50 | base_dir = '.' 51 | 52 | dstfile = cpy.compile(srcfile, base_dir, base_dir + '/_cpy_') 53 | 54 | #print ('-----') 55 | #print (''.join(open(dstfile, 'r').readlines())) 56 | #print ('-----') 57 | 58 | dstfile = os.path.abspath(dstfile) 59 | sys.path.append(os.path.dirname(os.path.abspath(srcfile))); 60 | sys.path.append(os.path.dirname(os.path.abspath(dstfile))); 61 | 62 | os.chdir(os.path.dirname(os.path.abspath(srcfile))); 63 | #print os.getcwd(); 64 | 65 | if not is_compile: 66 | sys.argv = sys.argv[1 :] 67 | sys.path.insert(0, os.path.dirname(dstfile)) 68 | try: 69 | execfile(dstfile) 70 | except Exception: 71 | import traceback 72 | sys.stderr.write(traceback.format_exc()) 73 | pass 74 | -------------------------------------------------------------------------------- /deps/cpy/samples/class.cpy: -------------------------------------------------------------------------------- 1 | class A{ 2 | public a = 0; 3 | public static s = 1; 4 | 5 | function init(a){ 6 | this.a = a; 7 | print 'A init', a; 8 | } 9 | 10 | function f(a, b=1){ 11 | return a + b; 12 | } 13 | } 14 | 15 | print A.s; // 1 16 | a = new A(1); // A init 1 17 | print a.f(1, 2); 18 | -------------------------------------------------------------------------------- /deps/cpy/samples/extends.cpy: -------------------------------------------------------------------------------- 1 | class A{ 2 | function f(){ 3 | print 'A.f'; 4 | } 5 | } 6 | class B extends A{ 7 | function g(){ 8 | print "B.g"; 9 | } 10 | } 11 | 12 | b = new B(); 13 | b.f(); 14 | b.g(); 15 | -------------------------------------------------------------------------------- /deps/cpy/samples/foreach.cpy: -------------------------------------------------------------------------------- 1 | 2 | arr = [10, 11, 12]; 3 | foreach(arr as k=>v){ 4 | print k, v; 5 | } 6 | 7 | # output: # 8 | 9 | d = { 10 | 'a': 1, 11 | 'b': 2, 12 | 'c': 3, 13 | }; 14 | 15 | foreach(d as k=>v){ 16 | print k, v; 17 | } 18 | -------------------------------------------------------------------------------- /deps/cpy/samples/function.cpy: -------------------------------------------------------------------------------- 1 | 2 | function f(a, b=1){ 3 | return a + b; 4 | } 5 | 6 | print f(1); 7 | print f(1, 2); 8 | 9 | -------------------------------------------------------------------------------- /deps/cpy/samples/hello.cpy: -------------------------------------------------------------------------------- 1 | 2 | printf("Hello World!\n"); 3 | -------------------------------------------------------------------------------- /deps/cpy/samples/list.cpy: -------------------------------------------------------------------------------- 1 | a = []; // empty array 2 | a.append(1); 3 | a.append(2); 4 | print a[0]; // output: 1 5 | print a; // output: [1, 2] 6 | 7 | a = [1, 2]; 8 | print a; 9 | -------------------------------------------------------------------------------- /deps/cpy/samples/object.cpy: -------------------------------------------------------------------------------- 1 | 2 | a = {}; // empty dictionary 3 | a['x'] = [1, 2]; 4 | a['y'] = [3, 4]; 5 | foreach(a as k=>v1, v2){ 6 | printf('%s: %d, %d\n', k, v1, v2); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /deps/cpy/samples/simple_client.cpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideawu/ssdb/f229ba277c7f7d0ca5a441c0c6fb3d1209af68e4/deps/cpy/samples/simple_client.cpy -------------------------------------------------------------------------------- /deps/cpy/samples/simple_server.cpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideawu/ssdb/f229ba277c7f7d0ca5a441c0c6fb3d1209af68e4/deps/cpy/samples/simple_server.cpy -------------------------------------------------------------------------------- /deps/cpy/samples/stdin.cpy: -------------------------------------------------------------------------------- 1 | 2 | 3 | print "input 'q' to quit:"; 4 | 5 | while(true){ 6 | printf("> "); 7 | line = stdin.readline(); 8 | line = line.strip().lower(); 9 | if(line == 'q'){ 10 | print "bye."; 11 | break; 12 | }else{ 13 | print 'your input:', repr(line); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /deps/cpy/samples/test.cpy: -------------------------------------------------------------------------------- 1 | a = {}; // empty dictionary 2 | a['x'] = 1; 3 | a['y'] = 2; 4 | foreach(a as k,v){ 5 | print k, v; 6 | } 7 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/.autom4te.cfg: -------------------------------------------------------------------------------- 1 | begin-language: "Autoconf-without-aclocal-m4" 2 | args: --no-cache 3 | end-language: "Autoconf-without-aclocal-m4" 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/COPYING: -------------------------------------------------------------------------------- 1 | Unless otherwise specified, files in the jemalloc source distribution are 2 | subject to the following license: 3 | -------------------------------------------------------------------------------- 4 | Copyright (C) 2002-2015 Jason Evans . 5 | All rights reserved. 6 | Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. 7 | Copyright (C) 2009-2015 Facebook, Inc. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 1. Redistributions of source code must retain the above copyright notice(s), 12 | this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright notice(s), 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS 18 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/README: -------------------------------------------------------------------------------- 1 | jemalloc is a general purpose malloc(3) implementation that emphasizes 2 | fragmentation avoidance and scalable concurrency support. jemalloc first came 3 | into use as the FreeBSD libc allocator in 2005, and since then it has found its 4 | way into numerous applications that rely on its predictable behavior. In 2010 5 | jemalloc development efforts broadened to include developer support features 6 | such as heap profiling, Valgrind integration, and extensive monitoring/tuning 7 | hooks. Modern jemalloc releases continue to be integrated back into FreeBSD, 8 | and therefore versatility remains critical. Ongoing development efforts trend 9 | toward making jemalloc among the best allocators for a broad range of demanding 10 | applications, and eliminating/mitigating weaknesses that have practical 11 | repercussions for real world applications. 12 | 13 | The COPYING file contains copyright and licensing information. 14 | 15 | The INSTALL file contains information on how to configure, build, and install 16 | jemalloc. 17 | 18 | The ChangeLog file contains a brief summary of changes for each release. 19 | 20 | URL: http://www.canonware.com/jemalloc/ 21 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in autoconf; do 4 | echo "$i" 5 | $i 6 | if [ $? -ne 0 ]; then 7 | echo "Error $? in $i" 8 | exit 1 9 | fi 10 | done 11 | 12 | echo "./configure --enable-autogen $@" 13 | ./configure --enable-autogen $@ 14 | if [ $? -ne 0 ]; then 15 | echo "Error $? in ./configure" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/bin/jemalloc-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | usage() { 4 | cat < 7 | Options: 8 | --help | -h : Print usage. 9 | --version : Print jemalloc version. 10 | --revision : Print shared library revision number. 11 | --config : Print configure options used to build jemalloc. 12 | --prefix : Print installation directory prefix. 13 | --bindir : Print binary installation directory. 14 | --datadir : Print data installation directory. 15 | --includedir : Print include installation directory. 16 | --libdir : Print library installation directory. 17 | --mandir : Print manual page installation directory. 18 | --cc : Print compiler used to build jemalloc. 19 | --cflags : Print compiler flags used to build jemalloc. 20 | --cppflags : Print preprocessor flags used to build jemalloc. 21 | --ldflags : Print library flags used to build jemalloc. 22 | --libs : Print libraries jemalloc was linked against. 23 | EOF 24 | } 25 | 26 | prefix="@prefix@" 27 | exec_prefix="@exec_prefix@" 28 | 29 | case "$1" in 30 | --help | -h) 31 | usage 32 | exit 0 33 | ;; 34 | --version) 35 | echo "@jemalloc_version@" 36 | ;; 37 | --revision) 38 | echo "@rev@" 39 | ;; 40 | --config) 41 | echo "@CONFIG@" 42 | ;; 43 | --prefix) 44 | echo "@PREFIX@" 45 | ;; 46 | --bindir) 47 | echo "@BINDIR@" 48 | ;; 49 | --datadir) 50 | echo "@DATADIR@" 51 | ;; 52 | --includedir) 53 | echo "@INCLUDEDIR@" 54 | ;; 55 | --libdir) 56 | echo "@LIBDIR@" 57 | ;; 58 | --mandir) 59 | echo "@MANDIR@" 60 | ;; 61 | --cc) 62 | echo "@CC@" 63 | ;; 64 | --cflags) 65 | echo "@CFLAGS@" 66 | ;; 67 | --cppflags) 68 | echo "@CPPFLAGS@" 69 | ;; 70 | --ldflags) 71 | echo "@LDFLAGS@ @EXTRA_LDFLAGS@" 72 | ;; 73 | --libs) 74 | echo "@LIBS@" 75 | ;; 76 | *) 77 | usage 78 | exit 1 79 | esac 80 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/bin/jemalloc.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | libdir=@libdir@ 6 | 7 | @LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@ 8 | export @LD_PRELOAD_VAR@ 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/config.stamp.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideawu/ssdb/f229ba277c7f7d0ca5a441c0c6fb3d1209af68e4/deps/jemalloc-4.1.0/config.stamp.in -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | objdir=$1 6 | suffix=$2 7 | shift 2 8 | objs=$@ 9 | 10 | gcov -b -p -f -o "${objdir}" ${objs} 11 | 12 | # Move gcov outputs so that subsequent gcov invocations won't clobber results 13 | # for the same sources with different compilation flags. 14 | for f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do 15 | mv "${f}" "${f}.${suffix}" 16 | done 17 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/doc/html.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/doc/manpages.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/doc/stylesheet.xsl: -------------------------------------------------------------------------------- 1 | 2 | ansi 3 | 4 | 5 | "" 6 | 7 | 8 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Define a custom assert() in order to reduce the chances of deadlock during 3 | * assertion failure. 4 | */ 5 | #ifndef assert 6 | #define assert(e) do { \ 7 | if (unlikely(config_debug && !(e))) { \ 8 | malloc_printf( \ 9 | ": %s:%d: Failed assertion: \"%s\"\n", \ 10 | __FILE__, __LINE__, #e); \ 11 | abort(); \ 12 | } \ 13 | } while (0) 14 | #endif 15 | 16 | #ifndef not_reached 17 | #define not_reached() do { \ 18 | if (config_debug) { \ 19 | malloc_printf( \ 20 | ": %s:%d: Unreachable code reached\n", \ 21 | __FILE__, __LINE__); \ 22 | abort(); \ 23 | } \ 24 | unreachable(); \ 25 | } while (0) 26 | #endif 27 | 28 | #ifndef not_implemented 29 | #define not_implemented() do { \ 30 | if (config_debug) { \ 31 | malloc_printf(": %s:%d: Not implemented\n", \ 32 | __FILE__, __LINE__); \ 33 | abort(); \ 34 | } \ 35 | } while (0) 36 | #endif 37 | 38 | #ifndef assert_not_implemented 39 | #define assert_not_implemented(e) do { \ 40 | if (unlikely(config_debug && !(e))) \ 41 | not_implemented(); \ 42 | } while (0) 43 | #endif 44 | 45 | 46 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/base.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *base_alloc(size_t size); 13 | void base_stats_get(size_t *allocated, size_t *resident, size_t *mapped); 14 | bool base_boot(void); 15 | void base_prefork(void); 16 | void base_postfork_parent(void); 17 | void base_postfork_child(void); 18 | 19 | #endif /* JEMALLOC_H_EXTERNS */ 20 | /******************************************************************************/ 21 | #ifdef JEMALLOC_H_INLINES 22 | 23 | #endif /* JEMALLOC_H_INLINES */ 24 | /******************************************************************************/ 25 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/chunk_dss.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef enum { 5 | dss_prec_disabled = 0, 6 | dss_prec_primary = 1, 7 | dss_prec_secondary = 2, 8 | 9 | dss_prec_limit = 3 10 | } dss_prec_t; 11 | #define DSS_PREC_DEFAULT dss_prec_secondary 12 | #define DSS_DEFAULT "secondary" 13 | 14 | #endif /* JEMALLOC_H_TYPES */ 15 | /******************************************************************************/ 16 | #ifdef JEMALLOC_H_STRUCTS 17 | 18 | extern const char *dss_prec_names[]; 19 | 20 | #endif /* JEMALLOC_H_STRUCTS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_EXTERNS 23 | 24 | dss_prec_t chunk_dss_prec_get(void); 25 | bool chunk_dss_prec_set(dss_prec_t dss_prec); 26 | void *chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, 27 | size_t alignment, bool *zero, bool *commit); 28 | bool chunk_in_dss(void *chunk); 29 | bool chunk_dss_boot(void); 30 | void chunk_dss_prefork(void); 31 | void chunk_dss_postfork_parent(void); 32 | void chunk_dss_postfork_child(void); 33 | 34 | #endif /* JEMALLOC_H_EXTERNS */ 35 | /******************************************************************************/ 36 | #ifdef JEMALLOC_H_INLINES 37 | 38 | #endif /* JEMALLOC_H_INLINES */ 39 | /******************************************************************************/ 40 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/chunk_mmap.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, 13 | bool *zero, bool *commit); 14 | bool chunk_dalloc_mmap(void *chunk, size_t size); 15 | 16 | #endif /* JEMALLOC_H_EXTERNS */ 17 | /******************************************************************************/ 18 | #ifdef JEMALLOC_H_INLINES 19 | 20 | #endif /* JEMALLOC_H_INLINES */ 21 | /******************************************************************************/ 22 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/huge.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *huge_malloc(tsd_t *tsd, arena_t *arena, size_t usize, bool zero, 13 | tcache_t *tcache); 14 | void *huge_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment, 15 | bool zero, tcache_t *tcache); 16 | bool huge_ralloc_no_move(tsd_t *tsd, void *ptr, size_t oldsize, 17 | size_t usize_min, size_t usize_max, bool zero); 18 | void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, 19 | size_t usize, size_t alignment, bool zero, tcache_t *tcache); 20 | #ifdef JEMALLOC_JET 21 | typedef void (huge_dalloc_junk_t)(void *, size_t); 22 | extern huge_dalloc_junk_t *huge_dalloc_junk; 23 | #endif 24 | void huge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache); 25 | arena_t *huge_aalloc(const void *ptr); 26 | size_t huge_salloc(const void *ptr); 27 | prof_tctx_t *huge_prof_tctx_get(const void *ptr); 28 | void huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx); 29 | void huge_prof_tctx_reset(const void *ptr); 30 | 31 | #endif /* JEMALLOC_H_EXTERNS */ 32 | /******************************************************************************/ 33 | #ifdef JEMALLOC_H_INLINES 34 | 35 | #endif /* JEMALLOC_H_INLINES */ 36 | /******************************************************************************/ 37 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal_decls.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_DECLS_H 2 | #define JEMALLOC_INTERNAL_DECLS_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | # include 7 | # include "msvc_compat/windows_extra.h" 8 | 9 | #else 10 | # include 11 | # include 12 | # if !defined(__pnacl__) && !defined(__native_client__) 13 | # include 14 | # if !defined(SYS_write) && defined(__NR_write) 15 | # define SYS_write __NR_write 16 | # endif 17 | # include 18 | # endif 19 | # include 20 | # include 21 | # include 22 | #endif 23 | #include 24 | 25 | #include 26 | #ifndef SIZE_T_MAX 27 | # define SIZE_T_MAX SIZE_MAX 28 | #endif 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #ifndef offsetof 36 | # define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) 37 | #endif 38 | #include 39 | #include 40 | #include 41 | #ifdef _MSC_VER 42 | # include 43 | typedef intptr_t ssize_t; 44 | # define PATH_MAX 1024 45 | # define STDERR_FILENO 2 46 | # define __func__ __FUNCTION__ 47 | # ifdef JEMALLOC_HAS_RESTRICT 48 | # define restrict __restrict 49 | # endif 50 | /* Disable warnings about deprecated system functions. */ 51 | # pragma warning(disable: 4996) 52 | #if _MSC_VER < 1800 53 | static int 54 | isblank(int c) 55 | { 56 | 57 | return (c == '\t' || c == ' '); 58 | } 59 | #endif 60 | #else 61 | # include 62 | #endif 63 | #include 64 | 65 | #endif /* JEMALLOC_INTERNAL_H */ 66 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/jemalloc_internal_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for 3 | * functions that are static inline functions if inlining is enabled, and 4 | * single-definition library-private functions if inlining is disabled. 5 | * 6 | * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in 7 | * which case the denoted functions are always static, regardless of whether 8 | * inlining is enabled. 9 | */ 10 | #if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE) 11 | /* Disable inlining to make debugging/profiling easier. */ 12 | # define JEMALLOC_ALWAYS_INLINE 13 | # define JEMALLOC_ALWAYS_INLINE_C static 14 | # define JEMALLOC_INLINE 15 | # define JEMALLOC_INLINE_C static 16 | # define inline 17 | #else 18 | # define JEMALLOC_ENABLE_INLINE 19 | # ifdef JEMALLOC_HAVE_ATTR 20 | # define JEMALLOC_ALWAYS_INLINE \ 21 | static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) 22 | # define JEMALLOC_ALWAYS_INLINE_C \ 23 | static inline JEMALLOC_ATTR(always_inline) 24 | # else 25 | # define JEMALLOC_ALWAYS_INLINE static inline 26 | # define JEMALLOC_ALWAYS_INLINE_C static inline 27 | # endif 28 | # define JEMALLOC_INLINE static inline 29 | # define JEMALLOC_INLINE_C static inline 30 | # ifdef _MSC_VER 31 | # define inline _inline 32 | # endif 33 | #endif 34 | 35 | #ifdef JEMALLOC_CC_SILENCE 36 | # define UNUSED JEMALLOC_ATTR(unused) 37 | #else 38 | # define UNUSED 39 | #endif 40 | 41 | #define ZU(z) ((size_t)z) 42 | #define ZI(z) ((ssize_t)z) 43 | #define QU(q) ((uint64_t)q) 44 | #define QI(q) ((int64_t)q) 45 | 46 | #define KZU(z) ZU(z##ULL) 47 | #define KZI(z) ZI(z##LL) 48 | #define KQU(q) QU(q##ULL) 49 | #define KQI(q) QI(q##LL) 50 | 51 | #ifndef __DECONST 52 | # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) 53 | #endif 54 | 55 | #ifndef JEMALLOC_HAS_RESTRICT 56 | # define restrict 57 | #endif 58 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/nstime.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \ 5 | && _POSIX_MONOTONIC_CLOCK >= 0 6 | 7 | typedef struct nstime_s nstime_t; 8 | 9 | /* Maximum supported number of seconds (~584 years). */ 10 | #define NSTIME_SEC_MAX 18446744072 11 | 12 | #endif /* JEMALLOC_H_TYPES */ 13 | /******************************************************************************/ 14 | #ifdef JEMALLOC_H_STRUCTS 15 | 16 | struct nstime_s { 17 | uint64_t ns; 18 | }; 19 | 20 | #endif /* JEMALLOC_H_STRUCTS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_EXTERNS 23 | 24 | void nstime_init(nstime_t *time, uint64_t ns); 25 | void nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec); 26 | uint64_t nstime_ns(const nstime_t *time); 27 | uint64_t nstime_sec(const nstime_t *time); 28 | uint64_t nstime_nsec(const nstime_t *time); 29 | void nstime_copy(nstime_t *time, const nstime_t *source); 30 | int nstime_compare(const nstime_t *a, const nstime_t *b); 31 | void nstime_add(nstime_t *time, const nstime_t *addend); 32 | void nstime_subtract(nstime_t *time, const nstime_t *subtrahend); 33 | void nstime_imultiply(nstime_t *time, uint64_t multiplier); 34 | void nstime_idivide(nstime_t *time, uint64_t divisor); 35 | uint64_t nstime_divide(const nstime_t *time, const nstime_t *divisor); 36 | #ifdef JEMALLOC_JET 37 | typedef bool (nstime_update_t)(nstime_t *); 38 | extern nstime_update_t *nstime_update; 39 | #else 40 | bool nstime_update(nstime_t *time); 41 | #endif 42 | 43 | #endif /* JEMALLOC_H_EXTERNS */ 44 | /******************************************************************************/ 45 | #ifdef JEMALLOC_H_INLINES 46 | 47 | #endif /* JEMALLOC_H_INLINES */ 48 | /******************************************************************************/ 49 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/pages.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *pages_map(void *addr, size_t size); 13 | void pages_unmap(void *addr, size_t size); 14 | void *pages_trim(void *addr, size_t alloc_size, size_t leadsize, 15 | size_t size); 16 | bool pages_commit(void *addr, size_t size); 17 | bool pages_decommit(void *addr, size_t size); 18 | bool pages_purge(void *addr, size_t size); 19 | 20 | #endif /* JEMALLOC_H_EXTERNS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_INLINES 23 | 24 | #endif /* JEMALLOC_H_INLINES */ 25 | /******************************************************************************/ 26 | 27 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/private_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#define ${symbol} JEMALLOC_N(${symbol})" 5 | done 6 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/private_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#undef ${symbol}" 5 | done 6 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/public_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#define je_${n} JEMALLOC_N(${n})" 6 | done 7 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/public_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#undef je_${n}" 6 | done 7 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/quarantine.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct quarantine_obj_s quarantine_obj_t; 5 | typedef struct quarantine_s quarantine_t; 6 | 7 | /* Default per thread quarantine size if valgrind is enabled. */ 8 | #define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24) 9 | 10 | #endif /* JEMALLOC_H_TYPES */ 11 | /******************************************************************************/ 12 | #ifdef JEMALLOC_H_STRUCTS 13 | 14 | struct quarantine_obj_s { 15 | void *ptr; 16 | size_t usize; 17 | }; 18 | 19 | struct quarantine_s { 20 | size_t curbytes; 21 | size_t curobjs; 22 | size_t first; 23 | #define LG_MAXOBJS_INIT 10 24 | size_t lg_maxobjs; 25 | quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */ 26 | }; 27 | 28 | #endif /* JEMALLOC_H_STRUCTS */ 29 | /******************************************************************************/ 30 | #ifdef JEMALLOC_H_EXTERNS 31 | 32 | void quarantine_alloc_hook_work(tsd_t *tsd); 33 | void quarantine(tsd_t *tsd, void *ptr); 34 | void quarantine_cleanup(tsd_t *tsd); 35 | 36 | #endif /* JEMALLOC_H_EXTERNS */ 37 | /******************************************************************************/ 38 | #ifdef JEMALLOC_H_INLINES 39 | 40 | #ifndef JEMALLOC_ENABLE_INLINE 41 | void quarantine_alloc_hook(void); 42 | #endif 43 | 44 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_)) 45 | JEMALLOC_ALWAYS_INLINE void 46 | quarantine_alloc_hook(void) 47 | { 48 | tsd_t *tsd; 49 | 50 | assert(config_fill && opt_quarantine); 51 | 52 | tsd = tsd_fetch(); 53 | if (tsd_quarantine_get(tsd) == NULL) 54 | quarantine_alloc_hook_work(tsd); 55 | } 56 | #endif 57 | 58 | #endif /* JEMALLOC_H_INLINES */ 59 | /******************************************************************************/ 60 | 61 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/internal/ticker.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct ticker_s ticker_t; 5 | 6 | #endif /* JEMALLOC_H_TYPES */ 7 | /******************************************************************************/ 8 | #ifdef JEMALLOC_H_STRUCTS 9 | 10 | struct ticker_s { 11 | int32_t tick; 12 | int32_t nticks; 13 | }; 14 | 15 | #endif /* JEMALLOC_H_STRUCTS */ 16 | /******************************************************************************/ 17 | #ifdef JEMALLOC_H_EXTERNS 18 | 19 | #endif /* JEMALLOC_H_EXTERNS */ 20 | /******************************************************************************/ 21 | #ifdef JEMALLOC_H_INLINES 22 | 23 | #ifndef JEMALLOC_ENABLE_INLINE 24 | void ticker_init(ticker_t *ticker, int32_t nticks); 25 | void ticker_copy(ticker_t *ticker, const ticker_t *other); 26 | int32_t ticker_read(const ticker_t *ticker); 27 | bool ticker_ticks(ticker_t *ticker, int32_t nticks); 28 | bool ticker_tick(ticker_t *ticker); 29 | #endif 30 | 31 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TICKER_C_)) 32 | JEMALLOC_INLINE void 33 | ticker_init(ticker_t *ticker, int32_t nticks) 34 | { 35 | 36 | ticker->tick = nticks; 37 | ticker->nticks = nticks; 38 | } 39 | 40 | JEMALLOC_INLINE void 41 | ticker_copy(ticker_t *ticker, const ticker_t *other) 42 | { 43 | 44 | *ticker = *other; 45 | } 46 | 47 | JEMALLOC_INLINE int32_t 48 | ticker_read(const ticker_t *ticker) 49 | { 50 | 51 | return (ticker->tick); 52 | } 53 | 54 | JEMALLOC_INLINE bool 55 | ticker_ticks(ticker_t *ticker, int32_t nticks) 56 | { 57 | 58 | if (unlikely(ticker->tick < nticks)) { 59 | ticker->tick = ticker->nticks; 60 | return (true); 61 | } 62 | ticker->tick -= nticks; 63 | return(false); 64 | } 65 | 66 | JEMALLOC_INLINE bool 67 | ticker_tick(ticker_t *ticker) 68 | { 69 | 70 | return (ticker_ticks(ticker, 1)); 71 | } 72 | #endif 73 | 74 | #endif /* JEMALLOC_H_INLINES */ 75 | /******************************************************************************/ 76 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/jemalloc/jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | objroot=$1 4 | 5 | cat < 5 | 6 | /* MSVC doesn't define _Bool or bool in C, but does have BOOL */ 7 | /* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ 8 | /* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as 9 | * a built-in type. */ 10 | #ifndef __clang__ 11 | typedef BOOL _Bool; 12 | #endif 13 | 14 | #define bool _Bool 15 | #define true 1 16 | #define false 0 17 | 18 | #define __bool_true_false_are_defined 1 19 | 20 | #endif /* stdbool_h */ 21 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/msvc_compat/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef strings_h 2 | #define strings_h 3 | 4 | /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided 5 | * for both */ 6 | #ifdef _MSC_VER 7 | # include 8 | # pragma intrinsic(_BitScanForward) 9 | static __forceinline int ffsl(long x) 10 | { 11 | unsigned long i; 12 | 13 | if (_BitScanForward(&i, x)) 14 | return (i + 1); 15 | return (0); 16 | } 17 | 18 | static __forceinline int ffs(int x) 19 | { 20 | 21 | return (ffsl(x)); 22 | } 23 | 24 | # ifdef _M_X64 25 | # pragma intrinsic(_BitScanForward64) 26 | # endif 27 | 28 | static __forceinline int ffsll(unsigned __int64 x) 29 | { 30 | unsigned long i; 31 | #ifdef _M_X64 32 | if (_BitScanForward64(&i, x)) 33 | return (i + 1); 34 | return (0); 35 | #else 36 | // Fallback for 32-bit build where 64-bit version not available 37 | // assuming little endian 38 | union { 39 | unsigned __int64 ll; 40 | unsigned long l[2]; 41 | } s; 42 | 43 | s.ll = x; 44 | 45 | if (_BitScanForward(&i, s.l[0])) 46 | return (i + 1); 47 | else if(_BitScanForward(&i, s.l[1])) 48 | return (i + 33); 49 | return (0); 50 | #endif 51 | } 52 | 53 | #else 54 | # define ffsll(x) __builtin_ffsll(x) 55 | # define ffsl(x) __builtin_ffsl(x) 56 | # define ffs(x) __builtin_ffs(x) 57 | #endif 58 | 59 | #endif /* strings_h */ 60 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/include/msvc_compat/windows_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef MSVC_COMPAT_WINDOWS_EXTRA_H 2 | #define MSVC_COMPAT_WINDOWS_EXTRA_H 3 | 4 | #ifndef ENOENT 5 | # define ENOENT ERROR_PATH_NOT_FOUND 6 | #endif 7 | #ifndef EINVAL 8 | # define EINVAL ERROR_BAD_ARGUMENTS 9 | #endif 10 | #ifndef EAGAIN 11 | # define EAGAIN ERROR_OUTOFMEMORY 12 | #endif 13 | #ifndef EPERM 14 | # define EPERM ERROR_WRITE_FAULT 15 | #endif 16 | #ifndef EFAULT 17 | # define EFAULT ERROR_INVALID_ADDRESS 18 | #endif 19 | #ifndef ENOMEM 20 | # define ENOMEM ERROR_NOT_ENOUGH_MEMORY 21 | #endif 22 | #ifndef ERANGE 23 | # define ERANGE ERROR_INVALID_DATA 24 | #endif 25 | 26 | #endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ 27 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/jemalloc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | install_suffix=@install_suffix@ 6 | 7 | Name: jemalloc 8 | Description: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. 9 | URL: http://www.canonware.com/jemalloc 10 | Version: @jemalloc_version@ 11 | Cflags: -I${includedir} 12 | Libs: -L${libdir} -ljemalloc${install_suffix} 13 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/msvc/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 2 | How to build jemalloc for Windows 3 | ================================= 4 | 5 | 1. Install Cygwin with at least the following packages: 6 | * autoconf 7 | * autogen 8 | * gawk 9 | * grep 10 | * sed 11 | 12 | 2. Install Visual Studio 2015 with Visual C++ 13 | 14 | 3. Add Cygwin\bin to the PATH environment variable 15 | 16 | 4. Open "VS2015 x86 Native Tools Command Prompt" 17 | (note: x86/x64 doesn't matter at this point) 18 | 19 | 5. Generate header files: 20 | sh -c "./autogen.sh CC=cl --enable-lazy-lock=no" 21 | 22 | 6. Now the project can be opened and built in Visual Studio: 23 | msvc\jemalloc_vc2015.sln 24 | 25 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int test_threads(); 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/msvc/projects/vc2015/test_threads/test_threads_main.cpp: -------------------------------------------------------------------------------- 1 | #include "test_threads.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std::chrono_literals; 7 | 8 | int main(int argc, char** argv) 9 | { 10 | int rc = test_threads(); 11 | return rc; 12 | } 13 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/atomic.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_ATOMIC_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/extent.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | JEMALLOC_INLINE_C size_t 7 | extent_quantize(size_t size) 8 | { 9 | 10 | /* 11 | * Round down to the nearest chunk size that can actually be requested 12 | * during normal huge allocation. 13 | */ 14 | return (index2size(size2index(size + 1) - 1)); 15 | } 16 | 17 | JEMALLOC_INLINE_C int 18 | extent_szad_comp(const extent_node_t *a, const extent_node_t *b) 19 | { 20 | int ret; 21 | size_t a_qsize = extent_quantize(extent_node_size_get(a)); 22 | size_t b_qsize = extent_quantize(extent_node_size_get(b)); 23 | 24 | /* 25 | * Compare based on quantized size rather than size, in order to sort 26 | * equally useful extents only by address. 27 | */ 28 | ret = (a_qsize > b_qsize) - (a_qsize < b_qsize); 29 | if (ret == 0) { 30 | uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); 31 | uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); 32 | 33 | ret = (a_addr > b_addr) - (a_addr < b_addr); 34 | } 35 | 36 | return (ret); 37 | } 38 | 39 | /* Generate red-black tree functions. */ 40 | rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, szad_link, 41 | extent_szad_comp) 42 | 43 | JEMALLOC_INLINE_C int 44 | extent_ad_comp(const extent_node_t *a, const extent_node_t *b) 45 | { 46 | uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); 47 | uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); 48 | 49 | return ((a_addr > b_addr) - (a_addr < b_addr)); 50 | } 51 | 52 | /* Generate red-black tree functions. */ 53 | rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp) 54 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/hash.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_HASH_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/mb.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MB_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/prng.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_PRNG_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/ticker.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TICKER_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/src/valgrind.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal.h" 2 | #ifndef JEMALLOC_VALGRIND 3 | # error "This source file is for Valgrind integration." 4 | #endif 5 | 6 | #include 7 | 8 | void 9 | valgrind_make_mem_noaccess(void *ptr, size_t usize) 10 | { 11 | 12 | VALGRIND_MAKE_MEM_NOACCESS(ptr, usize); 13 | } 14 | 15 | void 16 | valgrind_make_mem_undefined(void *ptr, size_t usize) 17 | { 18 | 19 | VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize); 20 | } 21 | 22 | void 23 | valgrind_make_mem_defined(void *ptr, size_t usize) 24 | { 25 | 26 | VALGRIND_MAKE_MEM_DEFINED(ptr, usize); 27 | } 28 | 29 | void 30 | valgrind_freelike_block(void *ptr, size_t usize) 31 | { 32 | 33 | VALGRIND_FREELIKE_BLOCK(ptr, usize); 34 | } 35 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/include/test/btalloc.h: -------------------------------------------------------------------------------- 1 | /* btalloc() provides a mechanism for allocating via permuted backtraces. */ 2 | void *btalloc(size_t size, unsigned bits); 3 | 4 | #define btalloc_n_proto(n) \ 5 | void *btalloc_##n(size_t size, unsigned bits); 6 | btalloc_n_proto(0) 7 | btalloc_n_proto(1) 8 | 9 | #define btalloc_n_gen(n) \ 10 | void * \ 11 | btalloc_##n(size_t size, unsigned bits) \ 12 | { \ 13 | void *p; \ 14 | \ 15 | if (bits == 0) \ 16 | p = mallocx(size, 0); \ 17 | else { \ 18 | switch (bits & 0x1U) { \ 19 | case 0: \ 20 | p = (btalloc_0(size, bits >> 1)); \ 21 | break; \ 22 | case 1: \ 23 | p = (btalloc_1(size, bits >> 1)); \ 24 | break; \ 25 | default: not_reached(); \ 26 | } \ 27 | } \ 28 | /* Intentionally sabotage tail call optimization. */ \ 29 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); \ 30 | return (p); \ 31 | } 32 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/include/test/jemalloc_test_defs.h.in: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal_defs.h" 2 | #include "jemalloc/internal/jemalloc_internal_decls.h" 3 | 4 | /* 5 | * For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its 6 | * dependencies are notoriously unportable in practice. 7 | */ 8 | #undef HAVE_SSE2 9 | #undef HAVE_ALTIVEC 10 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/include/test/mtx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mtx is a slightly simplified version of malloc_mutex. This code duplication 3 | * is unfortunate, but there are allocator bootstrapping considerations that 4 | * would leak into the test infrastructure if malloc_mutex were used directly 5 | * in tests. 6 | */ 7 | 8 | typedef struct { 9 | #ifdef _WIN32 10 | CRITICAL_SECTION lock; 11 | #elif (defined(JEMALLOC_OSSPIN)) 12 | OSSpinLock lock; 13 | #else 14 | pthread_mutex_t lock; 15 | #endif 16 | } mtx_t; 17 | 18 | bool mtx_init(mtx_t *mtx); 19 | void mtx_fini(mtx_t *mtx); 20 | void mtx_lock(mtx_t *mtx); 21 | void mtx_unlock(mtx_t *mtx); 22 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/include/test/thd.h: -------------------------------------------------------------------------------- 1 | /* Abstraction layer for threading in tests. */ 2 | #ifdef _WIN32 3 | typedef HANDLE thd_t; 4 | #else 5 | typedef pthread_t thd_t; 6 | #endif 7 | 8 | void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); 9 | void thd_join(thd_t thd, void **ret); 10 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/include/test/timer.h: -------------------------------------------------------------------------------- 1 | /* Simple timer, for use in benchmark reporting. */ 2 | 3 | typedef struct { 4 | nstime_t t0; 5 | nstime_t t1; 6 | } timedelta_t; 7 | 8 | void timer_start(timedelta_t *timer); 9 | void timer_stop(timedelta_t *timer); 10 | uint64_t timer_usec(const timedelta_t *timer); 11 | void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen); 12 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/integration/MALLOCX_ARENA.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | static bool have_dss = 6 | #ifdef JEMALLOC_DSS 7 | true 8 | #else 9 | false 10 | #endif 11 | ; 12 | 13 | void * 14 | thd_start(void *arg) 15 | { 16 | unsigned thread_ind = (unsigned)(uintptr_t)arg; 17 | unsigned arena_ind; 18 | void *p; 19 | size_t sz; 20 | 21 | sz = sizeof(arena_ind); 22 | assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0, 23 | "Error in arenas.extend"); 24 | 25 | if (thread_ind % 4 != 3) { 26 | size_t mib[3]; 27 | size_t miblen = sizeof(mib) / sizeof(size_t); 28 | const char *dss_precs[] = {"disabled", "primary", "secondary"}; 29 | unsigned prec_ind = thread_ind % 30 | (sizeof(dss_precs)/sizeof(char*)); 31 | const char *dss = dss_precs[prec_ind]; 32 | int expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT; 33 | assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, 34 | "Error in mallctlnametomib()"); 35 | mib[1] = arena_ind; 36 | assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, 37 | sizeof(const char *)), expected_err, 38 | "Error in mallctlbymib()"); 39 | } 40 | 41 | p = mallocx(1, MALLOCX_ARENA(arena_ind)); 42 | assert_ptr_not_null(p, "Unexpected mallocx() error"); 43 | dallocx(p, 0); 44 | 45 | return (NULL); 46 | } 47 | 48 | TEST_BEGIN(test_MALLOCX_ARENA) 49 | { 50 | thd_t thds[NTHREADS]; 51 | unsigned i; 52 | 53 | for (i = 0; i < NTHREADS; i++) { 54 | thd_create(&thds[i], thd_start, 55 | (void *)(uintptr_t)i); 56 | } 57 | 58 | for (i = 0; i < NTHREADS; i++) 59 | thd_join(thds[i], NULL); 60 | } 61 | TEST_END 62 | 63 | int 64 | main(void) 65 | { 66 | 67 | return (test( 68 | test_MALLOCX_ARENA)); 69 | } 70 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/integration/overflow.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_overflow) 4 | { 5 | unsigned nhchunks; 6 | size_t mib[4]; 7 | size_t sz, miblen, max_size_class; 8 | void *p; 9 | 10 | sz = sizeof(unsigned); 11 | assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0, 12 | "Unexpected mallctl() error"); 13 | 14 | miblen = sizeof(mib) / sizeof(size_t); 15 | assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, 16 | "Unexpected mallctlnametomib() error"); 17 | mib[2] = nhchunks - 1; 18 | 19 | sz = sizeof(size_t); 20 | assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0, 21 | "Unexpected mallctlbymib() error"); 22 | 23 | assert_ptr_null(malloc(max_size_class + 1), 24 | "Expected OOM due to over-sized allocation request"); 25 | assert_ptr_null(malloc(SIZE_T_MAX), 26 | "Expected OOM due to over-sized allocation request"); 27 | 28 | assert_ptr_null(calloc(1, max_size_class + 1), 29 | "Expected OOM due to over-sized allocation request"); 30 | assert_ptr_null(calloc(1, SIZE_T_MAX), 31 | "Expected OOM due to over-sized allocation request"); 32 | 33 | p = malloc(1); 34 | assert_ptr_not_null(p, "Unexpected malloc() OOM"); 35 | assert_ptr_null(realloc(p, max_size_class + 1), 36 | "Expected OOM due to over-sized allocation request"); 37 | assert_ptr_null(realloc(p, SIZE_T_MAX), 38 | "Expected OOM due to over-sized allocation request"); 39 | free(p); 40 | } 41 | TEST_END 42 | 43 | int 44 | main(void) 45 | { 46 | 47 | return (test( 48 | test_overflow)); 49 | } 50 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/integration/sdallocx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define MAXALIGN (((size_t)1) << 25) 4 | #define NITER 4 5 | 6 | TEST_BEGIN(test_basic) 7 | { 8 | void *ptr = mallocx(64, 0); 9 | sdallocx(ptr, 64, 0); 10 | } 11 | TEST_END 12 | 13 | TEST_BEGIN(test_alignment_and_size) 14 | { 15 | size_t nsz, sz, alignment, total; 16 | unsigned i; 17 | void *ps[NITER]; 18 | 19 | for (i = 0; i < NITER; i++) 20 | ps[i] = NULL; 21 | 22 | for (alignment = 8; 23 | alignment <= MAXALIGN; 24 | alignment <<= 1) { 25 | total = 0; 26 | for (sz = 1; 27 | sz < 3 * alignment && sz < (1U << 31); 28 | sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 29 | for (i = 0; i < NITER; i++) { 30 | nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | 31 | MALLOCX_ZERO); 32 | ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | 33 | MALLOCX_ZERO); 34 | total += nsz; 35 | if (total >= (MAXALIGN << 1)) 36 | break; 37 | } 38 | for (i = 0; i < NITER; i++) { 39 | if (ps[i] != NULL) { 40 | sdallocx(ps[i], sz, 41 | MALLOCX_ALIGN(alignment)); 42 | ps[i] = NULL; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | TEST_END 49 | 50 | int 51 | main(void) 52 | { 53 | 54 | return (test( 55 | test_basic, 56 | test_alignment_and_size)); 57 | } 58 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/integration/thread_arena.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | void * 6 | thd_start(void *arg) 7 | { 8 | unsigned main_arena_ind = *(unsigned *)arg; 9 | void *p; 10 | unsigned arena_ind; 11 | size_t size; 12 | int err; 13 | 14 | p = malloc(1); 15 | assert_ptr_not_null(p, "Error in malloc()"); 16 | free(p); 17 | 18 | size = sizeof(arena_ind); 19 | if ((err = mallctl("thread.arena", &arena_ind, &size, &main_arena_ind, 20 | sizeof(main_arena_ind)))) { 21 | char buf[BUFERROR_BUF]; 22 | 23 | buferror(err, buf, sizeof(buf)); 24 | test_fail("Error in mallctl(): %s", buf); 25 | } 26 | 27 | size = sizeof(arena_ind); 28 | if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { 29 | char buf[BUFERROR_BUF]; 30 | 31 | buferror(err, buf, sizeof(buf)); 32 | test_fail("Error in mallctl(): %s", buf); 33 | } 34 | assert_u_eq(arena_ind, main_arena_ind, 35 | "Arena index should be same as for main thread"); 36 | 37 | return (NULL); 38 | } 39 | 40 | TEST_BEGIN(test_thread_arena) 41 | { 42 | void *p; 43 | unsigned arena_ind; 44 | size_t size; 45 | int err; 46 | thd_t thds[NTHREADS]; 47 | unsigned i; 48 | 49 | p = malloc(1); 50 | assert_ptr_not_null(p, "Error in malloc()"); 51 | 52 | size = sizeof(arena_ind); 53 | if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { 54 | char buf[BUFERROR_BUF]; 55 | 56 | buferror(err, buf, sizeof(buf)); 57 | test_fail("Error in mallctl(): %s", buf); 58 | } 59 | 60 | for (i = 0; i < NTHREADS; i++) { 61 | thd_create(&thds[i], thd_start, 62 | (void *)&arena_ind); 63 | } 64 | 65 | for (i = 0; i < NTHREADS; i++) { 66 | intptr_t join_ret; 67 | thd_join(thds[i], (void *)&join_ret); 68 | assert_zd_eq(join_ret, 0, "Unexpected thread join error"); 69 | } 70 | } 71 | TEST_END 72 | 73 | int 74 | main(void) 75 | { 76 | 77 | return (test( 78 | test_thread_arena)); 79 | } 80 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/btalloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void * 4 | btalloc(size_t size, unsigned bits) 5 | { 6 | 7 | return (btalloc_0(size, bits)); 8 | } 9 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/btalloc_0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(0) 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/btalloc_1.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(1) 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/math.c: -------------------------------------------------------------------------------- 1 | #define MATH_C_ 2 | #include "test/jemalloc_test.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/mq.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* 4 | * Sleep for approximately ns nanoseconds. No lower *nor* upper bound on sleep 5 | * time is guaranteed. 6 | */ 7 | void 8 | mq_nanosleep(unsigned ns) 9 | { 10 | 11 | assert(ns <= 1000*1000*1000); 12 | 13 | #ifdef _WIN32 14 | Sleep(ns / 1000); 15 | #else 16 | { 17 | struct timespec timeout; 18 | 19 | if (ns < 1000*1000*1000) { 20 | timeout.tv_sec = 0; 21 | timeout.tv_nsec = ns; 22 | } else { 23 | timeout.tv_sec = 1; 24 | timeout.tv_nsec = 0; 25 | } 26 | nanosleep(&timeout, NULL); 27 | } 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/mtx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifndef _CRT_SPINCOUNT 4 | #define _CRT_SPINCOUNT 4000 5 | #endif 6 | 7 | bool 8 | mtx_init(mtx_t *mtx) 9 | { 10 | 11 | #ifdef _WIN32 12 | if (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT)) 13 | return (true); 14 | #elif (defined(JEMALLOC_OSSPIN)) 15 | mtx->lock = 0; 16 | #else 17 | pthread_mutexattr_t attr; 18 | 19 | if (pthread_mutexattr_init(&attr) != 0) 20 | return (true); 21 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 22 | if (pthread_mutex_init(&mtx->lock, &attr) != 0) { 23 | pthread_mutexattr_destroy(&attr); 24 | return (true); 25 | } 26 | pthread_mutexattr_destroy(&attr); 27 | #endif 28 | return (false); 29 | } 30 | 31 | void 32 | mtx_fini(mtx_t *mtx) 33 | { 34 | 35 | #ifdef _WIN32 36 | #elif (defined(JEMALLOC_OSSPIN)) 37 | #else 38 | pthread_mutex_destroy(&mtx->lock); 39 | #endif 40 | } 41 | 42 | void 43 | mtx_lock(mtx_t *mtx) 44 | { 45 | 46 | #ifdef _WIN32 47 | EnterCriticalSection(&mtx->lock); 48 | #elif (defined(JEMALLOC_OSSPIN)) 49 | OSSpinLockLock(&mtx->lock); 50 | #else 51 | pthread_mutex_lock(&mtx->lock); 52 | #endif 53 | } 54 | 55 | void 56 | mtx_unlock(mtx_t *mtx) 57 | { 58 | 59 | #ifdef _WIN32 60 | LeaveCriticalSection(&mtx->lock); 61 | #elif (defined(JEMALLOC_OSSPIN)) 62 | OSSpinLockUnlock(&mtx->lock); 63 | #else 64 | pthread_mutex_unlock(&mtx->lock); 65 | #endif 66 | } 67 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/thd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef _WIN32 4 | void 5 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 6 | { 7 | LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; 8 | *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); 9 | if (*thd == NULL) 10 | test_fail("Error in CreateThread()\n"); 11 | } 12 | 13 | void 14 | thd_join(thd_t thd, void **ret) 15 | { 16 | 17 | if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) { 18 | DWORD exit_code; 19 | GetExitCodeThread(thd, (LPDWORD) &exit_code); 20 | *ret = (void *)(uintptr_t)exit_code; 21 | } 22 | } 23 | 24 | #else 25 | void 26 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 27 | { 28 | 29 | if (pthread_create(thd, NULL, proc, arg) != 0) 30 | test_fail("Error in pthread_create()\n"); 31 | } 32 | 33 | void 34 | thd_join(thd_t thd, void **ret) 35 | { 36 | 37 | pthread_join(thd, ret); 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/src/timer.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void 4 | timer_start(timedelta_t *timer) 5 | { 6 | 7 | nstime_init(&timer->t0, 0); 8 | nstime_update(&timer->t0); 9 | } 10 | 11 | void 12 | timer_stop(timedelta_t *timer) 13 | { 14 | 15 | nstime_copy(&timer->t1, &timer->t0); 16 | nstime_update(&timer->t1); 17 | } 18 | 19 | uint64_t 20 | timer_usec(const timedelta_t *timer) 21 | { 22 | nstime_t delta; 23 | 24 | nstime_copy(&delta, &timer->t1); 25 | nstime_subtract(&delta, &timer->t0); 26 | return (nstime_ns(&delta) / 1000); 27 | } 28 | 29 | void 30 | timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen) 31 | { 32 | uint64_t t0 = timer_usec(a); 33 | uint64_t t1 = timer_usec(b); 34 | uint64_t mult; 35 | unsigned i = 0; 36 | unsigned j; 37 | int n; 38 | 39 | /* Whole. */ 40 | n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1); 41 | i += n; 42 | if (i >= buflen) 43 | return; 44 | mult = 1; 45 | for (j = 0; j < n; j++) 46 | mult *= 10; 47 | 48 | /* Decimal. */ 49 | n = malloc_snprintf(&buf[i], buflen-i, "."); 50 | i += n; 51 | 52 | /* Fraction. */ 53 | while (i < buflen-1) { 54 | uint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10 55 | >= 5)) ? 1 : 0; 56 | n = malloc_snprintf(&buf[i], buflen-i, 57 | "%"FMTu64, (t0 * mult / t1) % 10 + round); 58 | i += n; 59 | mult *= 10; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/test.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case @abi@ in 4 | macho) 5 | export DYLD_FALLBACK_LIBRARY_PATH="@objroot@lib" 6 | ;; 7 | pecoff) 8 | export PATH="${PATH}:@objroot@lib" 9 | ;; 10 | *) 11 | ;; 12 | esac 13 | 14 | # Corresponds to test_status_t. 15 | pass_code=0 16 | skip_code=1 17 | fail_code=2 18 | 19 | pass_count=0 20 | skip_count=0 21 | fail_count=0 22 | for t in $@; do 23 | if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then 24 | echo 25 | fi 26 | echo "=== ${t} ===" 27 | ${t}@exe@ @abs_srcroot@ @abs_objroot@ 28 | result_code=$? 29 | case ${result_code} in 30 | ${pass_code}) 31 | pass_count=$((pass_count+1)) 32 | ;; 33 | ${skip_code}) 34 | skip_count=$((skip_count+1)) 35 | ;; 36 | ${fail_code}) 37 | fail_count=$((fail_count+1)) 38 | ;; 39 | *) 40 | echo "Test harness error" 1>&2 41 | exit 1 42 | esac 43 | done 44 | 45 | total_count=`expr ${pass_count} + ${skip_count} + ${fail_count}` 46 | echo 47 | echo "Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}" 48 | 49 | if [ ${fail_count} -eq 0 ] ; then 50 | exit 0 51 | else 52 | exit 1 53 | fi 54 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/junk_alloc.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TEST_JUNK_OPT "junk:alloc" 2 | #include "junk.c" 3 | #undef JEMALLOC_TEST_JUNK_OPT 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/junk_free.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TEST_JUNK_OPT "junk:free" 2 | #include "junk.c" 3 | #undef JEMALLOC_TEST_JUNK_OPT 4 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/lg_chunk.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* 4 | * Make sure that opt.lg_chunk clamping is sufficient. In practice, this test 5 | * program will fail a debug assertion during initialization and abort (rather 6 | * than the test soft-failing) if clamping is insufficient. 7 | */ 8 | const char *malloc_conf = "lg_chunk:0"; 9 | 10 | TEST_BEGIN(test_lg_chunk_clamp) 11 | { 12 | void *p; 13 | 14 | p = mallocx(1, 0); 15 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 16 | dallocx(p, 0); 17 | } 18 | TEST_END 19 | 20 | int 21 | main(void) 22 | { 23 | 24 | return (test( 25 | test_lg_chunk_clamp)); 26 | } 27 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/mtx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 2 4 | #define NINCRS 2000000 5 | 6 | TEST_BEGIN(test_mtx_basic) 7 | { 8 | mtx_t mtx; 9 | 10 | assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure"); 11 | mtx_lock(&mtx); 12 | mtx_unlock(&mtx); 13 | mtx_fini(&mtx); 14 | } 15 | TEST_END 16 | 17 | typedef struct { 18 | mtx_t mtx; 19 | unsigned x; 20 | } thd_start_arg_t; 21 | 22 | static void * 23 | thd_start(void *varg) 24 | { 25 | thd_start_arg_t *arg = (thd_start_arg_t *)varg; 26 | unsigned i; 27 | 28 | for (i = 0; i < NINCRS; i++) { 29 | mtx_lock(&arg->mtx); 30 | arg->x++; 31 | mtx_unlock(&arg->mtx); 32 | } 33 | return (NULL); 34 | } 35 | 36 | TEST_BEGIN(test_mtx_race) 37 | { 38 | thd_start_arg_t arg; 39 | thd_t thds[NTHREADS]; 40 | unsigned i; 41 | 42 | assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure"); 43 | arg.x = 0; 44 | for (i = 0; i < NTHREADS; i++) 45 | thd_create(&thds[i], thd_start, (void *)&arg); 46 | for (i = 0; i < NTHREADS; i++) 47 | thd_join(thds[i], NULL); 48 | assert_u_eq(arg.x, NTHREADS * NINCRS, 49 | "Race-related counter corruption"); 50 | } 51 | TEST_END 52 | 53 | int 54 | main(void) 55 | { 56 | 57 | return (test( 58 | test_mtx_basic, 59 | test_mtx_race)); 60 | } 61 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/prng.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_prng_lg_range) 4 | { 5 | uint64_t sa, sb, ra, rb; 6 | unsigned lg_range; 7 | 8 | sa = 42; 9 | ra = prng_lg_range(&sa, 64); 10 | sa = 42; 11 | rb = prng_lg_range(&sa, 64); 12 | assert_u64_eq(ra, rb, 13 | "Repeated generation should produce repeated results"); 14 | 15 | sb = 42; 16 | rb = prng_lg_range(&sb, 64); 17 | assert_u64_eq(ra, rb, 18 | "Equivalent generation should produce equivalent results"); 19 | 20 | sa = 42; 21 | ra = prng_lg_range(&sa, 64); 22 | rb = prng_lg_range(&sa, 64); 23 | assert_u64_ne(ra, rb, 24 | "Full-width results must not immediately repeat"); 25 | 26 | sa = 42; 27 | ra = prng_lg_range(&sa, 64); 28 | for (lg_range = 63; lg_range > 0; lg_range--) { 29 | sb = 42; 30 | rb = prng_lg_range(&sb, lg_range); 31 | assert_u64_eq((rb & (UINT64_C(0xffffffffffffffff) << lg_range)), 32 | 0, "High order bits should be 0, lg_range=%u", lg_range); 33 | assert_u64_eq(rb, (ra >> (64 - lg_range)), 34 | "Expected high order bits of full-width result, " 35 | "lg_range=%u", lg_range); 36 | } 37 | } 38 | TEST_END 39 | 40 | TEST_BEGIN(test_prng_range) 41 | { 42 | uint64_t range; 43 | #define MAX_RANGE 10000000 44 | #define RANGE_STEP 97 45 | #define NREPS 10 46 | 47 | for (range = 2; range < MAX_RANGE; range += RANGE_STEP) { 48 | uint64_t s; 49 | unsigned rep; 50 | 51 | s = range; 52 | for (rep = 0; rep < NREPS; rep++) { 53 | uint64_t r = prng_range(&s, range); 54 | 55 | assert_u64_lt(r, range, "Out of range"); 56 | } 57 | } 58 | } 59 | TEST_END 60 | 61 | int 62 | main(void) 63 | { 64 | 65 | return (test( 66 | test_prng_lg_range, 67 | test_prng_range)); 68 | } 69 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/prof_idump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef JEMALLOC_PROF 4 | const char *malloc_conf = 5 | "prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0," 6 | "lg_prof_interval:0"; 7 | #endif 8 | 9 | static bool did_prof_dump_open; 10 | 11 | static int 12 | prof_dump_open_intercept(bool propagate_err, const char *filename) 13 | { 14 | int fd; 15 | 16 | did_prof_dump_open = true; 17 | 18 | fd = open("/dev/null", O_WRONLY); 19 | assert_d_ne(fd, -1, "Unexpected open() failure"); 20 | 21 | return (fd); 22 | } 23 | 24 | TEST_BEGIN(test_idump) 25 | { 26 | bool active; 27 | void *p; 28 | 29 | test_skip_if(!config_prof); 30 | 31 | active = true; 32 | assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), 33 | 0, "Unexpected mallctl failure while activating profiling"); 34 | 35 | prof_dump_open = prof_dump_open_intercept; 36 | 37 | did_prof_dump_open = false; 38 | p = mallocx(1, 0); 39 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 40 | dallocx(p, 0); 41 | assert_true(did_prof_dump_open, "Expected a profile dump"); 42 | } 43 | TEST_END 44 | 45 | int 46 | main(void) 47 | { 48 | 49 | return (test( 50 | test_idump)); 51 | } 52 | -------------------------------------------------------------------------------- /deps/jemalloc-4.1.0/test/unit/zero.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef JEMALLOC_FILL 4 | const char *malloc_conf = 5 | "abort:false,junk:false,zero:true,redzone:false,quarantine:0"; 6 | #endif 7 | 8 | static void 9 | test_zero(size_t sz_min, size_t sz_max) 10 | { 11 | char *s; 12 | size_t sz_prev, sz, i; 13 | 14 | sz_prev = 0; 15 | s = (char *)mallocx(sz_min, 0); 16 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 17 | 18 | for (sz = sallocx(s, 0); sz <= sz_max; 19 | sz_prev = sz, sz = sallocx(s, 0)) { 20 | if (sz_prev > 0) { 21 | assert_c_eq(s[0], 'a', 22 | "Previously allocated byte %zu/%zu is corrupted", 23 | ZU(0), sz_prev); 24 | assert_c_eq(s[sz_prev-1], 'a', 25 | "Previously allocated byte %zu/%zu is corrupted", 26 | sz_prev-1, sz_prev); 27 | } 28 | 29 | for (i = sz_prev; i < sz; i++) { 30 | assert_c_eq(s[i], 0x0, 31 | "Newly allocated byte %zu/%zu isn't zero-filled", 32 | i, sz); 33 | s[i] = 'a'; 34 | } 35 | 36 | if (xallocx(s, sz+1, 0, 0) == sz) { 37 | s = (char *)rallocx(s, sz+1, 0); 38 | assert_ptr_not_null((void *)s, 39 | "Unexpected rallocx() failure"); 40 | } 41 | } 42 | 43 | dallocx(s, 0); 44 | } 45 | 46 | TEST_BEGIN(test_zero_small) 47 | { 48 | 49 | test_skip_if(!config_fill); 50 | test_zero(1, SMALL_MAXCLASS-1); 51 | } 52 | TEST_END 53 | 54 | TEST_BEGIN(test_zero_large) 55 | { 56 | 57 | test_skip_if(!config_fill); 58 | test_zero(SMALL_MAXCLASS+1, large_maxclass); 59 | } 60 | TEST_END 61 | 62 | TEST_BEGIN(test_zero_huge) 63 | { 64 | 65 | test_skip_if(!config_fill); 66 | test_zero(large_maxclass+1, chunksize*2); 67 | } 68 | TEST_END 69 | 70 | int 71 | main(void) 72 | { 73 | 74 | return (test( 75 | test_zero_small, 76 | test_zero_large, 77 | test_zero_huge)); 78 | } 79 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/.gitignore: -------------------------------------------------------------------------------- 1 | build_config.mk 2 | *.a 3 | *.o 4 | *.dylib* 5 | *.so 6 | *.so.* 7 | *_test 8 | db_bench 9 | leveldbutil 10 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - clang 4 | - gcc 5 | os: 6 | - linux 7 | - osx 8 | sudo: false 9 | before_install: 10 | - echo $LANG 11 | - echo $LC_ALL 12 | script: 13 | - make -j 4 check 14 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file like so: 2 | # Name or Organization 3 | 4 | Google Inc. 5 | 6 | # Initial version authors: 7 | Jeffrey Dean 8 | Sanjay Ghemawat 9 | 10 | # Partial list of contributors: 11 | Kevin Regan 12 | Johan Bilien 13 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We'd love to accept your code patches! However, before we can take them, we 4 | have to jump a couple of legal hurdles. 5 | 6 | ## Contributor License Agreements 7 | 8 | Please fill out either the individual or corporate Contributor License 9 | Agreement as appropriate. 10 | 11 | * If you are an individual writing original source code and you're sure you 12 | own the intellectual property, then sign an [individual CLA](https://developers.google.com/open-source/cla/individual). 13 | * If you work for a company that wants to allow you to contribute your work, 14 | then sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). 15 | 16 | Follow either of the two links above to access the appropriate CLA and 17 | instructions for how to sign and return it. 18 | 19 | ## Submitting a Patch 20 | 21 | 1. Sign the contributors license agreement above. 22 | 2. Decide which code you want to submit. A submission should be a set of changes 23 | that addresses one issue in the [issue tracker](https://github.com/google/leveldb/issues). 24 | Please don't mix more than one logical change per submission, because it makes 25 | the history hard to follow. If you want to make a change 26 | (e.g. add a sample or feature) that doesn't have a corresponding issue in the 27 | issue tracker, please create one. 28 | 3. **Submitting**: When you are ready to submit, send us a Pull Request. Be 29 | sure to include the issue number you fixed and the name you used to sign 30 | the CLA. 31 | 32 | ## Writing Code ## 33 | 34 | If your contribution contains code, please make sure that it follows 35 | [the style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). 36 | Otherwise we will have to ask you to make changes, and that's no fun for anyone. 37 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/NEWS: -------------------------------------------------------------------------------- 1 | Release 1.2 2011-05-16 2 | ---------------------- 3 | 4 | Fixes for larger databases (tested up to one billion 100-byte entries, 5 | i.e., ~100GB). 6 | 7 | (1) Place hard limit on number of level-0 files. This fixes errors 8 | of the form "too many open files". 9 | 10 | (2) Fixed memtable management. Before the fix, a heavy write burst 11 | could cause unbounded memory usage. 12 | 13 | A fix for a logging bug where the reader would incorrectly complain 14 | about corruption. 15 | 16 | Allow public access to WriteBatch contents so that users can easily 17 | wrap a DB. 18 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/TODO: -------------------------------------------------------------------------------- 1 | ss 2 | - Stats 3 | 4 | db 5 | - Maybe implement DB::BulkDeleteForRange(start_key, end_key) 6 | that would blow away files whose ranges are entirely contained 7 | within [start_key..end_key]? For Chrome, deletion of obsolete 8 | object stores, etc. can be done in the background anyway, so 9 | probably not that important. 10 | - There have been requests for MultiGet. 11 | 12 | After a range is completely deleted, what gets rid of the 13 | corresponding files if we do no future changes to that range. Make 14 | the conditions for triggering compactions fire in more situations? 15 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/builder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_BUILDER_H_ 6 | #define STORAGE_LEVELDB_DB_BUILDER_H_ 7 | 8 | #include "leveldb/status.h" 9 | 10 | namespace leveldb { 11 | 12 | struct Options; 13 | struct FileMetaData; 14 | 15 | class Env; 16 | class Iterator; 17 | class TableCache; 18 | class VersionEdit; 19 | 20 | // Build a Table file from the contents of *iter. The generated file 21 | // will be named according to meta->number. On success, the rest of 22 | // *meta will be filled with metadata about the generated table. 23 | // If no data is present in *iter, meta->file_size will be set to 24 | // zero, and no Table file will be produced. 25 | extern Status BuildTable(const std::string& dbname, 26 | Env* env, 27 | const Options& options, 28 | TableCache* table_cache, 29 | Iterator* iter, 30 | FileMetaData* meta); 31 | 32 | } // namespace leveldb 33 | 34 | #endif // STORAGE_LEVELDB_DB_BUILDER_H_ 35 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/db_iter.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_DB_ITER_H_ 6 | #define STORAGE_LEVELDB_DB_DB_ITER_H_ 7 | 8 | #include 9 | #include "leveldb/db.h" 10 | #include "db/dbformat.h" 11 | 12 | namespace leveldb { 13 | 14 | class DBImpl; 15 | 16 | // Return a new iterator that converts internal keys (yielded by 17 | // "*internal_iter") that were live at the specified "sequence" number 18 | // into appropriate user keys. 19 | extern Iterator* NewDBIterator( 20 | DBImpl* db, 21 | const Comparator* user_key_comparator, 22 | Iterator* internal_iter, 23 | SequenceNumber sequence, 24 | uint32_t seed); 25 | 26 | } // namespace leveldb 27 | 28 | #endif // STORAGE_LEVELDB_DB_DB_ITER_H_ 29 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/leveldbutil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "leveldb/dumpfile.h" 7 | #include "leveldb/env.h" 8 | #include "leveldb/status.h" 9 | 10 | namespace leveldb { 11 | namespace { 12 | 13 | class StdoutPrinter : public WritableFile { 14 | public: 15 | virtual Status Append(const Slice& data) { 16 | fwrite(data.data(), 1, data.size(), stdout); 17 | return Status::OK(); 18 | } 19 | virtual Status Close() { return Status::OK(); } 20 | virtual Status Flush() { return Status::OK(); } 21 | virtual Status Sync() { return Status::OK(); } 22 | }; 23 | 24 | bool HandleDumpCommand(Env* env, char** files, int num) { 25 | StdoutPrinter printer; 26 | bool ok = true; 27 | for (int i = 0; i < num; i++) { 28 | Status s = DumpFile(env, files[i], &printer); 29 | if (!s.ok()) { 30 | fprintf(stderr, "%s\n", s.ToString().c_str()); 31 | ok = false; 32 | } 33 | } 34 | return ok; 35 | } 36 | 37 | } // namespace 38 | } // namespace leveldb 39 | 40 | static void Usage() { 41 | fprintf( 42 | stderr, 43 | "Usage: leveldbutil command...\n" 44 | " dump files... -- dump contents of specified files\n" 45 | ); 46 | } 47 | 48 | int main(int argc, char** argv) { 49 | leveldb::Env* env = leveldb::Env::Default(); 50 | bool ok = true; 51 | if (argc < 2) { 52 | Usage(); 53 | ok = false; 54 | } else { 55 | std::string command = argv[1]; 56 | if (command == "dump") { 57 | ok = leveldb::HandleDumpCommand(env, argv+2, argc-2); 58 | } else { 59 | Usage(); 60 | ok = false; 61 | } 62 | } 63 | return (ok ? 0 : 1); 64 | } 65 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/log_format.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Log format information shared by reader and writer. 6 | // See ../doc/log_format.md for more detail. 7 | 8 | #ifndef STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 9 | #define STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 10 | 11 | namespace leveldb { 12 | namespace log { 13 | 14 | enum RecordType { 15 | // Zero is reserved for preallocated files 16 | kZeroType = 0, 17 | 18 | kFullType = 1, 19 | 20 | // For fragments 21 | kFirstType = 2, 22 | kMiddleType = 3, 23 | kLastType = 4 24 | }; 25 | static const int kMaxRecordType = kLastType; 26 | 27 | static const int kBlockSize = 32768; 28 | 29 | // Header is checksum (4 bytes), length (2 bytes), type (1 byte). 30 | static const int kHeaderSize = 4 + 2 + 1; 31 | 32 | } // namespace log 33 | } // namespace leveldb 34 | 35 | #endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 36 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/log_writer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_LOG_WRITER_H_ 6 | #define STORAGE_LEVELDB_DB_LOG_WRITER_H_ 7 | 8 | #include 9 | #include "db/log_format.h" 10 | #include "leveldb/slice.h" 11 | #include "leveldb/status.h" 12 | 13 | namespace leveldb { 14 | 15 | class WritableFile; 16 | 17 | namespace log { 18 | 19 | class Writer { 20 | public: 21 | // Create a writer that will append data to "*dest". 22 | // "*dest" must be initially empty. 23 | // "*dest" must remain live while this Writer is in use. 24 | explicit Writer(WritableFile* dest); 25 | 26 | // Create a writer that will append data to "*dest". 27 | // "*dest" must have initial length "dest_length". 28 | // "*dest" must remain live while this Writer is in use. 29 | Writer(WritableFile* dest, uint64_t dest_length); 30 | 31 | ~Writer(); 32 | 33 | Status AddRecord(const Slice& slice); 34 | 35 | private: 36 | WritableFile* dest_; 37 | int block_offset_; // Current offset in block 38 | 39 | // crc32c values for all supported record types. These are 40 | // pre-computed to reduce the overhead of computing the crc of the 41 | // record type stored in the header. 42 | uint32_t type_crc_[kMaxRecordType + 1]; 43 | 44 | Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length); 45 | 46 | // No copying allowed 47 | Writer(const Writer&); 48 | void operator=(const Writer&); 49 | }; 50 | 51 | } // namespace log 52 | } // namespace leveldb 53 | 54 | #endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_ 55 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/snapshot.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_ 6 | #define STORAGE_LEVELDB_DB_SNAPSHOT_H_ 7 | 8 | #include "db/dbformat.h" 9 | #include "leveldb/db.h" 10 | 11 | namespace leveldb { 12 | 13 | class SnapshotList; 14 | 15 | // Snapshots are kept in a doubly-linked list in the DB. 16 | // Each SnapshotImpl corresponds to a particular sequence number. 17 | class SnapshotImpl : public Snapshot { 18 | public: 19 | SequenceNumber number_; // const after creation 20 | 21 | private: 22 | friend class SnapshotList; 23 | 24 | // SnapshotImpl is kept in a doubly-linked circular list 25 | SnapshotImpl* prev_; 26 | SnapshotImpl* next_; 27 | 28 | SnapshotList* list_; // just for sanity checks 29 | }; 30 | 31 | class SnapshotList { 32 | public: 33 | SnapshotList() { 34 | list_.prev_ = &list_; 35 | list_.next_ = &list_; 36 | } 37 | 38 | bool empty() const { return list_.next_ == &list_; } 39 | SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; } 40 | SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; } 41 | 42 | const SnapshotImpl* New(SequenceNumber seq) { 43 | SnapshotImpl* s = new SnapshotImpl; 44 | s->number_ = seq; 45 | s->list_ = this; 46 | s->next_ = &list_; 47 | s->prev_ = list_.prev_; 48 | s->prev_->next_ = s; 49 | s->next_->prev_ = s; 50 | return s; 51 | } 52 | 53 | void Delete(const SnapshotImpl* s) { 54 | assert(s->list_ == this); 55 | s->prev_->next_ = s->next_; 56 | s->next_->prev_ = s->prev_; 57 | delete s; 58 | } 59 | 60 | private: 61 | // Dummy head of doubly-linked list of snapshots 62 | SnapshotImpl list_; 63 | }; 64 | 65 | } // namespace leveldb 66 | 67 | #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_ 68 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/version_edit_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/version_edit.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | 10 | static void TestEncodeDecode(const VersionEdit& edit) { 11 | std::string encoded, encoded2; 12 | edit.EncodeTo(&encoded); 13 | VersionEdit parsed; 14 | Status s = parsed.DecodeFrom(encoded); 15 | ASSERT_TRUE(s.ok()) << s.ToString(); 16 | parsed.EncodeTo(&encoded2); 17 | ASSERT_EQ(encoded, encoded2); 18 | } 19 | 20 | class VersionEditTest { }; 21 | 22 | TEST(VersionEditTest, EncodeDecode) { 23 | static const uint64_t kBig = 1ull << 50; 24 | 25 | VersionEdit edit; 26 | for (int i = 0; i < 4; i++) { 27 | TestEncodeDecode(edit); 28 | edit.AddFile(3, kBig + 300 + i, kBig + 400 + i, 29 | InternalKey("foo", kBig + 500 + i, kTypeValue), 30 | InternalKey("zoo", kBig + 600 + i, kTypeDeletion)); 31 | edit.DeleteFile(4, kBig + 700 + i); 32 | edit.SetCompactPointer(i, InternalKey("x", kBig + 900 + i, kTypeValue)); 33 | } 34 | 35 | edit.SetComparatorName("foo"); 36 | edit.SetLogNumber(kBig + 100); 37 | edit.SetNextFile(kBig + 200); 38 | edit.SetLastSequence(kBig + 1000); 39 | TestEncodeDecode(edit); 40 | } 41 | 42 | } // namespace leveldb 43 | 44 | int main(int argc, char** argv) { 45 | return leveldb::test::RunAllTests(); 46 | } 47 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/db/write_batch_internal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 6 | #define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 7 | 8 | #include "db/dbformat.h" 9 | #include "leveldb/write_batch.h" 10 | 11 | namespace leveldb { 12 | 13 | class MemTable; 14 | 15 | // WriteBatchInternal provides static methods for manipulating a 16 | // WriteBatch that we don't want in the public WriteBatch interface. 17 | class WriteBatchInternal { 18 | public: 19 | // Return the number of entries in the batch. 20 | static int Count(const WriteBatch* batch); 21 | 22 | // Set the count for the number of entries in the batch. 23 | static void SetCount(WriteBatch* batch, int n); 24 | 25 | // Return the sequence number for the start of this batch. 26 | static SequenceNumber Sequence(const WriteBatch* batch); 27 | 28 | // Store the specified number as the sequence number for the start of 29 | // this batch. 30 | static void SetSequence(WriteBatch* batch, SequenceNumber seq); 31 | 32 | static Slice Contents(const WriteBatch* batch) { 33 | return Slice(batch->rep_); 34 | } 35 | 36 | static size_t ByteSize(const WriteBatch* batch) { 37 | return batch->rep_.size(); 38 | } 39 | 40 | static void SetContents(WriteBatch* batch, const Slice& contents); 41 | 42 | static Status InsertInto(const WriteBatch* batch, MemTable* memtable); 43 | 44 | static void Append(WriteBatch* dst, const WriteBatch* src); 45 | }; 46 | 47 | } // namespace leveldb 48 | 49 | 50 | #endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 51 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/helpers/memenv/memenv.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_ 6 | #define STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_ 7 | 8 | namespace leveldb { 9 | 10 | class Env; 11 | 12 | // Returns a new environment that stores its data in memory and delegates 13 | // all non-file-storage tasks to base_env. The caller must delete the result 14 | // when it is no longer needed. 15 | // *base_env must remain live while the result is in use. 16 | Env* NewMemEnv(Env* base_env); 17 | 18 | } // namespace leveldb 19 | 20 | #endif // STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_ 21 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/include/leveldb/dumpfile.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ 7 | 8 | #include 9 | #include "leveldb/env.h" 10 | #include "leveldb/status.h" 11 | 12 | namespace leveldb { 13 | 14 | // Dump the contents of the file named by fname in text format to 15 | // *dst. Makes a sequence of dst->Append() calls; each call is passed 16 | // the newline-terminated text corresponding to a single item found 17 | // in the file. 18 | // 19 | // Returns a non-OK result if fname does not name a leveldb storage 20 | // file, or if the file cannot be read. 21 | Status DumpFile(Env* env, const std::string& fname, WritableFile* dst); 22 | 23 | } // namespace leveldb 24 | 25 | #endif // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ 26 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/issues/issue200_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // Test for issue 200: when iterator switches direction from backward 6 | // to forward, the current key can be yielded unexpectedly if a new 7 | // mutation has been added just before the current key. 8 | 9 | #include "leveldb/db.h" 10 | #include "util/testharness.h" 11 | 12 | namespace leveldb { 13 | 14 | class Issue200 { }; 15 | 16 | TEST(Issue200, Test) { 17 | // Get rid of any state from an old run. 18 | std::string dbpath = test::TmpDir() + "/leveldb_issue200_test"; 19 | DestroyDB(dbpath, Options()); 20 | 21 | DB *db; 22 | Options options; 23 | options.create_if_missing = true; 24 | ASSERT_OK(DB::Open(options, dbpath, &db)); 25 | 26 | WriteOptions write_options; 27 | ASSERT_OK(db->Put(write_options, "1", "b")); 28 | ASSERT_OK(db->Put(write_options, "2", "c")); 29 | ASSERT_OK(db->Put(write_options, "3", "d")); 30 | ASSERT_OK(db->Put(write_options, "4", "e")); 31 | ASSERT_OK(db->Put(write_options, "5", "f")); 32 | 33 | ReadOptions read_options; 34 | Iterator *iter = db->NewIterator(read_options); 35 | 36 | // Add an element that should not be reflected in the iterator. 37 | ASSERT_OK(db->Put(write_options, "25", "cd")); 38 | 39 | iter->Seek("5"); 40 | ASSERT_EQ(iter->key().ToString(), "5"); 41 | iter->Prev(); 42 | ASSERT_EQ(iter->key().ToString(), "4"); 43 | iter->Prev(); 44 | ASSERT_EQ(iter->key().ToString(), "3"); 45 | iter->Next(); 46 | ASSERT_EQ(iter->key().ToString(), "4"); 47 | iter->Next(); 48 | ASSERT_EQ(iter->key().ToString(), "5"); 49 | 50 | delete iter; 51 | delete db; 52 | DestroyDB(dbpath, options); 53 | } 54 | 55 | } // namespace leveldb 56 | 57 | int main(int argc, char** argv) { 58 | return leveldb::test::RunAllTests(); 59 | } 60 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/port/README: -------------------------------------------------------------------------------- 1 | This directory contains interfaces and implementations that isolate the 2 | rest of the package from platform details. 3 | 4 | Code in the rest of the package includes "port.h" from this directory. 5 | "port.h" in turn includes a platform specific "port_.h" file 6 | that provides the platform specific implementation. 7 | 8 | See port_posix.h for an example of what must be provided in a platform 9 | specific header file. 10 | 11 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/port/port.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_PORT_PORT_H_ 6 | #define STORAGE_LEVELDB_PORT_PORT_H_ 7 | 8 | #include 9 | 10 | // Include the appropriate platform specific file below. If you are 11 | // porting to a new platform, see "port_example.h" for documentation 12 | // of what the new port_.h file must provide. 13 | #if defined(LEVELDB_PLATFORM_POSIX) 14 | # include "port/port_posix.h" 15 | #elif defined(LEVELDB_PLATFORM_CHROMIUM) 16 | # include "port/port_chromium.h" 17 | #endif 18 | 19 | #endif // STORAGE_LEVELDB_PORT_PORT_H_ 20 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/port/port_posix.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port_posix.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace leveldb { 12 | namespace port { 13 | 14 | static void PthreadCall(const char* label, int result) { 15 | if (result != 0) { 16 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 17 | abort(); 18 | } 19 | } 20 | 21 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 22 | 23 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 24 | 25 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 26 | 27 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 28 | 29 | CondVar::CondVar(Mutex* mu) 30 | : mu_(mu) { 31 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 32 | } 33 | 34 | CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } 35 | 36 | void CondVar::Wait() { 37 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 38 | } 39 | 40 | void CondVar::Signal() { 41 | PthreadCall("signal", pthread_cond_signal(&cv_)); 42 | } 43 | 44 | void CondVar::SignalAll() { 45 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 46 | } 47 | 48 | void InitOnce(OnceType* once, void (*initializer)()) { 49 | PthreadCall("once", pthread_once(once, initializer)); 50 | } 51 | 52 | } // namespace port 53 | } // namespace leveldb 54 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/port/thread_annotations.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ 6 | #define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ 7 | 8 | // Some environments provide custom macros to aid in static thread-safety 9 | // analysis. Provide empty definitions of such macros unless they are already 10 | // defined. 11 | 12 | #ifndef EXCLUSIVE_LOCKS_REQUIRED 13 | #define EXCLUSIVE_LOCKS_REQUIRED(...) 14 | #endif 15 | 16 | #ifndef SHARED_LOCKS_REQUIRED 17 | #define SHARED_LOCKS_REQUIRED(...) 18 | #endif 19 | 20 | #ifndef LOCKS_EXCLUDED 21 | #define LOCKS_EXCLUDED(...) 22 | #endif 23 | 24 | #ifndef LOCK_RETURNED 25 | #define LOCK_RETURNED(x) 26 | #endif 27 | 28 | #ifndef LOCKABLE 29 | #define LOCKABLE 30 | #endif 31 | 32 | #ifndef SCOPED_LOCKABLE 33 | #define SCOPED_LOCKABLE 34 | #endif 35 | 36 | #ifndef EXCLUSIVE_LOCK_FUNCTION 37 | #define EXCLUSIVE_LOCK_FUNCTION(...) 38 | #endif 39 | 40 | #ifndef SHARED_LOCK_FUNCTION 41 | #define SHARED_LOCK_FUNCTION(...) 42 | #endif 43 | 44 | #ifndef EXCLUSIVE_TRYLOCK_FUNCTION 45 | #define EXCLUSIVE_TRYLOCK_FUNCTION(...) 46 | #endif 47 | 48 | #ifndef SHARED_TRYLOCK_FUNCTION 49 | #define SHARED_TRYLOCK_FUNCTION(...) 50 | #endif 51 | 52 | #ifndef UNLOCK_FUNCTION 53 | #define UNLOCK_FUNCTION(...) 54 | #endif 55 | 56 | #ifndef NO_THREAD_SAFETY_ANALYSIS 57 | #define NO_THREAD_SAFETY_ANALYSIS 58 | #endif 59 | 60 | #endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ 61 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/port/win/stdint.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // MSVC didn't ship with this file until the 2010 version. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 8 | #define STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 9 | 10 | #if !defined(_MSC_VER) 11 | #error This file should only be included when compiling with MSVC. 12 | #endif 13 | 14 | // Define C99 equivalent types. 15 | typedef signed char int8_t; 16 | typedef signed short int16_t; 17 | typedef signed int int32_t; 18 | typedef signed long long int64_t; 19 | typedef unsigned char uint8_t; 20 | typedef unsigned short uint16_t; 21 | typedef unsigned int uint32_t; 22 | typedef unsigned long long uint64_t; 23 | 24 | #endif // STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 25 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/table/block.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_H_ 7 | 8 | #include 9 | #include 10 | #include "leveldb/iterator.h" 11 | 12 | namespace leveldb { 13 | 14 | struct BlockContents; 15 | class Comparator; 16 | 17 | class Block { 18 | public: 19 | // Initialize the block with the specified contents. 20 | explicit Block(const BlockContents& contents); 21 | 22 | ~Block(); 23 | 24 | size_t size() const { return size_; } 25 | Iterator* NewIterator(const Comparator* comparator); 26 | 27 | private: 28 | uint32_t NumRestarts() const; 29 | 30 | const char* data_; 31 | size_t size_; 32 | uint32_t restart_offset_; // Offset in data_ of restart array 33 | bool owned_; // Block owns data_[] 34 | 35 | // No copying allowed 36 | Block(const Block&); 37 | void operator=(const Block&); 38 | 39 | class Iter; 40 | }; 41 | 42 | } // namespace leveldb 43 | 44 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_H_ 45 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/table/block_builder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include "leveldb/slice.h" 12 | 13 | namespace leveldb { 14 | 15 | struct Options; 16 | 17 | class BlockBuilder { 18 | public: 19 | explicit BlockBuilder(const Options* options); 20 | 21 | // Reset the contents as if the BlockBuilder was just constructed. 22 | void Reset(); 23 | 24 | // REQUIRES: Finish() has not been called since the last call to Reset(). 25 | // REQUIRES: key is larger than any previously added key 26 | void Add(const Slice& key, const Slice& value); 27 | 28 | // Finish building the block and return a slice that refers to the 29 | // block contents. The returned slice will remain valid for the 30 | // lifetime of this builder or until Reset() is called. 31 | Slice Finish(); 32 | 33 | // Returns an estimate of the current (uncompressed) size of the block 34 | // we are building. 35 | size_t CurrentSizeEstimate() const; 36 | 37 | // Return true iff no entries have been added since the last Reset() 38 | bool empty() const { 39 | return buffer_.empty(); 40 | } 41 | 42 | private: 43 | const Options* options_; 44 | std::string buffer_; // Destination buffer 45 | std::vector restarts_; // Restart points 46 | int counter_; // Number of entries emitted since restart 47 | bool finished_; // Has Finish() been called? 48 | std::string last_key_; 49 | 50 | // No copying allowed 51 | BlockBuilder(const BlockBuilder&); 52 | void operator=(const BlockBuilder&); 53 | }; 54 | 55 | } // namespace leveldb 56 | 57 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 58 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/table/iterator.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/iterator.h" 6 | 7 | namespace leveldb { 8 | 9 | Iterator::Iterator() { 10 | cleanup_.function = NULL; 11 | cleanup_.next = NULL; 12 | } 13 | 14 | Iterator::~Iterator() { 15 | if (cleanup_.function != NULL) { 16 | (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2); 17 | for (Cleanup* c = cleanup_.next; c != NULL; ) { 18 | (*c->function)(c->arg1, c->arg2); 19 | Cleanup* next = c->next; 20 | delete c; 21 | c = next; 22 | } 23 | } 24 | } 25 | 26 | void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { 27 | assert(func != NULL); 28 | Cleanup* c; 29 | if (cleanup_.function == NULL) { 30 | c = &cleanup_; 31 | } else { 32 | c = new Cleanup; 33 | c->next = cleanup_.next; 34 | cleanup_.next = c; 35 | } 36 | c->function = func; 37 | c->arg1 = arg1; 38 | c->arg2 = arg2; 39 | } 40 | 41 | namespace { 42 | class EmptyIterator : public Iterator { 43 | public: 44 | EmptyIterator(const Status& s) : status_(s) { } 45 | virtual bool Valid() const { return false; } 46 | virtual void Seek(const Slice& target) { } 47 | virtual void SeekToFirst() { } 48 | virtual void SeekToLast() { } 49 | virtual void Next() { assert(false); } 50 | virtual void Prev() { assert(false); } 51 | Slice key() const { assert(false); return Slice(); } 52 | Slice value() const { assert(false); return Slice(); } 53 | virtual Status status() const { return status_; } 54 | private: 55 | Status status_; 56 | }; 57 | } // namespace 58 | 59 | Iterator* NewEmptyIterator() { 60 | return new EmptyIterator(Status::OK()); 61 | } 62 | 63 | Iterator* NewErrorIterator(const Status& status) { 64 | return new EmptyIterator(status); 65 | } 66 | 67 | } // namespace leveldb 68 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/table/merger.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_MERGER_H_ 6 | #define STORAGE_LEVELDB_TABLE_MERGER_H_ 7 | 8 | namespace leveldb { 9 | 10 | class Comparator; 11 | class Iterator; 12 | 13 | // Return an iterator that provided the union of the data in 14 | // children[0,n-1]. Takes ownership of the child iterators and 15 | // will delete them when the result iterator is deleted. 16 | // 17 | // The result does no duplicate suppression. I.e., if a particular 18 | // key is present in K child iterators, it will be yielded K times. 19 | // 20 | // REQUIRES: n >= 0 21 | extern Iterator* NewMergingIterator( 22 | const Comparator* comparator, Iterator** children, int n); 23 | 24 | } // namespace leveldb 25 | 26 | #endif // STORAGE_LEVELDB_TABLE_MERGER_H_ 27 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/table/two_level_iterator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 6 | #define STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 7 | 8 | #include "leveldb/iterator.h" 9 | 10 | namespace leveldb { 11 | 12 | struct ReadOptions; 13 | 14 | // Return a new two level iterator. A two-level iterator contains an 15 | // index iterator whose values point to a sequence of blocks where 16 | // each block is itself a sequence of key,value pairs. The returned 17 | // two-level iterator yields the concatenation of all key/value pairs 18 | // in the sequence of blocks. Takes ownership of "index_iter" and 19 | // will delete it when no longer needed. 20 | // 21 | // Uses a supplied function to convert an index_iter value into 22 | // an iterator over the contents of the corresponding block. 23 | extern Iterator* NewTwoLevelIterator( 24 | Iterator* index_iter, 25 | Iterator* (*block_function)( 26 | void* arg, 27 | const ReadOptions& options, 28 | const Slice& index_value), 29 | void* arg, 30 | const ReadOptions& options); 31 | 32 | } // namespace leveldb 33 | 34 | #endif // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 35 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/arena_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/arena.h" 6 | 7 | #include "util/random.h" 8 | #include "util/testharness.h" 9 | 10 | namespace leveldb { 11 | 12 | class ArenaTest { }; 13 | 14 | TEST(ArenaTest, Empty) { 15 | Arena arena; 16 | } 17 | 18 | TEST(ArenaTest, Simple) { 19 | std::vector > allocated; 20 | Arena arena; 21 | const int N = 100000; 22 | size_t bytes = 0; 23 | Random rnd(301); 24 | for (int i = 0; i < N; i++) { 25 | size_t s; 26 | if (i % (N / 10) == 0) { 27 | s = i; 28 | } else { 29 | s = rnd.OneIn(4000) ? rnd.Uniform(6000) : 30 | (rnd.OneIn(10) ? rnd.Uniform(100) : rnd.Uniform(20)); 31 | } 32 | if (s == 0) { 33 | // Our arena disallows size 0 allocations. 34 | s = 1; 35 | } 36 | char* r; 37 | if (rnd.OneIn(10)) { 38 | r = arena.AllocateAligned(s); 39 | } else { 40 | r = arena.Allocate(s); 41 | } 42 | 43 | for (size_t b = 0; b < s; b++) { 44 | // Fill the "i"th allocation with a known bit pattern 45 | r[b] = i % 256; 46 | } 47 | bytes += s; 48 | allocated.push_back(std::make_pair(s, r)); 49 | ASSERT_GE(arena.MemoryUsage(), bytes); 50 | if (i > N/10) { 51 | ASSERT_LE(arena.MemoryUsage(), bytes * 1.10); 52 | } 53 | } 54 | for (size_t i = 0; i < allocated.size(); i++) { 55 | size_t num_bytes = allocated[i].first; 56 | const char* p = allocated[i].second; 57 | for (size_t b = 0; b < num_bytes; b++) { 58 | // Check the "i"th allocation for the known bit pattern 59 | ASSERT_EQ(int(p[b]) & 0xff, i % 256); 60 | } 61 | } 62 | } 63 | 64 | } // namespace leveldb 65 | 66 | int main(int argc, char** argv) { 67 | return leveldb::test::RunAllTests(); 68 | } 69 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/crc32c.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_CRC32C_H_ 6 | #define STORAGE_LEVELDB_UTIL_CRC32C_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace leveldb { 12 | namespace crc32c { 13 | 14 | // Return the crc32c of concat(A, data[0,n-1]) where init_crc is the 15 | // crc32c of some string A. Extend() is often used to maintain the 16 | // crc32c of a stream of data. 17 | extern uint32_t Extend(uint32_t init_crc, const char* data, size_t n); 18 | 19 | // Return the crc32c of data[0,n-1] 20 | inline uint32_t Value(const char* data, size_t n) { 21 | return Extend(0, data, n); 22 | } 23 | 24 | static const uint32_t kMaskDelta = 0xa282ead8ul; 25 | 26 | // Return a masked representation of crc. 27 | // 28 | // Motivation: it is problematic to compute the CRC of a string that 29 | // contains embedded CRCs. Therefore we recommend that CRCs stored 30 | // somewhere (e.g., in files) should be masked before being stored. 31 | inline uint32_t Mask(uint32_t crc) { 32 | // Rotate right by 15 bits and add a constant. 33 | return ((crc >> 15) | (crc << 17)) + kMaskDelta; 34 | } 35 | 36 | // Return the crc whose masked representation is masked_crc. 37 | inline uint32_t Unmask(uint32_t masked_crc) { 38 | uint32_t rot = masked_crc - kMaskDelta; 39 | return ((rot >> 17) | (rot << 15)); 40 | } 41 | 42 | } // namespace crc32c 43 | } // namespace leveldb 44 | 45 | #endif // STORAGE_LEVELDB_UTIL_CRC32C_H_ 46 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/env_posix_test_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ 6 | #define STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ 7 | 8 | namespace leveldb { 9 | 10 | class EnvPosixTest; 11 | 12 | // A helper for the POSIX Env to facilitate testing. 13 | class EnvPosixTestHelper { 14 | private: 15 | friend class EnvPosixTest; 16 | 17 | // Set the maximum number of read-only files that will be opened. 18 | // Must be called before creating an Env. 19 | static void SetReadOnlyFDLimit(int limit); 20 | 21 | // Set the maximum number of read-only files that will be mapped via mmap. 22 | // Must be called before creating an Env. 23 | static void SetReadOnlyMMapLimit(int limit); 24 | }; 25 | 26 | } // namespace leveldb 27 | 28 | #endif // STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ 29 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/filter_policy.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/filter_policy.h" 6 | 7 | namespace leveldb { 8 | 9 | FilterPolicy::~FilterPolicy() { } 10 | 11 | } // namespace leveldb 12 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/hash.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "util/coding.h" 7 | #include "util/hash.h" 8 | 9 | // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through 10 | // between switch labels. The real definition should be provided externally. 11 | // This one is a fallback version for unsupported compilers. 12 | #ifndef FALLTHROUGH_INTENDED 13 | #define FALLTHROUGH_INTENDED do { } while (0) 14 | #endif 15 | 16 | namespace leveldb { 17 | 18 | uint32_t Hash(const char* data, size_t n, uint32_t seed) { 19 | // Similar to murmur hash 20 | const uint32_t m = 0xc6a4a793; 21 | const uint32_t r = 24; 22 | const char* limit = data + n; 23 | uint32_t h = seed ^ (n * m); 24 | 25 | // Pick up four bytes at a time 26 | while (data + 4 <= limit) { 27 | uint32_t w = DecodeFixed32(data); 28 | data += 4; 29 | h += w; 30 | h *= m; 31 | h ^= (h >> 16); 32 | } 33 | 34 | // Pick up remaining bytes 35 | switch (limit - data) { 36 | case 3: 37 | h += static_cast(data[2]) << 16; 38 | FALLTHROUGH_INTENDED; 39 | case 2: 40 | h += static_cast(data[1]) << 8; 41 | FALLTHROUGH_INTENDED; 42 | case 1: 43 | h += static_cast(data[0]); 44 | h *= m; 45 | h ^= (h >> r); 46 | break; 47 | } 48 | return h; 49 | } 50 | 51 | 52 | } // namespace leveldb 53 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/hash.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Simple hash function used for internal data structures 6 | 7 | #ifndef STORAGE_LEVELDB_UTIL_HASH_H_ 8 | #define STORAGE_LEVELDB_UTIL_HASH_H_ 9 | 10 | #include 11 | #include 12 | 13 | namespace leveldb { 14 | 15 | extern uint32_t Hash(const char* data, size_t n, uint32_t seed); 16 | 17 | } 18 | 19 | #endif // STORAGE_LEVELDB_UTIL_HASH_H_ 20 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/hash_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/hash.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | 10 | class HASH { }; 11 | 12 | TEST(HASH, SignedUnsignedIssue) { 13 | const unsigned char data1[1] = {0x62}; 14 | const unsigned char data2[2] = {0xc3, 0x97}; 15 | const unsigned char data3[3] = {0xe2, 0x99, 0xa5}; 16 | const unsigned char data4[4] = {0xe1, 0x80, 0xb9, 0x32}; 17 | const unsigned char data5[48] = { 18 | 0x01, 0xc0, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 22 | 0x14, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x04, 0x00, 24 | 0x00, 0x00, 0x00, 0x14, 25 | 0x00, 0x00, 0x00, 0x18, 26 | 0x28, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 28 | 0x02, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | ASSERT_EQ(Hash(0, 0, 0xbc9f1d34), 0xbc9f1d34); 33 | ASSERT_EQ( 34 | Hash(reinterpret_cast(data1), sizeof(data1), 0xbc9f1d34), 35 | 0xef1345c4); 36 | ASSERT_EQ( 37 | Hash(reinterpret_cast(data2), sizeof(data2), 0xbc9f1d34), 38 | 0x5b663814); 39 | ASSERT_EQ( 40 | Hash(reinterpret_cast(data3), sizeof(data3), 0xbc9f1d34), 41 | 0x323c078f); 42 | ASSERT_EQ( 43 | Hash(reinterpret_cast(data4), sizeof(data4), 0xbc9f1d34), 44 | 0xed21633a); 45 | ASSERT_EQ( 46 | Hash(reinterpret_cast(data5), sizeof(data5), 0x12345678), 47 | 0xf333dabb); 48 | } 49 | 50 | } // namespace leveldb 51 | 52 | int main(int argc, char** argv) { 53 | return leveldb::test::RunAllTests(); 54 | } 55 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/histogram.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 6 | #define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | class Histogram { 13 | public: 14 | Histogram() { } 15 | ~Histogram() { } 16 | 17 | void Clear(); 18 | void Add(double value); 19 | void Merge(const Histogram& other); 20 | 21 | std::string ToString() const; 22 | 23 | private: 24 | double min_; 25 | double max_; 26 | double num_; 27 | double sum_; 28 | double sum_squares_; 29 | 30 | enum { kNumBuckets = 154 }; 31 | static const double kBucketLimit[kNumBuckets]; 32 | double buckets_[kNumBuckets]; 33 | 34 | double Median() const; 35 | double Percentile(double p) const; 36 | double Average() const; 37 | double StandardDeviation() const; 38 | }; 39 | 40 | } // namespace leveldb 41 | 42 | #endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 43 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/logging.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Must not be included from any .h files to avoid polluting the namespace 6 | // with macros. 7 | 8 | #ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_ 9 | #define STORAGE_LEVELDB_UTIL_LOGGING_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "port/port.h" 15 | 16 | namespace leveldb { 17 | 18 | class Slice; 19 | class WritableFile; 20 | 21 | // Append a human-readable printout of "num" to *str 22 | extern void AppendNumberTo(std::string* str, uint64_t num); 23 | 24 | // Append a human-readable printout of "value" to *str. 25 | // Escapes any non-printable characters found in "value". 26 | extern void AppendEscapedStringTo(std::string* str, const Slice& value); 27 | 28 | // Return a human-readable printout of "num" 29 | extern std::string NumberToString(uint64_t num); 30 | 31 | // Return a human-readable version of "value". 32 | // Escapes any non-printable characters found in "value". 33 | extern std::string EscapeString(const Slice& value); 34 | 35 | // Parse a human-readable number from "*in" into *value. On success, 36 | // advances "*in" past the consumed number and sets "*val" to the 37 | // numeric value. Otherwise, returns false and leaves *in in an 38 | // unspecified state. 39 | extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val); 40 | 41 | } // namespace leveldb 42 | 43 | #endif // STORAGE_LEVELDB_UTIL_LOGGING_H_ 44 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/mutexlock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 6 | #define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 7 | 8 | #include "port/port.h" 9 | #include "port/thread_annotations.h" 10 | 11 | namespace leveldb { 12 | 13 | // Helper class that locks a mutex on construction and unlocks the mutex when 14 | // the destructor of the MutexLock object is invoked. 15 | // 16 | // Typical usage: 17 | // 18 | // void MyClass::MyMethod() { 19 | // MutexLock l(&mu_); // mu_ is an instance variable 20 | // ... some complex code, possibly with multiple return paths ... 21 | // } 22 | 23 | class SCOPED_LOCKABLE MutexLock { 24 | public: 25 | explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) 26 | : mu_(mu) { 27 | this->mu_->Lock(); 28 | } 29 | ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); } 30 | 31 | private: 32 | port::Mutex *const mu_; 33 | // No copying allowed 34 | MutexLock(const MutexLock&); 35 | void operator=(const MutexLock&); 36 | }; 37 | 38 | } // namespace leveldb 39 | 40 | 41 | #endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 42 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/options.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/options.h" 6 | 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/env.h" 9 | 10 | namespace leveldb { 11 | 12 | Options::Options() 13 | : comparator(BytewiseComparator()), 14 | compaction_speed(4096), 15 | create_if_missing(false), 16 | error_if_exists(false), 17 | paranoid_checks(false), 18 | env(Env::Default()), 19 | info_log(NULL), 20 | write_buffer_size(4<<20), 21 | max_open_files(1000), 22 | block_cache(NULL), 23 | block_size(4096), 24 | block_restart_interval(16), 25 | max_file_size(2<<20), 26 | compression(kSnappyCompression), 27 | reuse_logs(false), 28 | filter_policy(NULL) { 29 | } 30 | 31 | } // namespace leveldb 32 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/testharness.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/testharness.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace leveldb { 13 | namespace test { 14 | 15 | namespace { 16 | struct Test { 17 | const char* base; 18 | const char* name; 19 | void (*func)(); 20 | }; 21 | std::vector* tests; 22 | } 23 | 24 | bool RegisterTest(const char* base, const char* name, void (*func)()) { 25 | if (tests == NULL) { 26 | tests = new std::vector; 27 | } 28 | Test t; 29 | t.base = base; 30 | t.name = name; 31 | t.func = func; 32 | tests->push_back(t); 33 | return true; 34 | } 35 | 36 | int RunAllTests() { 37 | const char* matcher = getenv("LEVELDB_TESTS"); 38 | 39 | int num = 0; 40 | if (tests != NULL) { 41 | for (size_t i = 0; i < tests->size(); i++) { 42 | const Test& t = (*tests)[i]; 43 | if (matcher != NULL) { 44 | std::string name = t.base; 45 | name.push_back('.'); 46 | name.append(t.name); 47 | if (strstr(name.c_str(), matcher) == NULL) { 48 | continue; 49 | } 50 | } 51 | fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); 52 | (*t.func)(); 53 | ++num; 54 | } 55 | } 56 | fprintf(stderr, "==== PASSED %d tests\n", num); 57 | return 0; 58 | } 59 | 60 | std::string TmpDir() { 61 | std::string dir; 62 | Status s = Env::Default()->GetTestDirectory(&dir); 63 | ASSERT_TRUE(s.ok()) << s.ToString(); 64 | return dir; 65 | } 66 | 67 | int RandomSeed() { 68 | const char* env = getenv("TEST_RANDOM_SEED"); 69 | int result = (env != NULL ? atoi(env) : 301); 70 | if (result <= 0) { 71 | result = 301; 72 | } 73 | return result; 74 | } 75 | 76 | } // namespace test 77 | } // namespace leveldb 78 | -------------------------------------------------------------------------------- /deps/leveldb-1.20/util/testutil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/testutil.h" 6 | 7 | #include "util/random.h" 8 | 9 | namespace leveldb { 10 | namespace test { 11 | 12 | Slice RandomString(Random* rnd, int len, std::string* dst) { 13 | dst->resize(len); 14 | for (int i = 0; i < len; i++) { 15 | (*dst)[i] = static_cast(' ' + rnd->Uniform(95)); // ' ' .. '~' 16 | } 17 | return Slice(*dst); 18 | } 19 | 20 | std::string RandomKey(Random* rnd, int len) { 21 | // Make sure to generate a wide variety of characters so we 22 | // test the boundary conditions for short-key optimizations. 23 | static const char kTestChars[] = { 24 | '\0', '\1', 'a', 'b', 'c', 'd', 'e', '\xfd', '\xfe', '\xff' 25 | }; 26 | std::string result; 27 | for (int i = 0; i < len; i++) { 28 | result += kTestChars[rnd->Uniform(sizeof(kTestChars))]; 29 | } 30 | return result; 31 | } 32 | 33 | 34 | extern Slice CompressibleString(Random* rnd, double compressed_fraction, 35 | size_t len, std::string* dst) { 36 | int raw = static_cast(len * compressed_fraction); 37 | if (raw < 1) raw = 1; 38 | std::string raw_data; 39 | RandomString(rnd, raw, &raw_data); 40 | 41 | // Duplicate the random data until we have filled "len" bytes 42 | dst->clear(); 43 | while (dst->size() < len) { 44 | dst->append(raw_data); 45 | } 46 | dst->resize(len); 47 | return Slice(*dst); 48 | } 49 | 50 | } // namespace test 51 | } // namespace leveldb 52 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.lo 2 | *.libs 3 | *.deps 4 | *.la 5 | *.o 6 | Makefile 7 | config.h 8 | config.log 9 | config.status 10 | libtool 11 | snappy_unittest 12 | stamp-h1 13 | testdata 14 | 15 | 16 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/AUTHORS: -------------------------------------------------------------------------------- 1 | opensource@google.com 2 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2011, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/Makefile-ios: -------------------------------------------------------------------------------- 1 | PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms 2 | SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer 3 | DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer 4 | IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString) 5 | SIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk 6 | DEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk 7 | 8 | CFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DHAVE_CONFIG_H -I. -O2 9 | SIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64 10 | DEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64 11 | 12 | #OBJS = $(patsubst %.cc, %.o, $(wildcard *.cc)) 13 | OBJS = snappy-c.o snappy-sinksource.o snappy-stubs-internal.o snappy.o 14 | 15 | all: $(OBJS) 16 | rm -f libsnappy-ios.a 17 | ar -rs libsnappy-ios.a $(OBJS) 18 | 19 | .cc.o: 20 | mkdir -p ios-x86 21 | mkdir -p ios-arm 22 | xcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@ 23 | xcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@ 24 | lipo ios-x86/$@ ios-arm/$@ -create -output $@ 25 | 26 | clean: 27 | rm -rf *.o *.a ios-x86 ios-arm 28 | 29 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | # Library. 4 | lib_LTLIBRARIES = libsnappy.la 5 | libsnappy_la_SOURCES = snappy.cc snappy-sinksource.cc snappy-stubs-internal.cc snappy-c.cc 6 | libsnappy_la_LDFLAGS = -version-info $(SNAPPY_LTVERSION) 7 | 8 | include_HEADERS = snappy.h snappy-sinksource.h snappy-stubs-public.h snappy-c.h 9 | noinst_HEADERS = snappy-internal.h snappy-stubs-internal.h snappy-test.h 10 | 11 | # Unit tests and benchmarks. 12 | snappy_unittest_CPPFLAGS = $(gflags_CFLAGS) $(GTEST_CPPFLAGS) 13 | snappy_unittest_SOURCES = snappy_unittest.cc snappy-test.cc 14 | snappy_unittest_LDFLAGS = $(GTEST_LDFLAGS) 15 | snappy_unittest_LDADD = libsnappy.la $(UNITTEST_LIBS) $(gflags_LIBS) $(GTEST_LIBS) 16 | TESTS = snappy_unittest 17 | noinst_PROGRAMS = $(TESTS) 18 | 19 | EXTRA_DIST = autogen.sh testdata/alice29.txt testdata/asyoulik.txt testdata/baddata1.snappy testdata/baddata2.snappy testdata/baddata3.snappy testdata/cp.html testdata/fields.c testdata/geo.protodata testdata/grammar.lsp testdata/house.jpg testdata/html testdata/html_x_4 testdata/kennedy.xls testdata/kppkn.gtb testdata/lcet10.txt testdata/mapreduce-osdi-1.pdf testdata/plrabn12.txt testdata/ptt5 testdata/sum testdata/urls.10K testdata/xargs.1 20 | dist_doc_DATA = ChangeLog COPYING INSTALL NEWS README format_description.txt framing_format.txt 21 | 22 | libtool: $(LIBTOOL_DEPS) 23 | $(SHELL) ./config.status --recheck 24 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | rm -rf autom4te.cache 3 | aclocal -I m4 4 | autoheader 5 | libtoolize --copy 6 | automake --add-missing --copy 7 | autoconf 8 | -------------------------------------------------------------------------------- /deps/snappy-1.1.0/snappy-stubs-internal.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include 30 | #include 31 | 32 | #include "snappy-stubs-internal.h" 33 | 34 | namespace snappy { 35 | 36 | void Varint::Append32(string* s, uint32 value) { 37 | char buf[Varint::kMax32]; 38 | const char* p = Varint::Encode32(buf, value); 39 | s->append(buf, p - buf); 40 | } 41 | 42 | } // namespace snappy 43 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | * View online: http://www.ideawu.com/ssdb/ 2 | * Contribute to SSDB documentation project: https://github.com/ideawu/ssdb-docs -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideawu/ssdb/f229ba277c7f7d0ca5a441c0c6fb3d1209af68e4/docs/logo.png -------------------------------------------------------------------------------- /docs/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | SSDB 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | include ../build_config.mk 2 | 3 | OBJS = proc_sys.o proc_kv.o proc_hash.o proc_zset.o proc_queue.o \ 4 | backend_dump.o backend_sync.o slave.o \ 5 | serv.o 6 | LIBS = ./ssdb/libssdb.a ./util/libutil.a ./net/libnet.a 7 | EXES = ../ssdb-server 8 | 9 | 10 | all: ${OBJS} ssdb-server.o 11 | ${CXX} -o ../ssdb-server ssdb-server.o ${OBJS} ${LIBS} ${CLIBS} client/SSDB_impl.o 12 | 13 | ssdb-server.o: ssdb-server.cpp 14 | ${CXX} ${CFLAGS} -c ssdb-server.cpp 15 | slave.o: slave.h slave.cpp 16 | ${CXX} ${CFLAGS} -c slave.cpp 17 | backend_dump.o: backend_dump.h backend_dump.cpp 18 | ${CXX} ${CFLAGS} -c backend_dump.cpp 19 | backend_sync.o: backend_sync.h backend_sync.cpp 20 | ${CXX} ${CFLAGS} -c backend_sync.cpp 21 | 22 | proc.o: serv.h proc.cpp 23 | ${CXX} ${CFLAGS} -c proc.cpp 24 | proc_sys.o: proc_sys.cpp 25 | ${CXX} ${CFLAGS} -c proc_sys.cpp 26 | proc_kv.o: proc_kv.cpp 27 | ${CXX} ${CFLAGS} -c proc_kv.cpp 28 | proc_hash.o: proc_hash.cpp 29 | ${CXX} ${CFLAGS} -c proc_hash.cpp 30 | proc_zset.o: proc_zset.cpp 31 | ${CXX} ${CFLAGS} -c proc_zset.cpp 32 | proc_queue.o: proc_queue.cpp 33 | ${CXX} ${CFLAGS} -c proc_queue.cpp 34 | 35 | serv.o: serv.h serv.cpp 36 | ${CXX} ${CFLAGS} -c serv.cpp 37 | 38 | clean: 39 | rm -f ${EXES} *.o *.exe *.a 40 | 41 | -------------------------------------------------------------------------------- /src/backend_dump.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_BACKEND_DUMP_H_ 7 | #define SSDB_BACKEND_DUMP_H_ 8 | 9 | #include "include.h" 10 | #include "ssdb/ssdb.h" 11 | #include "net/link.h" 12 | 13 | class BackendDump{ 14 | private: 15 | struct run_arg{ 16 | const Link *link; 17 | const BackendDump *backend; 18 | }; 19 | static void* _run_thread(void *arg); 20 | SSDB *ssdb; 21 | public: 22 | BackendDump(SSDB *ssdb); 23 | ~BackendDump(); 24 | void proc(const Link *link); 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/backend_sync.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_BACKEND_SYNC_H_ 7 | #define SSDB_BACKEND_SYNC_H_ 8 | 9 | #include "include.h" 10 | #include 11 | #include 12 | #include 13 | 14 | #include "ssdb/ssdb_impl.h" 15 | #include "ssdb/binlog.h" 16 | #include "net/link.h" 17 | #include "util/thread.h" 18 | 19 | class BackendSync{ 20 | private: 21 | struct Client; 22 | private: 23 | std::vector clients; 24 | std::vector clients_tmp; 25 | 26 | struct run_arg{ 27 | const Link *link; 28 | const BackendSync *backend; 29 | }; 30 | volatile bool thread_quit; 31 | static void* _run_thread(void *arg); 32 | Mutex mutex; 33 | std::map workers; 34 | SSDBImpl *ssdb; 35 | int sync_speed; 36 | public: 37 | BackendSync(SSDBImpl *ssdb, int sync_speed); 38 | ~BackendSync(); 39 | void proc(const Link *link); 40 | 41 | std::vector stats(); 42 | }; 43 | 44 | struct BackendSync::Client{ 45 | static const int INIT = 0; 46 | static const int OUT_OF_SYNC = 1; 47 | static const int COPY = 2; 48 | static const int SYNC = 4; 49 | 50 | int status; 51 | Link *link; 52 | uint64_t last_seq; 53 | uint64_t last_noop_seq; 54 | std::string last_key; 55 | const BackendSync *backend; 56 | bool is_mirror; 57 | 58 | Iterator *iter; 59 | 60 | Client(const BackendSync *backend); 61 | ~Client(); 62 | void init(); 63 | void reset(); 64 | void noop(); 65 | int copy(); 66 | int sync(BinlogQueue *logs); 67 | void out_of_sync(); 68 | 69 | std::string stats(); 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/client/Makefile: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | all: lib 4 | ${CXX} -o demo demo.cpp libssdb-client.a 5 | ${CXX} -o hello-ssdb hello-ssdb.cpp libssdb-client.a 6 | 7 | lib: SSDB_client.h SSDB_impl.h SSDB_impl.cpp 8 | ${CXX} -I../ ${CFLAGS} -c SSDB_impl.cpp 9 | ar -cru libssdb-client.a\ 10 | SSDB_impl.o\ 11 | ../util/bytes.o\ 12 | ../net/link.o ../net/link_addr.o 13 | cp SSDB_client.h libssdb-client.a ../../api/cpp 14 | 15 | clean: 16 | rm -f demo hello-ssdb *.a *.o 17 | 18 | -------------------------------------------------------------------------------- /src/client/README.md: -------------------------------------------------------------------------------- 1 | SSDB C++ API Documentation {#mainpage} 2 | ============ 3 | 4 | @author: [ideawu](http://www.ideawu.com/) 5 | 6 | ## Build the static library(libssdb-client.a) 7 | 8 | Download the SSDB source code from [github](https://github.com/ideawu/ssdb). 9 | 10 | make 11 | 12 | The shell commands above will compile the C++ API codes, and generate a `libssdb-client.a` file. 13 | 14 | ## Sample code 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "SSDB_client.h" 21 | 22 | int main(int argc, char **argv){ 23 | const char *ip = (argc >= 2)? argv[1] : "127.0.0.1"; 24 | int port = (argc >= 3)? atoi(argv[2]) : 8888; 25 | 26 | ssdb::Client *client = ssdb::Client::connect(ip, port); 27 | if(client == NULL){ 28 | printf("fail to connect to server!\n"); 29 | return 0; 30 | } 31 | 32 | ssdb::Status s; 33 | s = client->set("k", "hello ssdb!"); 34 | if(s.ok()){ 35 | printf("k = hello ssdb!\n"); 36 | }else{ 37 | printf("error!\n"); 38 | } 39 | 40 | delete client; 41 | return 0; 42 | } 43 | 44 | Save the codes above into a file named `hello-ssdb.cpp`. 45 | 46 | ## Compile sample code 47 | 48 | If you are under the directory `api/cpp`, compile it like this 49 | 50 | g++ -o hello-ssdb hello-ssdb.cpp libssdb-client.a 51 | ./hello-ssdb 52 | 53 | Before you run `hello-ssdb`, you have to start ssdb-server with the default configuration. The output would be like 54 | 55 | k = hello ssdb! 56 | 57 | Connect to ssdb-server with `ssdb-cli`, to verify the key `k` is stored with the value "hello ssdb!". 58 | 59 | If your `hello-ssdb.cpp` file is not under the directory `api/cpp`, you will compile it like this 60 | 61 | g++ -o hello-ssdb -I hello-ssdb.cpp /libssdb-client.a 62 | 63 | -------------------------------------------------------------------------------- /src/include.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_INCLUDE_H_ 7 | #define SSDB_INCLUDE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "version.h" 28 | 29 | #ifndef UINT64_MAX 30 | #define UINT64_MAX 18446744073709551615ULL 31 | #endif 32 | #ifndef INT64_MAX 33 | #define INT64_MAX 0x7fffffffffffffffLL 34 | #endif 35 | 36 | 37 | static inline double microtime(){ 38 | struct timeval now; 39 | gettimeofday(&now, NULL); 40 | double ret = now.tv_sec + now.tv_usec/1000.0/1000.0; 41 | return ret; 42 | } 43 | 44 | static inline int64_t time_ms(){ 45 | struct timeval now; 46 | gettimeofday(&now, NULL); 47 | return (int64_t)now.tv_sec * 1000 + (int64_t)now.tv_usec/1000; 48 | } 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /src/net/.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | 3 | -------------------------------------------------------------------------------- /src/net/Makefile: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | OBJS = server.o resp.o proc.o worker.o fde.o link.o link_addr.o 4 | UTIL_OBJS = ../util/log.o ../util/config.o ../util/bytes.o 5 | EXES = test 6 | 7 | all: ${OBJS} 8 | ar -cru ./libnet.a ${OBJS} 9 | 10 | fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp 11 | ${CXX} ${CFLAGS} -c fde.cpp 12 | link_addr.o: link_addr.h link_addr.cpp 13 | ${CXX} ${CFLAGS} -c link_addr.cpp 14 | link.o: link.h link.cpp link_redis.h link_redis.cpp 15 | ${CXX} ${CFLAGS} -c link.cpp 16 | resp.o: resp.h resp.cpp 17 | ${CXX} ${CFLAGS} -c resp.cpp 18 | proc.o: proc.h proc.cpp 19 | ${CXX} ${CFLAGS} -c proc.cpp 20 | worker.o: worker.h worker.cpp 21 | ${CXX} ${CFLAGS} -c worker.cpp 22 | server.o: server.h server.cpp 23 | ${CXX} ${CFLAGS} -c server.cpp 24 | 25 | test: all 26 | ${CXX} -o test.out test.cpp ${CFLAGS} ${OBJS} ${UTIL_OBJS} ${CLIBS} 27 | ${CXX} -o test2.out test2.cpp ${CFLAGS} ${OBJS} ${UTIL_OBJS} ${CLIBS} 28 | 29 | clean: 30 | rm -f ${EXES} *.a *.o *.exe 31 | -------------------------------------------------------------------------------- /src/net/fde.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "fde.h" 7 | 8 | struct Fdevent* Fdevents::get_fde(int fd){ 9 | while((int)events.size() <= fd){ 10 | struct Fdevent *fde = new Fdevent(); 11 | fde->fd = events.size(); 12 | fde->s_flags = FDEVENT_NONE; 13 | fde->data.num = 0; 14 | fde->data.ptr = NULL; 15 | events.push_back(fde); 16 | } 17 | return events[fd]; 18 | } 19 | 20 | 21 | #ifdef HAVE_EPOLL 22 | #include "fde_epoll.cpp" 23 | #else 24 | #include "fde_select.cpp" 25 | #endif 26 | -------------------------------------------------------------------------------- /src/net/fde.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef UTIL_FDE_H 7 | #define UTIL_FDE_H 8 | 9 | #include "../include.h" 10 | 11 | #ifdef __linux__ 12 | #define HAVE_EPOLL 1 13 | #endif 14 | 15 | #define FDEVENT_NONE (0) 16 | #define FDEVENT_IN (1<<0) 17 | #define FDEVENT_PRI (1<<1) 18 | #define FDEVENT_OUT (1<<2) 19 | #define FDEVENT_HUP (1<<3) 20 | #define FDEVENT_ERR (1<<4) 21 | 22 | struct Fdevent{ 23 | int fd; 24 | int s_flags; // subscribed events 25 | int events; // ready events 26 | struct{ 27 | int num; 28 | void *ptr; 29 | }data; 30 | }; 31 | 32 | #include 33 | #ifdef HAVE_EPOLL 34 | #include 35 | #else 36 | #include 37 | #endif 38 | 39 | 40 | class Fdevents{ 41 | public: 42 | typedef std::vector events_t; 43 | private: 44 | #ifdef HAVE_EPOLL 45 | static const int MAX_FDS = 8 * 1024; 46 | int ep_fd; 47 | struct epoll_event ep_events[MAX_FDS]; 48 | #else 49 | int maxfd; 50 | fd_set readset; 51 | fd_set writeset; 52 | #endif 53 | events_t events; 54 | events_t ready_events; 55 | 56 | struct Fdevent *get_fde(int fd); 57 | public: 58 | Fdevents(); 59 | ~Fdevents(); 60 | 61 | bool isset(int fd, int flag); 62 | int set(int fd, int flags, int data_num, void *data_ptr); 63 | int del(int fd); 64 | int clr(int fd, int flags); 65 | const events_t* wait(int timeout_ms=-1); 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/net/link_addr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "link_addr.h" 4 | 5 | LinkAddr::LinkAddr(const char *ip, int port){ 6 | parse(ip, port); 7 | } 8 | 9 | LinkAddr::LinkAddr(bool is_ipv4){ 10 | this->is_ipv4(is_ipv4); 11 | } 12 | 13 | void LinkAddr::is_ipv4(bool yn){ 14 | if(yn){ 15 | ipv4 = true; 16 | family = AF_INET; 17 | addrlen = sizeof(addr4); 18 | }else{ 19 | ipv4 = false; 20 | family = AF_INET6; 21 | addrlen = sizeof(addr6); 22 | } 23 | } 24 | 25 | void LinkAddr::parse(const char *ip, int port){ 26 | this->is_ipv4(strchr(ip, ':') == NULL); 27 | if(ipv4){ 28 | bzero(&addr4, sizeof(addr4)); 29 | addr4.sin_family = family; 30 | addr4.sin_port = htons((short)port); 31 | inet_pton(family, ip, &addr4.sin_addr); 32 | }else{ 33 | bzero(&addr6, sizeof(addr6)); 34 | addr6.sin6_family = family; 35 | addr6.sin6_port = htons((short)port); 36 | inet_pton(family, ip, &addr6.sin6_addr); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/net/link_addr.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef NET_LINK_ADDR_H_ 7 | #define NET_LINK_ADDR_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | struct LinkAddr 15 | { 16 | bool ipv4; 17 | short family; 18 | socklen_t addrlen; 19 | 20 | LinkAddr(bool is_ipv4); 21 | LinkAddr(const char *ip, int port); 22 | void parse(const char *ip, int port); 23 | 24 | unsigned short port(){ 25 | return ipv4? ntohs(addr4.sin_port) : ntohs(addr6.sin6_port); 26 | } 27 | struct sockaddr* addr(){ 28 | return ipv4? (struct sockaddr *)&addr4 : (struct sockaddr *)&addr6; 29 | } 30 | void* sin_addr(){ 31 | return ipv4? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr; 32 | } 33 | 34 | private: 35 | struct sockaddr_in addr4; 36 | struct sockaddr_in6 addr6; 37 | 38 | LinkAddr(){}; 39 | void is_ipv4(bool yn); 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/net/link_redis.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef NET_REDIS_LINK_H_ 7 | #define NET_REDIS_LINK_H_ 8 | 9 | #include 10 | #include 11 | #include "../util/bytes.h" 12 | 13 | struct RedisRequestDesc 14 | { 15 | int strategy; 16 | std::string redis_cmd; 17 | std::string ssdb_cmd; 18 | int reply_type; 19 | }; 20 | 21 | class RedisLink 22 | { 23 | private: 24 | std::string cmd; 25 | RedisRequestDesc *req_desc; 26 | 27 | std::vector recv_bytes; 28 | std::vector recv_string; 29 | int parse_req(Buffer *input); 30 | int convert_req(); 31 | 32 | public: 33 | RedisLink(){ 34 | req_desc = NULL; 35 | } 36 | 37 | const std::vector* recv_req(Buffer *input); 38 | int send_resp(Buffer *output, const std::vector &resp); 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/net/proc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "proc.h" 7 | #include "server.h" 8 | #include "../util/log.h" 9 | 10 | ProcMap::ProcMap(){ 11 | } 12 | 13 | ProcMap::~ProcMap(){ 14 | proc_map_t::iterator it; 15 | for(it=proc_map.begin(); it!=proc_map.end(); it++){ 16 | delete it->second; 17 | } 18 | proc_map.clear(); 19 | } 20 | 21 | void ProcMap::set_proc(const std::string &c, proc_t proc){ 22 | this->set_proc(c, "t", proc); 23 | } 24 | 25 | void ProcMap::set_proc(const std::string &c, const char *sflags, proc_t proc){ 26 | Command *cmd = this->get_proc(c); 27 | if(!cmd){ 28 | cmd = new Command(); 29 | cmd->name = c; 30 | proc_map[cmd->name] = cmd; 31 | } 32 | cmd->proc = proc; 33 | cmd->flags = 0; 34 | for(const char *p=sflags; *p!='\0'; p++){ 35 | switch(*p){ 36 | case 'r': 37 | cmd->flags |= Command::FLAG_READ; 38 | break; 39 | case 'w': // w 必须和 t 同时出现, 因为某些写操作依赖单线程 40 | cmd->flags |= Command::FLAG_WRITE; 41 | cmd->flags |= Command::FLAG_THREAD; 42 | break; 43 | case 'b': 44 | cmd->flags |= Command::FLAG_BACKEND; 45 | break; 46 | case 't': 47 | cmd->flags |= Command::FLAG_THREAD; 48 | break; 49 | } 50 | } 51 | } 52 | 53 | Command* ProcMap::get_proc(const Bytes &str){ 54 | proc_map_t::iterator it = proc_map.find(str); 55 | if(it != proc_map.end()){ 56 | return it->second; 57 | } 58 | return NULL; 59 | } 60 | -------------------------------------------------------------------------------- /src/net/resp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef NET_RESP_H_ 7 | #define NET_RESP_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class Response 15 | { 16 | public: 17 | std::vector resp; 18 | 19 | int size() const; 20 | void push_back(const std::string &s); 21 | void add(int s); 22 | void add(int64_t s); 23 | void add(uint64_t s); 24 | void add(double s); 25 | void add(const std::string &s); 26 | 27 | void reply_status(int status, const char *errmsg=NULL); 28 | void reply_bool(int status, const char *errmsg=NULL); 29 | void reply_int(int status, int64_t val); 30 | // the same as Redis.REPLY_BULK 31 | void reply_get(int status, const std::string *val=NULL, const char *errmsg=NULL); 32 | void reply_list(int status, const std::vector &list); 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/net/server.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef NET_SERVER_H_ 7 | #define NET_SERVER_H_ 8 | 9 | #include "../include.h" 10 | #include 11 | #include 12 | #include 13 | 14 | #include "fde.h" 15 | #include "proc.h" 16 | #include "worker.h" 17 | 18 | class Link; 19 | class Config; 20 | class IpFilter; 21 | class Fdevents; 22 | 23 | typedef std::vector ready_list_t; 24 | 25 | class NetworkServer 26 | { 27 | private: 28 | int tick_interval; 29 | int status_report_ticks; 30 | 31 | //Config *conf; 32 | Link *serv_link; 33 | Fdevents *fdes; 34 | 35 | Link* accept_link(); 36 | int proc_result(ProcJob *job, ready_list_t *ready_list); 37 | int proc_client_event(const Fdevent *fde, ready_list_t *ready_list); 38 | 39 | int proc(ProcJob *job); 40 | 41 | int num_readers; 42 | int num_writers; 43 | ProcWorkerPool *writer; 44 | ProcWorkerPool *reader; 45 | 46 | bool readonly; 47 | 48 | NetworkServer(); 49 | 50 | protected: 51 | void usage(int argc, char **argv); 52 | 53 | public: 54 | IpFilter *ip_filter; 55 | void *data; 56 | ProcMap proc_map; 57 | int link_count; 58 | bool need_auth; 59 | std::set passwords; 60 | double slowlog_timeout; // in ms, but in config file, it's in seconds 61 | 62 | ~NetworkServer(); 63 | 64 | // could be called only once 65 | static NetworkServer* init(const char *conf_file, int num_readers=-1, int num_writers=-1); 66 | static NetworkServer* init(const Config &conf, int num_readers=-1, int num_writers=-1); 67 | void serve(); 68 | }; 69 | 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/net/test.conf: -------------------------------------------------------------------------------- 1 | pidfile = ./test.pid 2 | 3 | server: 4 | #ip: 127.0.0.1 5 | ip: ::1 6 | port: 9001 7 | # bind to public ip 8 | #ip: 0.0.0.0 9 | # format: allow|deny: all|ip_prefix 10 | # multiple allows or denys is supported 11 | #deny: all 12 | allow: 127.0.0.1 13 | allow: ::1 14 | #allow: 192.168 15 | # auth password must be longer than 31 characters 16 | #auth: very-strong-passwordwwwwwwwwwwwwww 17 | auth: a-123456789012345678901234567890 18 | auth: b-123456789012345678901234567890 19 | readonly: no 20 | 21 | logger: 22 | level: debug 23 | output: stdout 24 | rotate: 25 | size: 1000000000 26 | -------------------------------------------------------------------------------- /src/net/test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "server.h" 7 | 8 | void usage(int argc, char **argv){ 9 | printf("Usage:\n"); 10 | printf(" %s [-d] /path/to/server.conf\n", argv[0]); 11 | printf("Options:\n"); 12 | printf(" -d run as daemon\n"); 13 | } 14 | 15 | DEF_PROC(hello); 16 | 17 | int main(int argc, char **argv){ 18 | bool is_daemon = false; 19 | const char *conf_file = NULL; 20 | for(int i=1; iproc_map.set_proc("hello", "w", proc_hello); 38 | serv->serve(); 39 | delete serv; 40 | return 0; 41 | } 42 | 43 | int proc_hello(NetworkServer *net, Link *link, const Request &req, Response *resp){ 44 | resp->push_back("ok"); 45 | resp->push_back("world!"); 46 | if(req.size() > 1){ 47 | // The first argument start at index 1, just like argv. 48 | resp->push_back(req[1].String()); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/net/test2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "server.h" 7 | #include "../util/config.h" 8 | 9 | DEF_PROC(hello); 10 | 11 | int main(int argc, char **argv){ 12 | fprintf(stderr, "Usage: %s [ip] [port]\n\n", argv[0]); 13 | Config conf; 14 | conf.set("server.port", "9000"); 15 | if(argc > 1){ 16 | conf.set("server.ip", argv[1]); 17 | } 18 | if(argc > 2){ 19 | conf.set("server.port", argv[2]); 20 | } 21 | NetworkServer *serv = NetworkServer::init(conf); 22 | if(!serv){ 23 | exit(1); 24 | } 25 | // register command procedure 26 | serv->proc_map.set_proc("hello", proc_hello); 27 | serv->serve(); 28 | delete serv; 29 | return 0; 30 | } 31 | 32 | int proc_hello(NetworkServer *net, Link *link, const Request &req, Response *resp){ 33 | resp->push_back("ok"); 34 | resp->push_back("world!"); 35 | if(req.size() > 1){ 36 | // The first argument start at index 1, just like argv. 37 | resp->push_back(req[1].String()); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/net/worker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "worker.h" 7 | #include "link.h" 8 | #include "proc.h" 9 | #include "../util/log.h" 10 | #include "../include.h" 11 | 12 | ProcWorker::ProcWorker(const std::string &name){ 13 | this->name = name; 14 | } 15 | 16 | void ProcWorker::init(){ 17 | log_debug("%s %d init", this->name.c_str(), this->id); 18 | } 19 | 20 | int ProcWorker::proc(ProcJob *job){ 21 | const Request *req = job->req; 22 | 23 | proc_t p = job->cmd->proc; 24 | job->time_wait = 1000 * (microtime() - job->stime); 25 | job->result = (*p)(job->serv, job->link, *req, &job->resp); 26 | job->time_proc = 1000 * (microtime() - job->stime) - job->time_wait; 27 | 28 | if(job->link->send(job->resp.resp) == -1){ 29 | job->result = PROC_ERROR; 30 | }else{ 31 | // try to write socket before it would be added to fdevents 32 | // socket is NONBLOCK, so it won't block. 33 | if(job->link->write() < 0){ 34 | job->result = PROC_ERROR; 35 | } 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /src/net/worker.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef NET_WORKER_H_ 7 | #define NET_WORKER_H_ 8 | 9 | #include 10 | #include "../util/thread.h" 11 | #include "proc.h" 12 | 13 | // WARN: pipe latency is about 20 us, it is really slow! 14 | class ProcWorker : public WorkerPool::Worker{ 15 | public: 16 | ProcWorker(const std::string &name); 17 | ~ProcWorker(){} 18 | void init(); 19 | int proc(ProcJob *job); 20 | }; 21 | 22 | typedef WorkerPool ProcWorkerPool; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/proc_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2018 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | /* hash commands */ 7 | #include "serv.h" 8 | #include "net/proc.h" 9 | #include "net/server.h" 10 | 11 | DEF_PROC(hsize); 12 | DEF_PROC(hget); 13 | DEF_PROC(hset); 14 | DEF_PROC(hdel); 15 | DEF_PROC(hincr); 16 | DEF_PROC(hdecr); 17 | DEF_PROC(hclear); 18 | DEF_PROC(hgetall); 19 | DEF_PROC(hscan); 20 | DEF_PROC(hrscan); 21 | DEF_PROC(hkeys); 22 | DEF_PROC(hvals); 23 | DEF_PROC(hlist); 24 | DEF_PROC(hrlist); 25 | DEF_PROC(hexists); 26 | DEF_PROC(multi_hexists); 27 | DEF_PROC(multi_hsize); 28 | DEF_PROC(multi_hget); 29 | DEF_PROC(multi_hset); 30 | DEF_PROC(multi_hdel); 31 | DEF_PROC(hfix); 32 | -------------------------------------------------------------------------------- /src/proc_kv.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2018 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | /* kv commands */ 7 | #include "serv.h" 8 | #include "net/proc.h" 9 | #include "net/server.h" 10 | 11 | DEF_PROC(get); 12 | DEF_PROC(set); 13 | DEF_PROC(setx); 14 | DEF_PROC(setnx); 15 | DEF_PROC(getset); 16 | DEF_PROC(getbit); 17 | DEF_PROC(setbit); 18 | DEF_PROC(countbit); 19 | DEF_PROC(substr); 20 | DEF_PROC(getrange); 21 | DEF_PROC(strlen); 22 | DEF_PROC(bitcount); 23 | DEF_PROC(del); 24 | DEF_PROC(incr); 25 | DEF_PROC(decr); 26 | DEF_PROC(scan); 27 | DEF_PROC(rscan); 28 | DEF_PROC(keys); 29 | DEF_PROC(rkeys); 30 | DEF_PROC(exists); 31 | DEF_PROC(multi_exists); 32 | DEF_PROC(multi_get); 33 | DEF_PROC(multi_set); 34 | DEF_PROC(multi_del); 35 | DEF_PROC(ttl); 36 | DEF_PROC(expire); 37 | -------------------------------------------------------------------------------- /src/proc_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2018 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | /* system commands */ 7 | #include "serv.h" 8 | #include "net/proc.h" 9 | #include "net/server.h" 10 | 11 | DEF_PROC(qsize); 12 | DEF_PROC(qfront); 13 | DEF_PROC(qback); 14 | DEF_PROC(qpush); 15 | DEF_PROC(qpush_front); 16 | DEF_PROC(qpush_back); 17 | DEF_PROC(qpop); 18 | DEF_PROC(qpop_front); 19 | DEF_PROC(qpop_back); 20 | DEF_PROC(qtrim_front); 21 | DEF_PROC(qtrim_back); 22 | DEF_PROC(qfix); 23 | DEF_PROC(qclear); 24 | DEF_PROC(qlist); 25 | DEF_PROC(qrlist); 26 | DEF_PROC(qslice); 27 | DEF_PROC(qrange); 28 | DEF_PROC(qget); 29 | DEF_PROC(qset); 30 | -------------------------------------------------------------------------------- /src/proc_sys.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2018 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | /* system commands */ 7 | #include "serv.h" 8 | #include "net/proc.h" 9 | #include "net/server.h" 10 | 11 | DEF_PROC(flushdb); 12 | DEF_PROC(info); 13 | DEF_PROC(version); 14 | DEF_PROC(dbsize); 15 | DEF_PROC(compact); 16 | DEF_PROC(dump); 17 | DEF_PROC(sync140); 18 | DEF_PROC(slaveof); 19 | DEF_PROC(clear_binlog); 20 | 21 | DEF_PROC(get_key_range); 22 | DEF_PROC(ignore_key_range); 23 | DEF_PROC(get_kv_range); 24 | DEF_PROC(set_kv_range); 25 | -------------------------------------------------------------------------------- /src/proc_zset.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2018 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | /* zset commands */ 7 | #include "serv.h" 8 | #include "net/proc.h" 9 | #include "net/server.h" 10 | 11 | DEF_PROC(zrank); 12 | DEF_PROC(zrrank); 13 | DEF_PROC(zrange); 14 | DEF_PROC(zrrange); 15 | DEF_PROC(redis_zrange); 16 | DEF_PROC(redis_zrrange); 17 | DEF_PROC(zsize); 18 | DEF_PROC(zget); 19 | DEF_PROC(zset); 20 | DEF_PROC(zdel); 21 | DEF_PROC(zincr); 22 | DEF_PROC(zdecr); 23 | DEF_PROC(zclear); 24 | DEF_PROC(zfix); 25 | DEF_PROC(zscan); 26 | DEF_PROC(zrscan); 27 | DEF_PROC(zkeys); 28 | DEF_PROC(zlist); 29 | DEF_PROC(zrlist); 30 | DEF_PROC(zcount); 31 | DEF_PROC(zsum); 32 | DEF_PROC(zavg); 33 | DEF_PROC(zexists); 34 | DEF_PROC(zremrangebyrank); 35 | DEF_PROC(zremrangebyscore); 36 | DEF_PROC(multi_zexists); 37 | DEF_PROC(multi_zsize); 38 | DEF_PROC(multi_zget); 39 | DEF_PROC(multi_zset); 40 | DEF_PROC(multi_zdel); 41 | DEF_PROC(zpop_front); 42 | DEF_PROC(zpop_back); 43 | -------------------------------------------------------------------------------- /src/serv.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_SERVER_H_ 7 | #define SSDB_SERVER_H_ 8 | 9 | #include "include.h" 10 | #include 11 | #include 12 | #include 13 | #include "ssdb/ssdb_impl.h" 14 | #include "ssdb/ttl.h" 15 | #include "backend_dump.h" 16 | #include "backend_sync.h" 17 | #include "slave.h" 18 | #include "net/server.h" 19 | 20 | class SSDBServer 21 | { 22 | private: 23 | void reg_procs(NetworkServer *net); 24 | 25 | std::string kv_range_s; 26 | std::string kv_range_e; 27 | 28 | SSDB *meta; 29 | 30 | public: 31 | SSDBImpl *ssdb; 32 | BackendDump *backend_dump; 33 | BackendSync *backend_sync; 34 | ExpirationHandler *expiration; 35 | std::vector slaves; 36 | 37 | SSDBServer(SSDB *ssdb, SSDB *meta, const Config &conf, NetworkServer *net); 38 | ~SSDBServer(); 39 | 40 | int slaveof(const std::string &id, const std::string &host, int port, const std::string &auth, uint64_t last_seq, const std::string &last_key, bool is_mirror, int recv_timeout); 41 | 42 | int set_kv_range(const std::string &s, const std::string &e); 43 | int get_kv_range(std::string *s, std::string *e); 44 | bool in_kv_range(const std::string &key); 45 | bool in_kv_range(const Bytes &key); 46 | }; 47 | 48 | #define CHECK_KV_KEY_RANGE(n) do{ \ 49 | if(!link->ignore_key_range && req.size() > n){ \ 50 | if(!serv->in_kv_range(req[n])){ \ 51 | resp->push_back("out_of_range"); \ 52 | return 0; \ 53 | } \ 54 | } \ 55 | }while(0) 56 | 57 | #define CHECK_NUM_PARAMS(n) do{ \ 58 | if(req.size() < n){ \ 59 | resp->push_back("client_error"); \ 60 | resp->push_back("wrong number of arguments"); \ 61 | return 0; \ 62 | } \ 63 | }while(0) 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/slave.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_SLAVE_H_ 7 | #define SSDB_SLAVE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "ssdb/ssdb_impl.h" 14 | #include "ssdb/binlog.h" 15 | #include "net/link.h" 16 | 17 | class Slave{ 18 | private: 19 | uint64_t copy_count; 20 | uint64_t sync_count; 21 | 22 | std::string id_; 23 | 24 | SSDB *ssdb; 25 | SSDB *meta; 26 | Link *link; 27 | std::string master_ip; 28 | int master_port; 29 | bool is_mirror; 30 | char log_type; 31 | 32 | static const int DISCONNECTED = 0; 33 | static const int INIT = 1; 34 | static const int COPY = 2; 35 | static const int SYNC = 4; 36 | static const int OUT_OF_SYNC = 8; 37 | int status; 38 | 39 | void migrate_old_status(); 40 | 41 | std::string status_key(); 42 | void load_status(); 43 | void save_status(); 44 | 45 | volatile bool thread_quit; 46 | pthread_t run_thread_tid; 47 | static void* _run_thread(void *arg); 48 | 49 | int proc(const std::vector &req); 50 | int proc_noop(const Binlog &log, const std::vector &req); 51 | int proc_copy(const Binlog &log, const std::vector &req); 52 | int proc_sync(const Binlog &log, const std::vector &req); 53 | 54 | unsigned int connect_retry; 55 | int connect(); 56 | bool connected(){ 57 | return link != NULL; 58 | } 59 | public: 60 | // the max time wait for a noop or binlog message from master, 61 | // after this time, the slave will disconnect from master. 62 | // in seconds, default 30 63 | int recv_timeout; 64 | uint64_t last_seq; 65 | std::string last_key; 66 | std::string auth; 67 | Slave(SSDB *ssdb, SSDB *meta, const char *ip, int port, bool is_mirror=false); 68 | ~Slave(); 69 | void start(); 70 | void stop(); 71 | 72 | void set_id(const std::string &id); 73 | std::string stats() const; 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/ssdb/Makefile: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | OBJS = ssdb_impl.o iterator.o options.o \ 4 | t_kv.o t_hash.o t_zset.o t_queue.o binlog.o ttl.o 5 | LIBS = ../util/libutil.a 6 | 7 | 8 | all: ssdb.h ${OBJS} 9 | ar -cru ./libssdb.a ${OBJS} 10 | 11 | ssdb_impl.o: ssdb.h ssdb_impl.h ssdb_impl.cpp 12 | ${CXX} ${CFLAGS} -c ssdb_impl.cpp 13 | iterator.o: ssdb.h iterator.h iterator.cpp 14 | ${CXX} ${CFLAGS} -c iterator.cpp 15 | options.o: ssdb.h options.h options.cpp 16 | ${CXX} ${CFLAGS} -c options.cpp 17 | t_kv.o: ssdb.h t_kv.h t_kv.cpp 18 | ${CXX} ${CFLAGS} -c t_kv.cpp 19 | t_hash.o: ssdb.h t_hash.h t_hash.cpp 20 | ${CXX} ${CFLAGS} -c t_hash.cpp 21 | t_zset.o: ssdb.h t_zset.h t_zset.cpp 22 | ${CXX} ${CFLAGS} -c t_zset.cpp 23 | t_queue.o: ssdb.h t_queue.h t_queue.cpp 24 | ${CXX} ${CFLAGS} -c t_queue.cpp 25 | binlog.o: ssdb.h binlog.h binlog.cpp 26 | ${CXX} ${CFLAGS} -c binlog.cpp 27 | ttl.o: ssdb.h ttl.h ttl.cpp 28 | ${CXX} ${CFLAGS} -c ttl.cpp 29 | 30 | test: 31 | ${CXX} -o test.out test.cpp ${OBJS} ${CFLAGS} ${LIBS} ${CLIBS} 32 | 33 | clean: 34 | rm -f ${EXES} *.o *.exe *.a 35 | 36 | -------------------------------------------------------------------------------- /src/ssdb/Makefile-ios: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms 4 | SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer 5 | DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer 6 | IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString) 7 | SIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk 8 | DEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk 9 | 10 | CFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DIOS -I. -O2 -I$(LEVELDB_PATH)/include 11 | SIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64 12 | DEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64 13 | 14 | OBJS = ssdb_impl.o iterator.o options.o t_kv.o t_hash.o t_zset.o t_queue.o binlog.o ttl.o 15 | LIB = libssdb-ios.a 16 | OUTPUT_LIB_DIR = ../../ios 17 | OUTPUT_HEADER_DIR = ../../ios/include/ssdb 18 | 19 | all: $(OBJS) 20 | rm -f $(LIB) 21 | ar -rs $(LIB) $(OBJS) 22 | rm -rf $(OUTPUT_HEADER_DIR) $(OUTPUT_LIB_DIR)/$(LIB) 23 | mkdir -p $(OUTPUT_HEADER_DIR) 24 | cp -f const.h binlog.h iterator.h options.h ssdb.h ttl.h $(OUTPUT_HEADER_DIR) 25 | mv -f $(LIB) $(OUTPUT_LIB_DIR) 26 | 27 | .cpp.o: 28 | mkdir -p ios-x86 29 | mkdir -p ios-arm 30 | xcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@ 31 | xcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@ 32 | lipo ios-x86/$@ ios-arm/$@ -create -output $@ 33 | 34 | clean: 35 | rm -f ${EXES} *.o *.exe *.a 36 | 37 | -------------------------------------------------------------------------------- /src/ssdb/const.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_CONST_H_ 7 | #define SSDB_CONST_H_ 8 | 9 | static const int SSDB_SCORE_WIDTH = 9; 10 | static const int SSDB_KEY_LEN_MAX = 255; 11 | 12 | class DataType{ 13 | public: 14 | static const char SYNCLOG = 1; 15 | static const char KV = 'k'; 16 | static const char HASH = 'h'; // hashmap(sorted by key) 17 | static const char HSIZE = 'H'; 18 | static const char ZSET = 's'; // key => score 19 | static const char ZSCORE = 'z'; // key|score => "" 20 | static const char ZSIZE = 'Z'; 21 | static const char QUEUE = 'q'; 22 | static const char QSIZE = 'Q'; 23 | static const char MIN_PREFIX = HASH; 24 | static const char MAX_PREFIX = ZSET; 25 | }; 26 | 27 | class BinlogType{ 28 | public: 29 | static const char NOOP = 0; 30 | static const char SYNC = 1; 31 | static const char MIRROR = 2; 32 | static const char COPY = 3; 33 | static const char CTRL = 4; 34 | }; 35 | 36 | class BinlogCommand{ 37 | public: 38 | static const char NONE = 0; 39 | static const char KSET = 1; 40 | static const char KDEL = 2; 41 | static const char HSET = 3; 42 | static const char HDEL = 4; 43 | static const char ZSET = 5; 44 | static const char ZDEL = 6; 45 | 46 | static const char QPUSH_BACK = 10; 47 | static const char QPUSH_FRONT = 11; 48 | static const char QPOP_BACK = 12; 49 | static const char QPOP_FRONT = 13; 50 | static const char QSET = 14; 51 | 52 | static const char BEGIN = 7; 53 | static const char END = 8; 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/ssdb/iterator.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_ITERATOR_H_ 7 | #define SSDB_ITERATOR_H_ 8 | 9 | #include 10 | #include 11 | #include "../util/bytes.h" 12 | 13 | namespace leveldb{ 14 | class Iterator; 15 | } 16 | 17 | class Iterator{ 18 | public: 19 | enum Direction{ 20 | FORWARD, BACKWARD 21 | }; 22 | Iterator(leveldb::Iterator *it, 23 | const std::string &end, 24 | uint64_t limit, 25 | Direction direction=Iterator::FORWARD); 26 | ~Iterator(); 27 | bool skip(uint64_t offset); 28 | bool next(); 29 | Bytes key(); 30 | Bytes val(); 31 | private: 32 | leveldb::Iterator *it; 33 | std::string end; 34 | uint64_t limit; 35 | bool is_first; 36 | int direction; 37 | }; 38 | 39 | 40 | class KIterator{ 41 | public: 42 | std::string key; 43 | std::string val; 44 | 45 | KIterator(Iterator *it); 46 | ~KIterator(); 47 | void return_val(bool onoff); 48 | bool next(); 49 | private: 50 | Iterator *it; 51 | bool return_val_; 52 | }; 53 | 54 | 55 | class HIterator{ 56 | public: 57 | std::string name; 58 | std::string key; 59 | std::string val; 60 | 61 | HIterator(Iterator *it, const Bytes &name); 62 | ~HIterator(); 63 | void return_val(bool onoff); 64 | bool next(); 65 | private: 66 | Iterator *it; 67 | bool return_val_; 68 | }; 69 | 70 | 71 | class ZIterator{ 72 | public: 73 | std::string name; 74 | std::string key; 75 | std::string score; 76 | 77 | ZIterator(Iterator *it, const Bytes &name); 78 | ~ZIterator(); 79 | bool skip(uint64_t offset); 80 | bool next(); 81 | private: 82 | Iterator *it; 83 | }; 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/ssdb/options.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include "options.h" 7 | #include "../util/string_util.h" 8 | 9 | #ifdef NDEBUG 10 | static const int LOG_QUEUE_SIZE = 20 * 1000 * 1000; 11 | #else 12 | static const int LOG_QUEUE_SIZE = 10000; 13 | #endif 14 | 15 | Options::Options(){ 16 | Config c; 17 | this->load(c); 18 | } 19 | 20 | void Options::load(const Config &conf){ 21 | cache_size = (size_t)conf.get_num("leveldb.cache_size"); 22 | max_open_files = (size_t)conf.get_num("leveldb.max_open_files"); 23 | write_buffer_size = (size_t)conf.get_num("leveldb.write_buffer_size"); 24 | block_size = (size_t)conf.get_num("leveldb.block_size"); 25 | compaction_speed = conf.get_num("leveldb.compaction_speed"); 26 | compression = conf.get_str("leveldb.compression"); 27 | std::string binlog = conf.get_str("replication.binlog"); 28 | binlog_capacity = (size_t)conf.get_num("replication.binlog.capacity"); 29 | 30 | strtolower(&compression); 31 | if(compression != "no"){ 32 | compression = "yes"; 33 | } 34 | strtolower(&binlog); 35 | if(binlog != "yes"){ 36 | this->binlog = false; 37 | }else{ 38 | this->binlog = true; 39 | } 40 | if(binlog_capacity <= 0){ 41 | binlog_capacity = LOG_QUEUE_SIZE; 42 | } 43 | 44 | if(cache_size <= 0){ 45 | cache_size = 16; 46 | } 47 | if(write_buffer_size <= 0){ 48 | write_buffer_size = 16; 49 | } 50 | if(block_size <= 0){ 51 | block_size = 32; 52 | } 53 | if(max_open_files <= 0){ 54 | max_open_files = cache_size / 1024 * 300; 55 | if(max_open_files < 500){ 56 | max_open_files = 500; 57 | } 58 | if(max_open_files > 1000){ 59 | max_open_files = 1000; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/ssdb/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_OPTION_H_ 7 | #define SSDB_OPTION_H_ 8 | 9 | #include "../util/config.h" 10 | 11 | class Options 12 | { 13 | public: 14 | Options(); 15 | ~Options(){} 16 | 17 | void load(const Config &conf); 18 | 19 | size_t cache_size; 20 | size_t max_open_files; 21 | size_t write_buffer_size; 22 | size_t block_size; 23 | int compaction_speed; 24 | std::string compression; 25 | bool binlog; 26 | size_t binlog_capacity; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/ssdb/t_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_HASH_H_ 7 | #define SSDB_HASH_H_ 8 | 9 | #include "ssdb_impl.h" 10 | 11 | inline static 12 | std::string encode_hsize_key(const Bytes &name){ 13 | std::string buf; 14 | buf.reserve(name.size() + 1); 15 | buf.append(1, DataType::HSIZE); 16 | buf.append(name.data(), name.size()); 17 | return buf; 18 | } 19 | 20 | inline static 21 | int decode_hsize_key(const Bytes &slice, std::string *name){ 22 | Decoder decoder(slice.data(), slice.size()); 23 | if(decoder.skip(1) == -1){ 24 | return -1; 25 | } 26 | if(decoder.read_data(name) == -1){ 27 | return -1; 28 | } 29 | return 0; 30 | } 31 | 32 | inline static 33 | std::string encode_hash_key(const Bytes &name, const Bytes &key){ 34 | std::string buf; 35 | buf.reserve(128); 36 | buf.append(1, DataType::HASH); 37 | buf.append(1, (uint8_t)name.size()); 38 | buf.append(name.data(), name.size()); 39 | buf.append(1, '='); 40 | buf.append(key.data(), key.size()); 41 | return buf; 42 | } 43 | 44 | inline static 45 | int decode_hash_key(const Bytes &slice, std::string *name, std::string *key){ 46 | Decoder decoder(slice.data(), slice.size()); 47 | if(decoder.skip(1) == -1){ 48 | return -1; 49 | } 50 | if(decoder.read_8_data(name) == -1){ 51 | return -1; 52 | } 53 | if(decoder.skip(1) == -1){ 54 | return -1; 55 | } 56 | if(decoder.read_data(key) == -1){ 57 | return -1; 58 | } 59 | return 0; 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/ssdb/t_kv.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_KV_H_ 7 | #define SSDB_KV_H_ 8 | 9 | #include "ssdb_impl.h" 10 | 11 | static inline 12 | std::string encode_kv_key(const Bytes &key){ 13 | std::string buf; 14 | buf.reserve(key.size() + 1); 15 | buf.append(1, DataType::KV); 16 | buf.append(key.data(), key.size()); 17 | return buf; 18 | } 19 | 20 | static inline 21 | int decode_kv_key(const Bytes &slice, std::string *key){ 22 | Decoder decoder(slice.data(), slice.size()); 23 | if(decoder.skip(1) == -1){ 24 | return -1; 25 | } 26 | if(decoder.read_data(key) == -1){ 27 | return -1; 28 | } 29 | return 0; 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/ssdb/t_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_QUEUE_H_ 7 | #define SSDB_QUEUE_H_ 8 | 9 | #include "ssdb_impl.h" 10 | 11 | const uint64_t QFRONT_SEQ = 2; 12 | const uint64_t QBACK_SEQ = 3; 13 | const uint64_t QITEM_MIN_SEQ = 10000; 14 | const uint64_t QITEM_MAX_SEQ = 9223372036854775807ULL; 15 | const uint64_t QITEM_SEQ_INIT = QITEM_MAX_SEQ/2; 16 | 17 | inline static 18 | std::string encode_qsize_key(const Bytes &name){ 19 | std::string buf; 20 | buf.reserve(name.size() + 1); 21 | buf.append(1, DataType::QSIZE); 22 | buf.append(name.data(), name.size()); 23 | return buf; 24 | } 25 | 26 | inline static 27 | int decode_qsize_key(const Bytes &slice, std::string *name){ 28 | Decoder decoder(slice.data(), slice.size()); 29 | if(decoder.skip(1) == -1){ 30 | return -1; 31 | } 32 | if(decoder.read_data(name) == -1){ 33 | return -1; 34 | } 35 | return 0; 36 | } 37 | 38 | inline static 39 | std::string encode_qitem_key(const Bytes &name, uint64_t seq){ 40 | std::string buf; 41 | buf.reserve(128); 42 | buf.append(1, DataType::QUEUE); 43 | buf.append(1, (uint8_t)name.size()); 44 | buf.append(name.data(), name.size()); 45 | seq = big_endian(seq); 46 | buf.append((char *)&seq, sizeof(uint64_t)); 47 | return buf; 48 | } 49 | 50 | inline static 51 | int decode_qitem_key(const Bytes &slice, std::string *name, uint64_t *seq){ 52 | Decoder decoder(slice.data(), slice.size()); 53 | if(decoder.skip(1) == -1){ 54 | return -1; 55 | } 56 | if(decoder.read_8_data(name) == -1){ 57 | return -1; 58 | } 59 | if(decoder.read_uint64(seq) == -1){ 60 | return -1; 61 | } 62 | *seq = big_endian(*seq); 63 | return 0; 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/ssdb/test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include 7 | #include "ssdb.h" 8 | #include "../util/log.h" 9 | #include "../util/config.h" 10 | 11 | int main(int argc, char **argv){ 12 | set_log_level(Logger::LEVEL_TRACE); 13 | std::string work_dir = "./tmp/a"; 14 | Options opt; 15 | opt.compression = "no"; 16 | 17 | SSDB *ssdb = NULL; 18 | ssdb = SSDB::open(opt, work_dir); 19 | if(!ssdb){ 20 | log_fatal("could not open work_dir: %s", work_dir.c_str()); 21 | fprintf(stderr, "could not open work_dir: %s\n", work_dir.c_str()); 22 | exit(1); 23 | } 24 | std::string key, val; 25 | key = "a"; 26 | 27 | val.append(1024 * 1024, 'a'); 28 | ssdb->raw_set("tmp", val); 29 | ssdb->compact(); 30 | 31 | uint64_t size; 32 | size = ssdb->size(); 33 | log_debug("dbsize: %d", size); 34 | 35 | 36 | ssdb->get(key, &val); 37 | int num = str_to_int(val) + 1; 38 | ssdb->set(key, str(num)); 39 | ssdb->get(key, &val); 40 | 41 | log_debug("%s", val.c_str()); 42 | delete ssdb; 43 | } 44 | -------------------------------------------------------------------------------- /src/ssdb/ttl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef SSDB_TTL_H_ 7 | #define SSDB_TTL_H_ 8 | 9 | #include "ssdb.h" 10 | #include "../util/thread.h" 11 | #include "../util/sorted_set.h" 12 | #include 13 | 14 | class ExpirationHandler 15 | { 16 | public: 17 | Mutex mutex; 18 | 19 | ExpirationHandler(SSDB *ssdb); 20 | ~ExpirationHandler(); 21 | 22 | // "In Redis 2.6 or older the command returns -1 if the key does not exist 23 | // or if the key exist but has no associated expire. Starting with Redis 2.8.." 24 | // I stick to Redis 2.6 25 | int64_t get_ttl(const Bytes &key); 26 | // The caller must hold mutex before calling set/del functions 27 | int del_ttl(const Bytes &key); 28 | int set_ttl(const Bytes &key, int64_t ttl); 29 | 30 | private: 31 | SSDB *ssdb; 32 | volatile bool thread_quit; 33 | std::string list_name; 34 | int64_t first_timeout; 35 | SortedSet fast_keys; 36 | 37 | void start(); 38 | void stop(); 39 | void expire_loop(); 40 | static void* thread_func(void *arg); 41 | void load_expiration_keys_from_db(int num); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/util/Makefile: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | OBJS = log.o config.o bytes.o sorted_set.o app.o 4 | EXES = 5 | 6 | all: ${OBJS} 7 | ar -cru ./libutil.a ${OBJS} 8 | 9 | app.o: app.h app.cpp 10 | ${CXX} ${CFLAGS} -c app.cpp 11 | 12 | log.o: log.h log.cpp 13 | ${CXX} ${CFLAGS} -c log.cpp 14 | 15 | config.o: config.h config.cpp 16 | ${CXX} ${CFLAGS} -c config.cpp 17 | 18 | bytes.o: bytes.h bytes.cpp 19 | ${CXX} ${CFLAGS} -c bytes.cpp 20 | 21 | sorted_set.o: sorted_set.h sorted_set.cpp 22 | ${CXX} ${CFLAGS} -c sorted_set.cpp 23 | 24 | test: 25 | $(CXX) ${CFLAGS} test_sorted_set.cpp $(OBJS) 26 | 27 | clean: 28 | rm -f ${EXES} ${OBJS} *.o *.exe *.a 29 | 30 | -------------------------------------------------------------------------------- /src/util/Makefile-ios: -------------------------------------------------------------------------------- 1 | include ../../build_config.mk 2 | 3 | PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms 4 | SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer 5 | DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer 6 | IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString) 7 | SIMULATOR_SDK=$(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk 8 | DEVICE_SDK=$(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk 9 | 10 | CFLAGS= -miphoneos-version-min=7.0 -stdlib=libc++ -DIOS -I. -O2 -I$(LEVELDB_PATH)/include 11 | SIMULATOR_CFLAGS=$(CFLAGS) -isysroot $(SIMULATOR_SDK) -arch i386 -arch x86_64 12 | DEVICE_CFLAGS=$(CFLAGS) -isysroot $(DEVICE_SDK) -arch armv6 -arch armv7 -arch armv7s -arch arm64 13 | 14 | OBJS = config.o bytes.o sorted_set.o 15 | LIB = libutil-ios.a 16 | OUTPUT_LIB_DIR = ../../ios 17 | OUTPUT_HEADER_DIR = ../../ios/include/util 18 | 19 | all: $(OBJS) 20 | rm -f $(LIB) 21 | ar -rs $(LIB) $(OBJS) 22 | rm -rf $(OUTPUT_HEADER_DIR) $(OUTPUT_LIB_DIR)/$(LIB) 23 | mkdir -p $(OUTPUT_HEADER_DIR) 24 | cp -f config.h bytes.h string_util.h $(OUTPUT_HEADER_DIR) 25 | mv -f $(LIB) $(OUTPUT_LIB_DIR) 26 | 27 | .cpp.o: 28 | mkdir -p ios-x86 29 | mkdir -p ios-arm 30 | xcrun -sdk iphonesimulator clang++ $(SIMULATOR_CFLAGS) -c $< -o ios-x86/$@ 31 | xcrun -sdk iphoneos clang++ $(DEVICE_CFLAGS) -c $< -o ios-arm/$@ 32 | lipo ios-x86/$@ ios-arm/$@ -create -output $@ 33 | 34 | clean: 35 | rm -f ${EXES} *.o *.exe *.a 36 | 37 | -------------------------------------------------------------------------------- /src/util/app.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_APP_H 2 | #define UTIL_APP_H 3 | 4 | #include 5 | 6 | class Config; 7 | 8 | class Application{ 9 | public: 10 | Application(){}; 11 | virtual ~Application(){}; 12 | 13 | int main(int argc, char **argv); 14 | 15 | virtual void usage(int argc, char **argv); 16 | virtual void welcome() = 0; 17 | virtual void run() = 0; 18 | 19 | protected: 20 | struct AppArgs{ 21 | bool is_daemon; 22 | std::string pidfile; 23 | std::string conf_file; 24 | std::string work_dir; 25 | std::string start_opt; 26 | 27 | AppArgs(){ 28 | is_daemon = false; 29 | start_opt = "start"; 30 | } 31 | }; 32 | 33 | Config *conf; 34 | AppArgs app_args; 35 | 36 | private: 37 | void parse_args(int argc, char **argv); 38 | void init(); 39 | 40 | int read_pid(); 41 | void write_pid(); 42 | void check_pidfile(); 43 | void remove_pidfile(); 44 | void kill_process(); 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/util/daemon.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef UTIL_DAEMON_H 7 | #define UTIL_DAEMON_H 8 | 9 | int daemonize(const char *dir=NULL){ 10 | switch(fork()){ 11 | case -1: 12 | return -1; 13 | case 0: 14 | break; 15 | default: 16 | exit(0); 17 | } 18 | if(setsid() == -1){ 19 | exit(0); 20 | } 21 | if(dir != NULL){ 22 | if(chdir(dir) == -1){ 23 | exit(0); 24 | } 25 | } 26 | 27 | if(close(STDIN_FILENO) == -1){ 28 | exit(0); 29 | } 30 | if(close(STDOUT_FILENO) == -1){ 31 | exit(0); 32 | } 33 | if(close(STDERR_FILENO) == -1){ 34 | exit(0); 35 | } 36 | 37 | int fd = open("/dev/null", O_RDWR, 0); 38 | if(fd == -1){ 39 | exit(0); 40 | } 41 | if(dup2(fd, STDIN_FILENO) == -1){ 42 | exit(0); 43 | } 44 | if(dup2(fd, STDOUT_FILENO) == -1){ 45 | exit(0); 46 | } 47 | if(dup2(fd, STDERR_FILENO) == -1){ 48 | exit(0); 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/util/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef UTIL_FILE_H_ 7 | #define UTIL_FILE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static inline 15 | bool file_exists(const std::string &filename){ 16 | struct stat st; 17 | return stat(filename.c_str(), &st) == 0; 18 | } 19 | 20 | static inline 21 | bool is_dir(const std::string &filename){ 22 | struct stat st; 23 | if(stat(filename.c_str(), &st) == -1){ 24 | return false; 25 | } 26 | return (bool)S_ISDIR(st.st_mode); 27 | } 28 | 29 | static inline 30 | bool is_file(const std::string &filename){ 31 | struct stat st; 32 | if(stat(filename.c_str(), &st) == -1){ 33 | return false; 34 | } 35 | return (bool)S_ISREG(st.st_mode); 36 | } 37 | 38 | // return number of bytes read 39 | static inline 40 | int file_get_contents(const std::string &filename, std::string *content){ 41 | char buf[8192]; 42 | FILE *fp = fopen(filename.c_str(), "rb"); 43 | if(!fp){ 44 | return -1; 45 | } 46 | int ret = 0; 47 | while(!feof(fp) && !ferror(fp)){ 48 | int n = fread(buf, 1, sizeof(buf), fp); 49 | if(n > 0){ 50 | ret += n; 51 | content->append(buf, n); 52 | } 53 | } 54 | fclose(fp); 55 | return ret; 56 | } 57 | 58 | // return number of bytes written 59 | static inline 60 | int file_put_contents(const std::string &filename, const std::string &content){ 61 | FILE *fp = fopen(filename.c_str(), "wb"); 62 | if(!fp){ 63 | return -1; 64 | } 65 | int ret = fwrite(content.data(), 1, content.size(), fp); 66 | fclose(fp); 67 | return ret == (int)content.size()? ret : -1; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/util/line.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_LINE_H 2 | #define UTIL_LINE_H 3 | 4 | #include 5 | #include 6 | #include "string_util.h" 7 | 8 | class LineEncoder{ 9 | public: 10 | int write(const std::string &data){ 11 | val.append(str_escape(data)); 12 | val.append("\n"); 13 | return 0; 14 | } 15 | 16 | int write(int data){ 17 | return this->write(::str(data)); 18 | } 19 | 20 | int write(int64_t data){ 21 | return this->write(::str(data)); 22 | } 23 | 24 | std::string str(){ 25 | return val; 26 | } 27 | private: 28 | std::string val; 29 | }; 30 | 31 | class LineDecoder{ 32 | public: 33 | LineDecoder(const std::string &s){ 34 | spos = 0; 35 | epos = 0; 36 | buf = s.data(); 37 | len = (int)s.size(); 38 | } 39 | 40 | int readline(std::string *ret){ 41 | return this->read(ret); 42 | } 43 | 44 | int read(std::string *ret){ 45 | while(epos < len && buf[epos] != '\n'){ 46 | epos ++; 47 | } 48 | if(epos >= len || buf[epos] != '\n'){ 49 | return -1; 50 | } 51 | std::string line(&buf[spos], epos - spos); 52 | spos = epos + 1; 53 | epos = spos; 54 | *ret = str_unescape(line); 55 | return (int)ret->size(); 56 | } 57 | 58 | int read(int *ret){ 59 | std::string line; 60 | if(this->read(&line) == -1){ 61 | return -1; 62 | } 63 | *ret = str_to_int(line); 64 | return 0; 65 | } 66 | 67 | int read(int64_t *ret){ 68 | std::string line; 69 | if(this->read(&line) == -1){ 70 | return -1; 71 | } 72 | *ret = str_to_int64(line); 73 | return 0; 74 | } 75 | 76 | public: 77 | const char *buf; 78 | int len; 79 | int spos; 80 | int epos; 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/util/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The icomet Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef UTIL_LIST_H 7 | #define UTIL_LIST_H 8 | 9 | template 10 | class LinkedList{ 11 | public: 12 | class Iterator{ 13 | private: 14 | T p; 15 | public: 16 | friend class LinkedList; 17 | 18 | T next(){ 19 | T ret = p; 20 | if(p){ 21 | p = p->next; 22 | } 23 | return ret; 24 | } 25 | }; 26 | friend class Iterator; 27 | public: 28 | int size; 29 | T head; 30 | T tail; 31 | 32 | LinkedList(){ 33 | size = 0; 34 | head = NULL; 35 | tail = NULL; 36 | } 37 | 38 | Iterator iterator(){ 39 | Iterator it; 40 | it.p = this->head; 41 | return it; 42 | } 43 | 44 | bool empty() const{ 45 | return size == 0; 46 | } 47 | 48 | void remove(T t){ 49 | this->size --; 50 | if(t->prev){ 51 | t->prev->next = t->next; 52 | } 53 | if(t->next){ 54 | t->next->prev = t->prev; 55 | } 56 | if(this->head == t){ 57 | this->head = t->next; 58 | } 59 | if(this->tail == t){ 60 | this->tail = t->prev; 61 | } 62 | } 63 | 64 | T pop_front(){ 65 | T t = this->head; 66 | this->remove(t); 67 | return t; 68 | } 69 | 70 | void push_back(T t){ 71 | this->size ++; 72 | t->prev = this->tail; 73 | t->next = NULL; 74 | if(this->tail){ 75 | this->tail->next = t; 76 | }else{ // both head and tail is empty 77 | this->head = t; 78 | } 79 | this->tail = t; 80 | } 81 | }; 82 | 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/util/sorted_set.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #ifndef UTIL_SORTED_SET_H 7 | #define UTIL_SORTED_SET_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class SortedSet 15 | { 16 | public: 17 | bool empty() const{ 18 | return size() == 0; 19 | } 20 | int size() const; 21 | int add(const std::string &key, int64_t score); 22 | // 0: not found, 1: found and deleted 23 | int del(const std::string &key); 24 | // the first item is copied into key if SortedSet not empty 25 | int front(std::string *key, int64_t *score=NULL) const; 26 | int back(std::string *key, int64_t *score=NULL) const; 27 | int64_t max_score() const; 28 | int pop_front(); 29 | int pop_back(); 30 | 31 | /* 32 | class Iterator 33 | { 34 | public: 35 | bool next(); 36 | const std::string& key(); 37 | int64_t score(); 38 | }; 39 | 40 | Iterator begin(); 41 | */ 42 | 43 | private: 44 | struct Item 45 | { 46 | std::string key; 47 | int64_t score; 48 | 49 | bool operator<(const Item& b) const{ 50 | return this->score < b.score 51 | || (this->score == b.score && this->key < b.key); 52 | } 53 | }; 54 | 55 | std::map::iterator> existed; 56 | std::set sorted_set; 57 | }; 58 | 59 | 60 | /* 61 | TODO: HashedWheel 62 | Each item is linked in two list, one is slot list, the other 63 | one is total list. 64 | */ 65 | /* 66 | template 67 | class SortedList 68 | { 69 | public: 70 | void add(const T data, int64_t score); 71 | T front(); 72 | void pop_front(); 73 | 74 | class Item 75 | { 76 | public: 77 | int64_t score; 78 | Item *prev; 79 | Item *next; 80 | //Item *slot_prev; 81 | //Item *slot_next; 82 | T data; 83 | }; 84 | }; 85 | */ 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /src/util/test_sorted_set.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "log.h" 11 | #include "sorted_set.h" 12 | #include "bytes.h" 13 | 14 | int main(int argc, char **argv){ 15 | SortedSet zset; 16 | 17 | std::vector keys; 18 | for(int i='a'; i<='z'; i++){ 19 | char buf[10]; 20 | snprintf(buf, sizeof(buf), "%c", i); 21 | keys.push_back(buf); 22 | } 23 | 24 | log_debug(""); 25 | srand(time(NULL)); 26 | for(int i=0; i<1000 * 1000; i++){ 27 | std::string &key = keys[rand() % keys.size()]; 28 | zset.add(key, rand()%30 - 15); 29 | } 30 | log_debug(""); 31 | 32 | std::string key; 33 | int64_t score; 34 | int n = 0; 35 | while(zset.front(&key, &score)){ 36 | printf("%s : %4lld\n", key.c_str(), score); 37 | zset.pop_front(); 38 | n ++; 39 | } 40 | log_debug("%d", n); 41 | 42 | { 43 | Buffer bs(8192); 44 | bs.append_record("a"); 45 | bs.append_record("bs"); 46 | dump(bs.data(), bs.size()); 47 | 48 | Bytes s; 49 | bs.read_record(&s); 50 | dump(s.data(), s.size()); 51 | bs.read_record(&s); 52 | dump(s.data(), s.size()); 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /src/util/test_thread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2014 The SSDB Authors. All rights reserved. 3 | Use of this source code is governed by a BSD-style license that can be 4 | found in the LICENSE file. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "log.h" 11 | #include "thread.h" 12 | 13 | // g++ log.o a.cpp 14 | 15 | class MyWorker : public WorkerPool::Worker{ 16 | public: 17 | MyWorker(const std::string &name){ 18 | } 19 | 20 | int proc(int *job){ 21 | usleep(200 * 1000); 22 | *job = 100000 + *job; 23 | return 0; 24 | } 25 | }; 26 | 27 | #define NUM_JOBS 10 28 | 29 | int main(){ 30 | int jobs[NUM_JOBS]; 31 | WorkerPool tp("test"); 32 | tp.start(3); 33 | 34 | log_debug("add begin"); 35 | for(int i=0; i 8 | #include 9 | #endif 10 | -------------------------------------------------------------------------------- /ssdb.conf: -------------------------------------------------------------------------------- 1 | # ssdb-server config 2 | # MUST indent by TAB! 3 | 4 | # absolute path, or relative to path of this file, directory must exists 5 | work_dir = ./var 6 | pidfile = ./var/ssdb.pid 7 | 8 | server: 9 | # specify an ipv6 address to enable ipv6 support 10 | # ip: ::1 11 | ip: 127.0.0.1 12 | port: 8888 13 | # bind to public ip 14 | #ip: 0.0.0.0 15 | # format: allow|deny: all|ip_prefix 16 | # multiple allows or denys is supported 17 | #deny: all 18 | #allow: 127.0.0.1 19 | #allow: 192.168 20 | # auth password must be at least 32 characters 21 | #auth: very-strong-password 22 | #readonly: yes 23 | # in ms, to log slowlog with WARN level 24 | #slowlog_timeout: 5 25 | 26 | replication: 27 | binlog: yes 28 | # Limit sync speed to *MB/s, -1: no limit 29 | sync_speed: -1 30 | slaveof: 31 | # to identify a master even if it moved(ip, port changed) 32 | # if set to empty or not defined, ip:port will be used. 33 | #id: svc_2 34 | # sync|mirror, default is sync 35 | #type: sync 36 | #host: localhost 37 | #port: 8889 38 | 39 | logger: 40 | level: debug 41 | output: log.txt 42 | rotate: 43 | size: 1000000000 44 | 45 | leveldb: 46 | # in MB 47 | cache_size: 500 48 | # in MB 49 | write_buffer_size: 64 50 | # in MB/s 51 | compaction_speed: 1000 52 | # yes|no 53 | compression: yes 54 | 55 | 56 | -------------------------------------------------------------------------------- /ssdb_slave.conf: -------------------------------------------------------------------------------- 1 | # ssdb-server config for slave 2 | # MUST indent by TAB! 3 | 4 | # relative to path of this file, directory must exists 5 | work_dir = ./var_slave 6 | pidfile = ./var_slave/ssdb.pid 7 | 8 | server: 9 | ip: 127.0.0.1 10 | port: 8889 11 | #readonly: yes 12 | 13 | replication: 14 | binlog: yes 15 | # Limit sync speed to *MB/s, -1: no limit 16 | sync_speed: -1 17 | slaveof: 18 | # to identify a master even if it moved(ip, port changed) 19 | # if set to empty or not defined, "ip|port" will be used (e.g. "10.0.0.1|8888"). 20 | id: svc_1 21 | # sync|mirror, default is sync 22 | type: sync 23 | host: localhost 24 | port: 8888 25 | #auth: password 26 | 27 | logger: 28 | level: debug 29 | output: log_slave.txt 30 | rotate: 31 | size: 1000000000 32 | 33 | leveldb: 34 | # in MB 35 | cache_size: 500 36 | # in MB 37 | write_buffer_size: 64 38 | # in MB/s 39 | compaction_speed: 1000 40 | # yes|no 41 | compression: yes 42 | 43 | 44 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | include ../build_config.mk 2 | 3 | OBJS += ../src/net/link.o ../src/net/link_addr.o ../src/net/fde.o \ 4 | ../src/util/log.o ../src/util/bytes.o 5 | CFLAGS += -I../src 6 | EXES = ssdb-bench ssdb-dump ssdb-repair leveldb-import 7 | 8 | all: ssdb-bench.o ssdb-dump.o ssdb-repair.o leveldb-import.o ssdb-migrate.o 9 | ${CXX} -o ssdb-bench ssdb-bench.o ${OBJS} ${UTIL_OBJS} ${CLIBS} 10 | ${CXX} -o ssdb-dump ssdb-dump.o ${OBJS} ${UTIL_OBJS} ${CLIBS} 11 | ${CXX} -o ssdb-repair ssdb-repair.o ${OBJS} ${UTIL_OBJS} ${CLIBS} 12 | ${CXX} -o leveldb-import leveldb-import.o ${OBJS} ${UTIL_OBJS} ${CLIBS} 13 | ${CXX} -o ssdb-migrate ssdb-migrate.o ../api/cpp/libssdb-client.a ../src/util/libutil.a 14 | 15 | ssdb-migrate.o: ssdb-migrate.cpp 16 | ${CXX} ${CFLAGS} -I../api/cpp -c ssdb-migrate.cpp 17 | ssdb-bench.o: ssdb-bench.cpp 18 | ${CXX} ${CFLAGS} -c ssdb-bench.cpp 19 | ssdb-dump.o: ssdb-dump.cpp 20 | ${CXX} ${CFLAGS} -c ssdb-dump.cpp 21 | ssdb-repair.o: ssdb-repair.cpp 22 | ${CXX} ${CFLAGS} -c ssdb-repair.cpp 23 | leveldb-import.o: leveldb-import.cpp 24 | ${CXX} ${CFLAGS} -c leveldb-import.cpp 25 | 26 | clean: 27 | rm -f *.exe *.exe.stackdump *.o ${EXES} 28 | rm -rf _cpy_ 29 | 30 | -------------------------------------------------------------------------------- /tools/ssdb-cli: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | DIR=`S=\`readlink "$0"\`; [ -z "$S" ] && S=$0; dirname $S` 3 | 4 | if [ -e $DIR/../deps/cpy/cpy ]; then 5 | CPY=$DIR/../deps/cpy/cpy 6 | else 7 | CPY=$DIR/deps/cpy/cpy 8 | fi 9 | 10 | $CPY $DIR/ssdb-cli.cpy $@ 11 | -------------------------------------------------------------------------------- /tools/ssdb-cli.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | %~dp0..\deps\cpy\cpy.bat %~dp0\ssdb-cli.cpy %1 %2 %3 %4 %5 %6 %7 %8 %9 3 | -------------------------------------------------------------------------------- /tools/ssdb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # chkconfig: 2345 64 36 4 | # description: SSDB startup scripts 5 | # 6 | ssdb_root=/usr/local/ssdb 7 | ssdb_bin=$ssdb_root/ssdb-server 8 | # each config file for one instance 9 | # configs="/data/ssdb_data/test/ssdb.conf /data/ssdb_data/test2/ssdb.conf" 10 | configs="/data/ssdb_data/test/ssdb.conf" 11 | 12 | 13 | if [ -f /etc/rc.d/init.d/functions ]; then 14 | . /etc/rc.d/init.d/functions 15 | fi 16 | 17 | start() { 18 | for conf in $configs; do 19 | $ssdb_bin $conf -s restart -d 20 | done 21 | } 22 | 23 | stop() { 24 | for conf in $configs; do 25 | $ssdb_bin $conf -s stop -d 26 | done 27 | } 28 | 29 | # See how we were called. 30 | case "$1" in 31 | start) 32 | start 33 | ;; 34 | stop) 35 | stop 36 | ;; 37 | restart) 38 | stop 39 | start 40 | ;; 41 | *) 42 | echo $"Usage: $0 {start|stop|restart}" 43 | ;; 44 | esac 45 | exit $RETVAL 46 | -------------------------------------------------------------------------------- /tools/ssdb_cli/cluster.cpy: -------------------------------------------------------------------------------- 1 | import util.*; 2 | 3 | function kv_node_list(resp, time_consume){ 4 | len_index = 0; 5 | count = 0; 6 | while(len(resp.data) > len_index){ 7 | kv_len = int(resp.data[len_index]); 8 | if(kv_len < 6){ 9 | printf('bad response!\n'); 10 | break; 11 | } 12 | if(len(resp.data) >= len_index + kv_len){ 13 | count += 1; 14 | id = resp.data[len_index + 1]; 15 | status = resp.data[len_index + 2]; 16 | range_s = resp.data[len_index + 3]; 17 | range_e = resp.data[len_index + 4]; 18 | ip = resp.data[len_index + 5]; 19 | port = resp.data[len_index + 6]; 20 | 21 | status_text = 'UNKNOWN'; 22 | if(status == '0'){ 23 | status_text = 'INIT'; 24 | }else if(status == '1'){ 25 | status_text = 'SERVING'; 26 | } 27 | 28 | printf('id: %s\n', id); 29 | printf(' status: %s\n', status_text); 30 | printf(' range: (\"%s\", \"%s\"]\n', range_s.encode('string-escape'), range_e.encode('string-escape')); 31 | printf(' ip: %s\n', ip); 32 | printf(' port: %s\n', port); 33 | } 34 | len_index += 6 + 1; 35 | } 36 | sys.stderr.write(sprintf('%d result(s) (%.3f sec)\n', count, time_consume)); 37 | } 38 | -------------------------------------------------------------------------------- /tools/ssdb_cli/importer.cpy: -------------------------------------------------------------------------------- 1 | function run(link, filename){ 2 | if(!os.path.exists(filename)){ 3 | print 'Error: ' + filename + ' not exists!'; 4 | return; 5 | } 6 | total_size = os.path.getsize(filename); 7 | if(total_size == 0){ 8 | total_size = 1; 9 | } 10 | 11 | progress = 0; 12 | read_size = 0; 13 | fp = open(filename, 'r'); 14 | lineno = 0; 15 | foreach(fp as line){ 16 | lineno ++; 17 | read_size += len(line); 18 | progress_2 = int(float(read_size)/total_size * 100); 19 | if(progress_2 - progress >= 5 || read_size == total_size){ 20 | progress = progress_2; 21 | printf("%2d%%\n", progress_2); 22 | } 23 | 24 | ps = line.strip('\n').split('\t'); 25 | if(len(ps) < 2){ 26 | print 'Error: bad format at line ' + str(lineno) + ', abort!'; 27 | return; 28 | } 29 | cmd = ps[0].lower(); 30 | foreach(ps as k=>v){ 31 | ps[k] = str(v).decode('string-escape'); 32 | } 33 | 34 | link.request(cmd, ps[ 1 ..]); 35 | } 36 | print 'done.'; 37 | } 38 | -------------------------------------------------------------------------------- /tools/test_slow_client.php: -------------------------------------------------------------------------------- 1 |