├── src ├── Application │ ├── Fuse │ │ ├── kdbfs.h │ │ ├── kdbfs_main.c │ │ ├── Channel.h │ │ ├── HttpClient.h │ │ ├── HttpClient.cpp │ │ └── Channel.cpp │ ├── Keyspace │ │ ├── Client │ │ │ ├── Java │ │ │ │ ├── KeyspaceException.java │ │ │ │ ├── SWIGTYPE_p_void.java │ │ │ │ ├── SWIGTYPE_p_p_char.java │ │ │ │ ├── ListParams.java │ │ │ │ ├── Test.java │ │ │ │ ├── Status.java │ │ │ │ ├── Result.java │ │ │ │ └── imaxdiv_t.java │ │ │ ├── Ruby │ │ │ │ └── test.rb │ │ │ ├── keyspace_client.i │ │ │ ├── CSharp │ │ │ │ ├── stdint.h │ │ │ │ ├── inttypes.h │ │ │ │ ├── SWIGTYPE_p_void.cs │ │ │ │ ├── SWIGTYPE_p_p_char.cs │ │ │ │ ├── KeyspaceClientTest │ │ │ │ │ ├── Program.cs │ │ │ │ │ └── Properties │ │ │ │ │ │ └── AssemblyInfo.cs │ │ │ │ ├── KeyspaceClient │ │ │ │ │ ├── ListParam.cs │ │ │ │ │ ├── Properties │ │ │ │ │ │ └── AssemblyInfo.cs │ │ │ │ │ ├── Status.cs │ │ │ │ │ └── Result.cs │ │ │ │ ├── KeyspaceClient.sln │ │ │ │ └── imaxdiv_t.cs │ │ │ ├── KeyspaceClientConsts.h │ │ │ ├── Perl │ │ │ │ └── test.pl │ │ │ ├── PHP │ │ │ │ └── test.php │ │ │ ├── KeyspaceCommand.h │ │ │ ├── KeyspaceResponse.h │ │ │ ├── KeyspaceCommand.cpp │ │ │ ├── KeyspaceResult.h │ │ │ └── KeyspaceClientConn.h │ │ ├── Protocol │ │ │ ├── ProtocolServer.h │ │ │ ├── Memcache │ │ │ │ ├── MemcacheServer.cpp │ │ │ │ ├── MemcacheServer.h │ │ │ │ └── MemcacheConn.h │ │ │ ├── HTTP │ │ │ │ ├── HttpKeyspaceHandler.cpp │ │ │ │ ├── HttpKeyspaceHandler.h │ │ │ │ └── HttpApiHandler.h │ │ │ └── Keyspace │ │ │ │ ├── KeyspaceClientResp.h │ │ │ │ ├── KeyspaceServer.h │ │ │ │ ├── KeyspaceConn.h │ │ │ │ ├── KeyspaceClientReq.h │ │ │ │ ├── KeyspaceServer.cpp │ │ │ │ └── KeyspaceClientResp.cpp │ │ ├── Database │ │ │ ├── KeyspaceConsts.h │ │ │ ├── SyncListVisitor.h │ │ │ ├── KeyspaceMsg.h │ │ │ ├── SingleKeyspaceDB.h │ │ │ └── AsyncListVisitor.h │ │ └── Catchup │ │ │ ├── CatchupServer.h │ │ │ ├── CatchupServer.cpp │ │ │ ├── CatchupMsg.h │ │ │ ├── CatchupWriter.h │ │ │ ├── CatchupReader.h │ │ │ └── CatchupMsg.cpp │ ├── HTTP │ │ ├── Mime.h │ │ ├── HttpFileHandler.h │ │ ├── HttpRequest.h │ │ ├── JSONSession.h │ │ ├── HttpServer.h │ │ ├── HttpServer.cpp │ │ ├── HttpConn.h │ │ ├── UrlParam.h │ │ ├── HttpRequest.cpp │ │ ├── IMF.h │ │ ├── JSONSession.cpp │ │ └── HttpFileHandler.cpp │ ├── HubSim │ │ ├── Main.cpp │ │ └── HubSim.h │ ├── EchoServer │ │ ├── TCPEchoServer.h │ │ ├── UDPEchoServer.h │ │ ├── TCPEchoConn.h │ │ ├── TCPEchoServer.cpp │ │ ├── UDPEchoServer.cpp │ │ └── TCPEchoConn.cpp │ └── Console │ │ └── Console.h ├── Test │ ├── Tester.cpp │ ├── Test.agazso.cpp │ ├── OpenDirect.cpp │ ├── ThreadPoolTest.cpp │ ├── UDPTestClient.c │ ├── AsyncDBTest.cpp │ ├── UDPEchoClient.c │ ├── PaxosTester.c │ ├── QueueTest.cpp │ ├── TimeCheckTest.cpp │ ├── Test.h │ └── IOTest.cpp ├── System │ ├── Time.h │ ├── Time_Posix.cpp │ ├── Stopwatch.h │ ├── Events │ │ ├── Scheduler.h │ │ ├── EventLoop.h │ │ ├── Scheduler.cpp │ │ ├── EventLoop.cpp │ │ ├── Callable.h │ │ └── Timer.h │ ├── IO │ │ ├── IOProcessor.h │ │ ├── FD.h │ │ ├── Endpoint.h │ │ └── Socket.h │ ├── Config.h │ ├── ThreadPool.h │ ├── Containers │ │ ├── Queue.h │ │ └── SortedList.h │ ├── Time_Windows.cpp │ ├── Log.h │ ├── Platform.cpp │ ├── Common.h │ └── Platform.h ├── Framework │ ├── Paxos │ │ ├── PaxosConsts.h │ │ ├── PaxosLearner.h │ │ ├── PaxosAcceptor.h │ │ ├── PaxosState.h │ │ └── PaxosProposer.h │ ├── Transport │ │ ├── Transport.h │ │ ├── TransportUDPWriter.h │ │ ├── TransportTCPWriter.h │ │ ├── TransportUDPWriter.cpp │ │ ├── TCPServer.cpp │ │ ├── TransportUDPReader.h │ │ ├── TransportTCPReader.h │ │ ├── TransportUDPReader.cpp │ │ └── TransportTCPWriter.cpp │ ├── PaxosLease │ │ ├── PLeaseConsts.h │ │ ├── PLeaseAcceptor.h │ │ ├── PLeaseLearner.h │ │ ├── PLeaseProposer.h │ │ ├── PaxosLease.h │ │ ├── PLeaseState.h │ │ └── PLeaseMsg.h │ ├── ReplicatedLog │ │ ├── LogQueue.h │ │ ├── ReplicatedLogMsg.h │ │ ├── LogCache.h │ │ ├── ReplicatedDB.h │ │ ├── ReplicatedLogMsg.cpp │ │ ├── ReplicatedConfig.h │ │ └── LogQueue.cpp │ ├── Database │ │ ├── Cursor.h │ │ ├── Transaction.h │ │ ├── Database.h │ │ ├── Transaction.cpp │ │ ├── DatabaseConfig.h │ │ ├── Table.h │ │ └── Cursor.cpp │ └── AsyncDatabase │ │ ├── AsyncDatabase.h │ │ ├── AsyncDatabase.cpp │ │ └── MultiDatabaseOp.h └── Version.h ├── keyspace-config ├── script ├── DEBIAN │ ├── conffiles │ └── postinst ├── fixnewline.sh ├── genmakeobjs ├── safe_keyspaced.cmd ├── genmakedirs ├── debian-distributions ├── default ├── fix_swig_php.sh ├── keyspace-console ├── safe_keyspaced ├── fixnewline.py ├── version.sh ├── mkcontrol.sh └── keyspace ├── test ├── 0 │ └── keyspace.conf ├── 1 │ └── keyspace.conf ├── 2 │ └── keyspace.conf ├── clear ├── awsinit.sh ├── client.conf ├── concurrency │ ├── concurrency_set.py │ ├── concurrency_list.py │ ├── concurrency_get.py │ ├── concurrency_remove.py │ └── common.py ├── awsconf.sh ├── run ├── single │ └── keyspace.conf └── aws.sh ├── doc ├── FSFConf │ ├── FSFConf.dvi │ ├── FSFConf.pdf │ ├── FSFConf.tex │ ├── perf_ops1.eps │ ├── trencseni_elosztott2.zip │ └── FSFConf.aux ├── Keyspace │ ├── Keyspace.pdf │ ├── perf_mbs1.eps │ └── perf_ops1.eps ├── PaxosLease │ ├── PaxosLease.pdf │ └── PaxosLease.tex └── Sphinx │ └── source │ ├── keyspace │ ├── page.html │ ├── static │ │ ├── file.png │ │ ├── minus.png │ │ └── plus.png │ ├── theme.conf │ ├── changes │ │ ├── frameset.html │ │ ├── rstsource.html │ │ └── versionchanges.html │ ├── opensearch.xml │ ├── genindex-split.html │ ├── defindex.html │ ├── genindex-single.html │ ├── search.html │ ├── modindex.html │ └── genindex.html │ ├── about.rst │ └── index.rst ├── Makefile.Linux ├── Makefile.clientlib ├── README ├── Makefile.Darwin ├── Makefile.dirs ├── client └── LICENSE └── CHANGELOG /src/Application/Fuse/kdbfs.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /keyspace-config: -------------------------------------------------------------------------------- 1 | python keyspace-config.py 2 | -------------------------------------------------------------------------------- /script/DEBIAN/conffiles: -------------------------------------------------------------------------------- 1 | /etc/keyspace.conf 2 | -------------------------------------------------------------------------------- /test/clear: -------------------------------------------------------------------------------- 1 | rm test/$1/log* 2 | rm test/$1/keyspace 3 | -------------------------------------------------------------------------------- /doc/FSFConf/FSFConf.dvi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/FSFConf/FSFConf.dvi -------------------------------------------------------------------------------- /doc/FSFConf/FSFConf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/FSFConf/FSFConf.pdf -------------------------------------------------------------------------------- /doc/FSFConf/FSFConf.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/FSFConf/FSFConf.tex -------------------------------------------------------------------------------- /src/Test/Tester.cpp: -------------------------------------------------------------------------------- 1 | #include "Test.h" 2 | 3 | int bdbtest(); 4 | 5 | TEST_MAIN(bdbtest); 6 | -------------------------------------------------------------------------------- /test/awsinit.sh: -------------------------------------------------------------------------------- 1 | wget http://svn.scalien.com/keyspace/trunk/test/aws.sh; chmod +x aws.sh; . aws.sh -------------------------------------------------------------------------------- /doc/FSFConf/perf_ops1.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/FSFConf/perf_ops1.eps -------------------------------------------------------------------------------- /doc/Keyspace/Keyspace.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Keyspace/Keyspace.pdf -------------------------------------------------------------------------------- /doc/Keyspace/perf_mbs1.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Keyspace/perf_mbs1.eps -------------------------------------------------------------------------------- /doc/Keyspace/perf_ops1.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Keyspace/perf_ops1.eps -------------------------------------------------------------------------------- /doc/PaxosLease/PaxosLease.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/PaxosLease/PaxosLease.pdf -------------------------------------------------------------------------------- /doc/PaxosLease/PaxosLease.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/PaxosLease/PaxosLease.tex -------------------------------------------------------------------------------- /script/fixnewline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find . \( -name "*.cpp" -name "*.c" -or -name "*.h" \) -exec fixnewline.py {} + -------------------------------------------------------------------------------- /doc/FSFConf/trencseni_elosztott2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/FSFConf/trencseni_elosztott2.zip -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ body }} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Sphinx/source/keyspace/static/file.png -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Sphinx/source/keyspace/static/minus.png -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalien/keyspace/HEAD/doc/Sphinx/source/keyspace/static/plus.png -------------------------------------------------------------------------------- /script/genmakeobjs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "ALL_OBJECTS = \\" 4 | find ./src -name "*.cpp" | sed -e "s/^\.\/src\/\(.*\).cpp\$/\t\$(BUILD_DIR)\/\1.o \\\/" 5 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = none 3 | stylesheet = basic.css 4 | pygments_style = sphinx 5 | 6 | [options] 7 | nosidebar = false 8 | -------------------------------------------------------------------------------- /script/safe_keyspaced.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | :start 3 | %1 %2 4 | if %ERRORLEVEL% == 0 goto end 5 | if %ERRORLEVEL% == 1 goto end 6 | if %ERRORLEVEL% == 143 goto end 7 | goto start 8 | :end 9 | -------------------------------------------------------------------------------- /script/genmakedirs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo '$(BUILD_DIR):' 4 | echo ' -mkdir -p $(BUILD_DIR) \' 5 | find ./src -mindepth 2 -name '.svn' | sed -e "s/^\.\/src\/\(.*\).svn\$/\t\t\$(BUILD_DIR)\/\1 \\\/" -------------------------------------------------------------------------------- /src/System/Time.h: -------------------------------------------------------------------------------- 1 | #ifndef TIME_H 2 | #define TIME_H 3 | 4 | #include "Platform.h" 5 | 6 | uint64_t Now(); 7 | uint64_t NowMicro(); 8 | void MSleep(unsigned long msec); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/KeyspaceException.java: -------------------------------------------------------------------------------- 1 | package com.scalien.keyspace; 2 | 3 | public class KeyspaceException extends java.lang.Exception { 4 | public KeyspaceException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Framework/Paxos/PaxosConsts.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOS_CONSTS 2 | #define PAXOS_CONSTS 3 | 4 | #define PAXOS_SIZE (500*KB) 5 | #define RLOG_SIZE (PAXOS_SIZE + 10*KB) 6 | 7 | #define REQUEST_CHOSEN_TIMEOUT 7000 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /script/debian-distributions: -------------------------------------------------------------------------------- 1 | Origin: Scalien Software 2 | Label: Scalien Software 3 | Suite: stable 4 | Codename: etch 5 | Version: 4.0 6 | Architectures: i386 7 | Components: main non-free contrib 8 | Description: Repository for Scalien Keyspace DB 9 | -------------------------------------------------------------------------------- /src/Framework/Transport/Transport.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPORT_H 2 | #define TRANSPORT_H 3 | 4 | #include "System/Common.h" 5 | 6 | #define MAX_TCP_MESSAGE_SIZE (1*MB + 10*KB) 7 | 8 | #define MAX_UDP_MESSAGE_SIZE (64*KB + 1*KB) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /script/default: -------------------------------------------------------------------------------- 1 | DEFAULT_CONFIG=/etc/keyspace.conf 2 | NAME=keyspaced 3 | BIN_DIR=/usr/bin 4 | DAEMON=$BIN_DIR/$NAME 5 | SAFE_DAEMON=$BIN_DIR/safe_$NAME 6 | START_KEYSPACE=NO 7 | DATABASE_DIR=/var/lib/keyspace 8 | KEYSPACE_LOG=/var/log/keyspace.log 9 | KEYSPACE_USER=daemon -------------------------------------------------------------------------------- /script/fix_swig_php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$1 4 | 5 | mv $DIR/keyspace_client.php $DIR/keyspace_client_swig.php 6 | cat $DIR/keyspace_client_swig.php | sed 's/(function_exists($func) /(function_exists($func)) /' > $DIR/keyspace_client.php 7 | rm $DIR/keyspace_client_swig.php 8 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseConsts.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASECONSTS_H 2 | #define PLEASECONSTS_H 3 | 4 | #include "System/Common.h" 5 | 6 | #define ACQUIRELEASE_TIMEOUT 2000 // msec 7 | #define MAX_LEASE_TIME 7000 // msec 8 | #define PLEASE_PORT_OFFSET 1 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/ProtocolServer.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTOCOLSERVER_H 2 | #define PROTOCOLSERVER_H 3 | 4 | class ProtocolServer 5 | { 6 | public: 7 | virtual ~ProtocolServer() {} 8 | 9 | // virtual void Stop() = 0; 10 | // virtual void Continue() = 0; 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/Version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | #define VERSION_MAJOR "1" 5 | #define VERSION_MINOR "9" 6 | #define VERSION_RELEASE "0" 7 | #define VERSION_STRING VERSION_MAJOR "." VERSION_MINOR "." VERSION_RELEASE 8 | 9 | #define VERSION_RANDOM "0" 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/client.conf: -------------------------------------------------------------------------------- 1 | keyspace.endpoints = 127.0.0.1:7080, 127.0.0.1:7081, 127.0.0.1:7082 2 | #keyspace.endpoints = 127.0.0.1:7080 3 | keyspace.timeout = 14000 4 | dataset.total = 10M 5 | 6 | log.trace = false 7 | log.targets = stderr, file 8 | log.truncate = true 9 | log.file = test/client.log 10 | -------------------------------------------------------------------------------- /script/keyspace-console: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PORT=22222 4 | if [ "$3" != "" ]; then 5 | PORT=$3 6 | fi 7 | 8 | SERVER_CONSOLE=localhost 9 | if [ "$2" != "" ]; then 10 | SERVER_CONSOLE=$2 11 | fi 12 | 13 | echo_sleep() { 14 | echo $1 15 | sleep $2 16 | } 17 | 18 | echo_sleep "$1" 1 | telnet $SERVER_CONSOLE $PORT 19 | -------------------------------------------------------------------------------- /src/System/Time_Posix.cpp: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_WINDOWS 2 | 3 | #include "Time.h" 4 | 5 | uint64_t Now() 6 | { 7 | return GetMilliTimestamp(); 8 | } 9 | 10 | uint64_t NowMicro() 11 | { 12 | return GetMicroTimestamp(); 13 | } 14 | 15 | void MSleep(unsigned long msec) 16 | { 17 | usleep(msec * 1000); 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /script/safe_keyspaced: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | safe_keyspace() 4 | { 5 | while (:); do 6 | $1 $2 2>&1 >> /dev/null 7 | EXITSTATUS=$? 8 | if [ "$EXITSTATUS" = "0" -o "$EXITSTATUS" = "1" -o "$EXITSTATUS" = "143" -o "$EXITSTATUS" = "127" ]; then 9 | exit 0 10 | fi 11 | done 12 | } 13 | 14 | safe_keyspace $1 $2 $3 2>&1 >> /dev/null & 15 | -------------------------------------------------------------------------------- /script/fixnewline.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | if len(sys.argv[1:]) == 0: 6 | sys.exit(1) 7 | 8 | for arg in sys.argv[1:]: 9 | f = open(arg, 'r') 10 | f.seek(-1, 2) 11 | c = f.read(1) 12 | if c != '\n' and c != '\r': 13 | f.close() 14 | print(arg) 15 | f = open(arg, 'a') 16 | f.write('\n') 17 | 18 | f.close() 19 | -------------------------------------------------------------------------------- /src/Application/Fuse/kdbfs_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern struct fuse_operations kdbfs_oper; 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | int ret; 9 | 10 | umask(0); 11 | 12 | if (argc > 1) { 13 | ret = mkdir(argv[1], 0777); 14 | } 15 | 16 | return fuse_main(argc, argv, &kdbfs_oper, NULL); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/Application/HTTP/Mime.h: -------------------------------------------------------------------------------- 1 | #ifndef MIME_H 2 | #define MIME_H 3 | 4 | #define MIME_TYPE_TEXT_PLAIN "text/plain" 5 | #define MIME_TYPE_TEXT_HTML "text/html" 6 | #define MIME_TYPE_APPLICATION_OCTET_STREAM "application/octet-stream" 7 | 8 | const char* MimeTypeFromExtension(const char* ext, const char* defaultType = MIME_TYPE_APPLICATION_OCTET_STREAM); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Memcache/MemcacheServer.cpp: -------------------------------------------------------------------------------- 1 | #include "MemcacheServer.h" 2 | 3 | void MemcacheServer::Init(KeyspaceDB* kdb_) 4 | { 5 | if (!TCPServerT::Init(MEMCACHE_PORT, 10)) 6 | ASSERT_FAIL(); 7 | kdb = kdb_; 8 | } 9 | 10 | void MemcacheServer::InitConn(MemcacheConn* conn) 11 | { 12 | conn->Init(this, kdb); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/0/keyspace.conf: -------------------------------------------------------------------------------- 1 | mode = replicated 2 | 3 | paxos.nodeID = 0 4 | 5 | paxos.endpoints = 127.0.0.1:10000, 127.0.0.1:10010, 127.0.0.1:10020 6 | 7 | database.dir = test/0 8 | 9 | http.port = 8080 10 | keyspace.port = 7080 11 | 12 | log.trace = false 13 | log.targets = stdout, file 14 | log.file = test/0/keyspace.log 15 | log.timestamping = true 16 | log.truncate = true 17 | -------------------------------------------------------------------------------- /test/1/keyspace.conf: -------------------------------------------------------------------------------- 1 | mode = replicated 2 | 3 | paxos.nodeID = 1 4 | 5 | paxos.endpoints = 127.0.0.1:10000, 127.0.0.1:10010, 127.0.0.1:10020 6 | 7 | database.dir = test/1 8 | 9 | http.port = 8081 10 | keyspace.port = 7081 11 | 12 | log.trace = false 13 | log.targets = stdout, file 14 | log.file = test/1/keyspace.log 15 | log.timestamping = true 16 | log.truncate = true 17 | -------------------------------------------------------------------------------- /test/2/keyspace.conf: -------------------------------------------------------------------------------- 1 | mode = replicated 2 | 3 | paxos.nodeID = 2 4 | 5 | paxos.endpoints = 127.0.0.1:10000, 127.0.0.1:10010, 127.0.0.1:10020 6 | 7 | database.dir = test/2 8 | 9 | http.port = 8082 10 | keyspace.port = 7082 11 | 12 | log.trace = false 13 | log.targets = stdout, file 14 | log.file = test/2/keyspace.log 15 | log.timestamping = true 16 | log.truncate = true 17 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Ruby/test.rb: -------------------------------------------------------------------------------- 1 | require 'keyspace' 2 | 3 | ks = KeyspaceClient.new(["localhost:7080"]) 4 | ks.get("hol") 5 | print(ks.result.value) 6 | print(ks.count() + "\n") 7 | 8 | keys = ks.list_keys() 9 | keys.each do |key| 10 | print(key + "\n") 11 | end 12 | 13 | kv = ks.list_key_values() 14 | kv.each_pair do |k, v| 15 | print(k + " => " + v + "\n") 16 | end 17 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/keyspace_client.i: -------------------------------------------------------------------------------- 1 | %module keyspace_client 2 | %include "stl.i" 3 | %include "inttypes.i" 4 | %include "stdint.i" 5 | 6 | %{ 7 | /* Includes the header in the wrapper code */ 8 | #define SWIG_FILE_WITH_INIT 9 | #include "../KeyspaceClientWrap.h" 10 | %} 11 | 12 | /* Parse the header file to generate wrappers */ 13 | %include "../KeyspaceClientWrap.h" 14 | -------------------------------------------------------------------------------- /src/System/Stopwatch.h: -------------------------------------------------------------------------------- 1 | #ifndef STOPWATCH_H 2 | #define STOPWATCH_H 3 | 4 | #include "Time.h" 5 | 6 | class Stopwatch 7 | { 8 | public: 9 | long elapsed; 10 | 11 | Stopwatch () { Reset(); } 12 | 13 | void Reset() { elapsed = 0; } 14 | void Start() { started = Now(); } 15 | void Stop() { elapsed += Now() - started; } 16 | 17 | private: 18 | long started; 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/System/Events/Scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEDULER_H 2 | #define SCHEDULER_H 3 | 4 | #include "System/Containers/SortedList.h" 5 | #include "Timer.h" 6 | 7 | class Scheduler 8 | { 9 | public: 10 | static void Add(Timer* timer); 11 | static void Remove(Timer* timer); 12 | static void Reset(Timer* timer); 13 | static void Shutdown(); 14 | 15 | protected: 16 | static SortedList timers; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /script/version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | VERSION= 4 | if [ $1 -gt 0 ]; then 5 | VERSION=`sed -n 's/.*VERSION_MAJOR[[:space:]]*\"\([[:digit:]]*\)\"/\1/p' $2` 6 | fi 7 | if [ $1 -gt 1 ]; then 8 | VERSION=$VERSION.`sed -n 's/.*VERSION_MINOR[[:space:]]*\"\([[:digit:]]*\)\"/\1/p' $2` 9 | fi 10 | if [ $1 -gt 2 ]; then 11 | VERSION=$VERSION.`sed -n 's/.*VERSION_RELEASE[[:space:]]*\"\([[:digit:]]*\)\"/\1/p' $2` 12 | fi 13 | 14 | echo $VERSION 15 | 16 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/LogQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGQUEUE_H 2 | #define LOGQUEUE_H 3 | 4 | #include "System/Buffer.h" 5 | #include "System/Containers/List.h" 6 | 7 | class LogQueue 8 | { 9 | public: 10 | ~LogQueue(); 11 | 12 | bool Push(ByteString& value); 13 | ByteString* Next(); 14 | ByteString* Pop(); 15 | void Clear(); 16 | int Length(); 17 | 18 | private: 19 | List queue; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /Makefile.Linux: -------------------------------------------------------------------------------- 1 | # 2 | # Scalien Makefile for Linux 3 | # 4 | 5 | INCLUDE = \ 6 | -I$(KEYSPACE_DIR)/src \ 7 | -I/usr/include/db4.5 8 | 9 | LDPATH = \ 10 | 11 | BASE_CFLAGS = -Wall -fPIC $(INCLUDE) -DPLATFORM_$(PLATFORM_UCASE) -D__STDC_FORMAT_MACROS 12 | BASE_CXXFLAGS = $(BASE_CFLAGS) 13 | BASE_LDFLAGS = -lpthread -ldb_cxx -lrt $(LDPATH) 14 | SOLINK = -shared -fPIC -Wl,-soname,$(SONAME) 15 | SOEXT = so 16 | SWIG_LDFLAGS = -shared -fPIC 17 | BUNDLEEXT = so -------------------------------------------------------------------------------- /src/Application/HTTP/HttpFileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_FILE_HANDLER_H 2 | #define HTTP_FILE_HANDLER_H 3 | 4 | #include "HttpServer.h" 5 | 6 | class HttpFileHandler : public HttpHandler 7 | { 8 | public: 9 | HttpFileHandler(const char* docroot, const char* prefix); 10 | 11 | virtual bool HandleRequest(HttpConn* conn, const HttpRequest& request); 12 | 13 | private: 14 | const char* documentRoot; 15 | const char* prefix; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/Application/HubSim/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "System/Events/EventLoop.h" 2 | #include "System/IO/IOProcessor.h" 3 | #include "HubSim.h" 4 | 5 | IOProcessor* ioproc; 6 | 7 | int main(int argc, char* argv[]) 8 | { 9 | Log_SetTimestamping(true); 10 | 11 | IOProcessor::Init(); 12 | 13 | HubSim hubSim; 14 | hubSim.CreateNode("127.0.0.1:4001", 5000); 15 | hubSim.CreateNode("127.0.0.1:4000", 5001); 16 | 17 | EventLoop::Run(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/System/IO/IOProcessor.h: -------------------------------------------------------------------------------- 1 | #ifndef IOPROCESSOR_H 2 | #define IOPROCESSOR_H 3 | 4 | #include "IOOperation.h" 5 | 6 | class Callable; 7 | 8 | class IOProcessor 9 | { 10 | public: 11 | static bool Init(int maxfd, bool blockSignals); 12 | static void Shutdown(); 13 | 14 | static bool Add(IOOperation* ioop); 15 | static bool Remove(IOOperation* ioop); 16 | 17 | static bool Poll(int sleep); 18 | 19 | static bool Complete(Callable* callable); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /test/concurrency/concurrency_set.py: -------------------------------------------------------------------------------- 1 | import keyspace 2 | import random 3 | import common 4 | 5 | client = keyspace.Client(["127.0.0.1:7080", 6 | "127.0.0.1:7081", 7 | "127.0.0.1:7082"]) 8 | 9 | random.seed() 10 | 11 | common.set_print_granularity(100) 12 | 13 | while True: 14 | common.loop_count() 15 | i = random.randrange(0, common.num, 1) 16 | key = "%s" % i 17 | value = key 18 | client.set(key, value) 19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/changes/frameset.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Database/KeyspaceConsts.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACECONSTS_H 2 | #define KEYSPACECONSTS_H 3 | 4 | #define KEYSPACE_KEY_SIZE (1*KB) 5 | #define KEYSPACE_VAL_SIZE (100*KB) 6 | #define KEYSPACE_KEY_META_SIZE (KEYSPACE_KEY_SIZE + 64) 7 | #define KEYSPACE_VAL_META_SIZE (KEYSPACE_VAL_SIZE + 64) 8 | // for the paxosID:commandID part 9 | 10 | #define KEYSPACE_BUF_SIZE (KEYSPACE_KEY_SIZE + 2*KEYSPACE_VAL_SIZE + 1*KB) 11 | 12 | #define CATCHUP_PORT_OFFSET 2 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/Test/Test.agazso.cpp: -------------------------------------------------------------------------------- 1 | int KeyspaceClientTest(int argc, char** argv); 2 | extern "C" int keyspace_client_test(); 3 | 4 | #include 5 | #include "Application/Keyspace/Client/KeyspaceClient.h" 6 | #include "System/Buffer.h" 7 | 8 | int 9 | main(int argc, char** argv) 10 | { 11 | int ret; 12 | (void) argc; 13 | (void) argv; 14 | // ret = KeyspaceClientTestSuite(); 15 | ret = KeyspaceClientTest(argc, argv); 16 | // ret = keyspace_client_test(); 17 | 18 | return ret; 19 | } 20 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/HTTP/HttpKeyspaceHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "HttpKeyspaceHandler.h" 2 | #include "HttpKeyspaceSession.h" 3 | 4 | HttpKeyspaceHandler::HttpKeyspaceHandler(KeyspaceDB* kdb_) 5 | { 6 | kdb = kdb_; 7 | } 8 | 9 | bool HttpKeyspaceHandler::HandleRequest(HttpConn* conn, const HttpRequest& request) 10 | { 11 | HttpKeyspaceSession* session; 12 | session = new HttpKeyspaceSession(kdb); 13 | session->Init(conn); 14 | return session->HandleRequest(request); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/System/Events/EventLoop.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTLOOP_H 2 | #define EVENTLOOP_H 3 | 4 | #include "System/IO/IOProcessor.h" 5 | #include "Scheduler.h" 6 | 7 | #define SLEEP_MSEC 20 8 | 9 | class EventLoop : public Scheduler 10 | { 11 | public: 12 | static long RunTimers(); 13 | static bool RunOnce(); 14 | static void Run(); 15 | static void Init(); 16 | static void Shutdown(); 17 | static uint64_t Now(); 18 | static void UpdateTime(); 19 | static void Stop(); 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/HTTP/HttpKeyspaceHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_HTTP_HANDLER_H 2 | #define KEYSPACE_HTTP_HANDLER_H 3 | 4 | #include "Application/HTTP/HttpServer.h" 5 | 6 | class HttpConn; 7 | 8 | class HttpKeyspaceHandler : public HttpHandler 9 | { 10 | public: 11 | HttpKeyspaceHandler(KeyspaceDB* kdb_); 12 | 13 | // HttpHandler interface 14 | virtual bool HandleRequest(HttpConn* conn, const HttpRequest& request); 15 | 16 | private: 17 | KeyspaceDB* kdb; 18 | }; 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportUDPWriter.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPORT_UDP_WRITER_H 2 | #define TRANSPORT_UDP_WRITER_H 3 | 4 | #include "System/IO/Endpoint.h" 5 | #include "System/IO/Socket.h" 6 | #include "System/Buffer.h" 7 | 8 | class TransportUDPWriter 9 | { 10 | public: 11 | TransportUDPWriter(); 12 | virtual ~TransportUDPWriter(); 13 | 14 | virtual bool Init(Endpoint &endpoint); 15 | virtual void Write(ByteString &bs); 16 | 17 | private: 18 | Endpoint endpoint; 19 | Socket socket; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/System/Events/Scheduler.cpp: -------------------------------------------------------------------------------- 1 | #include "Scheduler.h" 2 | 3 | SortedList Scheduler::timers; 4 | 5 | void Scheduler::Add(Timer* timer) 6 | { 7 | timer->OnAdd(); 8 | timer->active = true; 9 | timers.Add(timer); 10 | } 11 | 12 | void Scheduler::Remove(Timer* timer) 13 | { 14 | timers.Remove(timer); 15 | timer->active = false; 16 | } 17 | 18 | void Scheduler::Reset(Timer* timer) 19 | { 20 | Remove(timer); 21 | Add(timer); 22 | } 23 | 24 | void Scheduler::Shutdown() 25 | { 26 | timers.Clear(); 27 | } 28 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpRequest.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_REQUEST_H 2 | #define HTTP_REQUEST_H 3 | 4 | #include "IMF.h" 5 | 6 | class HttpRequest 7 | { 8 | public: 9 | typedef IMFHeader::RequestLine RequestLine; 10 | enum State 11 | { 12 | REQUEST_LINE, 13 | HEADER, 14 | CONTENT 15 | }; 16 | 17 | IMFHeader header; 18 | RequestLine line; 19 | State state; 20 | int pos; 21 | int contentLength; 22 | 23 | void Init(); 24 | void Free(); 25 | int Parse(char *buf, int len); 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/changes/rstsource.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans filename=filename, docstitle=docstitle|e %}{{ filename }} — {{ docstitle }}{% endtrans %} 6 | 9 | 10 | 11 |
12 |       {{ text }}
13 |     
14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupServer.h: -------------------------------------------------------------------------------- 1 | #ifndef CATCHUPSERVER_H 2 | #define CATCHUPSERVER_H 3 | 4 | #include "Framework/Transport/TCPServer.h" 5 | #include "Framework/Database/Table.h" 6 | #include "Framework/ReplicatedLog/ReplicatedLog.h" 7 | #include "CatchupWriter.h" 8 | 9 | #define CONN_BACKLOG 2 10 | 11 | class CatchupServer : public TCPServerT 12 | { 13 | public: 14 | void Init(int port); 15 | void Shutdown(); 16 | 17 | void InitConn(CatchupWriter* conn); 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/Application/Fuse/Channel.h: -------------------------------------------------------------------------------- 1 | #ifndef CHANNEL_H 2 | #define CHANNEL_H 3 | 4 | #include 5 | 6 | class Channel 7 | { 8 | public: 9 | Channel(); 10 | 11 | int Send(const char* buf, int count); 12 | int Receive(char* buf, int count); 13 | private: 14 | bool sending; 15 | pthread_mutex_t send_mutex; 16 | pthread_cond_t send_cond; 17 | 18 | bool receiving; 19 | pthread_mutex_t recv_mutex; 20 | pthread_cond_t recv_cond; 21 | 22 | const char* buf; 23 | int count; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/Application/Fuse/HttpClient.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_CLIENT_H 2 | #define HTTP_CLIENT_H 3 | 4 | #include "Framework/Transport/TCPConn.h" 5 | #include "Application/Keyspace/Protocol/HttpRequest.h" 6 | 7 | class HttpClient : public TCPConn<> 8 | { 9 | public: 10 | void Init(); 11 | void GetRequest(const char *url); 12 | 13 | private: 14 | HttpRequest response; 15 | 16 | // TCPConn interface 17 | virtual void OnRead(); 18 | virtual void OnClose(); 19 | 20 | int ParseResponse(char* buf, int len); 21 | 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef STDINT_H 2 | #define STDINT_H 3 | 4 | // Compatibility header file for Visual C++ 5 | 6 | typedef __int8 int8_t; 7 | typedef __int16 int16_t; 8 | typedef __int32 int32_t; 9 | typedef __int64 int64_t; 10 | 11 | typedef unsigned __int8 uint8_t; 12 | typedef unsigned __int16 uint16_t; 13 | typedef unsigned __int32 uint32_t; 14 | typedef unsigned __int64 uint64_t; 15 | 16 | typedef int64_t intmax_t; 17 | typedef uint64_t uintmax_t; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/Framework/Database/Cursor.h: -------------------------------------------------------------------------------- 1 | #ifndef CURSOR_HPP 2 | #define CURSOR_HPP 3 | 4 | #include "System/Buffer.h" 5 | #include 6 | 7 | class Table; // forward 8 | 9 | class Cursor 10 | { 11 | friend class Table; 12 | 13 | public: 14 | bool Start(ByteString &key); 15 | bool Start(ByteString &key, ByteString &value); 16 | bool Delete(); 17 | 18 | bool Next(ByteString &key, ByteString &value); 19 | bool Prev(ByteString &key, ByteString &value); 20 | 21 | bool Close(); 22 | 23 | private: 24 | Dbc* cursor; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/System/Config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | class Config 5 | { 6 | public: 7 | static bool Init(const char* filename); 8 | static void Shutdown(); 9 | 10 | static int GetIntValue(const char *name, int defval); 11 | static const char* GetValue(const char* name, const char *defval); 12 | static bool GetBoolValue(const char* name, bool defval); 13 | 14 | static int GetListNum(const char* name); 15 | static const char* GetListValue(const char* name, int num, const char* defval); 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /test/concurrency/concurrency_list.py: -------------------------------------------------------------------------------- 1 | import keyspace 2 | import random 3 | import common 4 | 5 | client = keyspace.Client(["127.0.0.1:7080", 6 | "127.0.0.1:7081", 7 | "127.0.0.1:7082"]) 8 | 9 | random.seed() 10 | 11 | common.set_print_granularity(100) 12 | 13 | while True: 14 | common.loop_count() 15 | kvs = client.list_key_values("") 16 | for key, value in kvs.iteritems(): 17 | if key != value: 18 | print("TEST FAILED") 19 | print("%s => %s" % (key, value)) 20 | exit(1) 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Framework/AsyncDatabase/AsyncDatabase.h: -------------------------------------------------------------------------------- 1 | #ifndef ASYNCDATABASE_H 2 | #define ASYNCDATABASE_H 3 | 4 | #include "MultiDatabaseOp.h" 5 | #include "System/ThreadPool.h" 6 | #include "System/Events/Callable.h" 7 | 8 | class MultiDatabaseOp; 9 | 10 | class AsyncDatabase 11 | { 12 | public: 13 | void Init(int numThread); 14 | void Shutdown(); 15 | 16 | void Add(MultiDatabaseOp* dbop); 17 | 18 | private: 19 | ThreadPool* threadPool; 20 | }; 21 | 22 | 23 | // globals 24 | extern AsyncDatabase dbWriter; 25 | extern AsyncDatabase dbReader; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /script/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . /etc/default/keyspace 4 | 5 | make_database_dir() { 6 | mkdir -p $DATABASE_DIR 7 | chown $KEYSPACE_USER $DATABASE_DIR 8 | } 9 | 10 | create_logfile() { 11 | touch $KEYSPACE_LOG 12 | chown $KEYSPACE_USER $KEYSPACE_LOG 13 | } 14 | 15 | start_if_needed() { 16 | if [ "$START_KEYSPACE" = "YES" ]; 17 | then 18 | /etc/init.d/keyspace start 19 | fi 20 | } 21 | 22 | echo "making database directory..." 23 | make_database_dir 24 | 25 | echo "creating log file..." 26 | create_logfile 27 | 28 | start_if_needed 29 | 30 | echo done 31 | -------------------------------------------------------------------------------- /script/mkcontrol.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # usage: 4 | # mkcontrol.sh target-control-file package-name version arch 5 | 6 | PACKAGE=$2 7 | VERSION=$3 8 | ARCH=$4 9 | 10 | cat > $1 << EOF 11 | Package: $PACKAGE 12 | Version: $VERSION 13 | Section: database 14 | Priority: optional 15 | Depends: libstdc++6, libdb4.4++|libdb4.5++|libdb4.6++ 16 | Architecture: $ARCH 17 | Installed-Size: 1024 18 | Maintainer: Scalien Software (info@scalien.com) 19 | Source: $PACKAGE 20 | Description: Scalien Keyspace DB 21 | Keyspace is a consistently replicated key-value database. 22 | 23 | EOF 24 | -------------------------------------------------------------------------------- /src/Framework/Database/Transaction.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSACTION_H 2 | #define TRANSACTION_H 3 | 4 | #include "Database.h" 5 | #include "Table.h" 6 | 7 | class Transaction 8 | { 9 | friend class Table; 10 | 11 | public: 12 | Transaction(); 13 | Transaction(Database* database); 14 | Transaction(Table* table); 15 | 16 | void Set(Database* database); 17 | void Set(Table* table); 18 | bool IsActive(); 19 | bool Begin(); 20 | bool Commit(); 21 | bool Rollback(); 22 | 23 | private: 24 | Database* database; 25 | DbTxn* txn; 26 | bool active; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/System/IO/FD.h: -------------------------------------------------------------------------------- 1 | #ifndef FD_H 2 | #define FD_H 3 | 4 | // File description abstraction 5 | 6 | // On Windows the file handle is a pointer, on unices it is a 7 | // growing index in an array in the process, thus it can be used 8 | // as an array index in IOProcessor. We emulate this behavior on 9 | // Windows. 10 | 11 | 12 | #ifdef PLATFORM_WINDOWS 13 | struct FD 14 | { 15 | int index; 16 | intptr_t sock; 17 | }; 18 | 19 | extern const FD INVALID_FD; 20 | 21 | #else 22 | typedef int FD; 23 | #define INVALID_FD -1 24 | #endif 25 | 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Framework/AsyncDatabase/AsyncDatabase.cpp: -------------------------------------------------------------------------------- 1 | #include "AsyncDatabase.h" 2 | #include "MultiDatabaseOp.h" 3 | 4 | 5 | // globals 6 | AsyncDatabase dbWriter; 7 | AsyncDatabase dbReader; 8 | 9 | 10 | void AsyncDatabase::Init(int numThread) 11 | { 12 | threadPool = ThreadPool::Create(numThread); 13 | threadPool->Start(); 14 | } 15 | 16 | void AsyncDatabase::Shutdown() 17 | { 18 | threadPool->Stop(); 19 | delete threadPool; 20 | } 21 | 22 | void AsyncDatabase::Add(MultiDatabaseOp* dbop) 23 | { 24 | dbop->active = true; 25 | 26 | threadPool->Execute(dbop->GetOperation()); 27 | } 28 | -------------------------------------------------------------------------------- /test/concurrency/concurrency_get.py: -------------------------------------------------------------------------------- 1 | import keyspace 2 | import random 3 | import common 4 | 5 | client = keyspace.Client(["127.0.0.1:7080", 6 | "127.0.0.1:7081", 7 | "127.0.0.1:7082"]) 8 | 9 | random.seed() 10 | 11 | common.set_print_granularity(100) 12 | 13 | while True: 14 | common.loop_count() 15 | i = random.randrange(0, common.num, 1) 16 | key = "%s" % i 17 | value = client.get(key) 18 | if value is None: continue 19 | if key != value: 20 | print("TEST FAILED") 21 | print("%s => %s" % (key, value)) 22 | exit(1) 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/ReplicatedLogMsg.h: -------------------------------------------------------------------------------- 1 | #ifndef REPLICATEDLOGMSG_H 2 | #define REPLICATEDLOGMSG_H 3 | 4 | #include "System/Buffer.h" 5 | 6 | #define BS_MSG_NOP ByteString(strlen("NOP"), strlen("NOP"), "NOP") 7 | 8 | class ReplicatedLogMsg 9 | { 10 | public: 11 | unsigned nodeID; 12 | uint64_t restartCounter; 13 | uint64_t leaseEpoch; 14 | ByteString value; 15 | 16 | bool Init(unsigned nodeID_, uint64_t restartCounter_, 17 | uint64_t leaseEpoch_, ByteString& value_); 18 | 19 | bool Read(const ByteString& data); 20 | bool Write(ByteString& data); 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /test/concurrency/concurrency_remove.py: -------------------------------------------------------------------------------- 1 | import keyspace 2 | import random 3 | import common 4 | 5 | client = keyspace.Client(["127.0.0.1:7080", 6 | "127.0.0.1:7081", 7 | "127.0.0.1:7082"]) 8 | 9 | random.seed() 10 | 11 | common.set_print_granularity(100) 12 | 13 | while True: 14 | common.loop_count() 15 | i = random.randrange(0, common.num, 1) 16 | key = "%s" % i 17 | value = client.remove(key) 18 | if value is None: continue 19 | if key != value: 20 | print("TEST FAILED") 21 | print("%s => %s" % (key, value)) 22 | exit(1) 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceClientConsts.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_CLIENT_CONSTS_H 2 | #define KEYSPACE_CLIENT_CONSTS_H 3 | 4 | #define KEYSPACE_SUCCESS 0 5 | #define KEYSPACE_API_ERROR -1 6 | 7 | #define KEYSPACE_PARTIAL -101 8 | #define KEYSPACE_FAILURE -102 9 | 10 | #define KEYSPACE_NOMASTER -201 11 | #define KEYSPACE_NOCONNECTION -202 12 | 13 | #define KEYSPACE_MASTER_TIMEOUT -301 14 | #define KEYSPACE_GLOBAL_TIMEOUT -302 15 | 16 | #define KEYSPACE_NOSERVICE -401 17 | #define KEYSPACE_FAILED -402 18 | 19 | #define KEYSPACE_DEFAULT_TIMEOUT 120*1000 // msec 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Perl/test.pl: -------------------------------------------------------------------------------- 1 | use Keyspace; 2 | 3 | $client = new Keyspace(("localhost:7080")); 4 | print($client->get("hol") . "\n"); 5 | $client->set("hol", "budapest"); 6 | print($client->get("hol") . "\n"); 7 | print($client->count('count' => 5) . "\n"); 8 | 9 | print($client->add("c", 1) . "\n"); 10 | 11 | @keys = $client->list_keys(); 12 | for my $key (@keys) { 13 | print($key . "\n"); 14 | } 15 | 16 | %kv = $client->list_key_values(); 17 | for my $key (keys %kv) { 18 | print($key . " => " . $kv{$key} . "\n"); 19 | } 20 | 21 | print(Keyspace::status_string($client->{result}->transport_status()) . "\n"); 22 | -------------------------------------------------------------------------------- /src/Application/EchoServer/TCPEchoServer.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPECHOSERVER_H 2 | #define TCPECHOSERVER_H 3 | 4 | #include "System/IO/IOProcessor.h" 5 | #include "System/IO/Socket.h" 6 | #include "System/Events/Scheduler.h" 7 | 8 | #define TCPECHOSERVER_PORT 3000 9 | 10 | class TCPEchoServer 11 | { 12 | typedef MFunc Func; 13 | 14 | public: 15 | TCPEchoServer(); 16 | 17 | private: 18 | bool Init(IOProcessor* ioproc_, Scheduler* scheduler_); 19 | 20 | void OnConnect(); 21 | IOProcessor* ioproc; 22 | Scheduler* scheduler; 23 | Socket listener; 24 | TCPRead tcpread; 25 | Func onConnect; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupServer.cpp: -------------------------------------------------------------------------------- 1 | #include "CatchupServer.h" 2 | #include "CatchupWriter.h" 3 | 4 | void CatchupServer::Init(int port_) 5 | { 6 | if (!TCPServerT::Init(port_, CONN_BACKLOG)) 7 | STOP_FAIL("Cannot initialize CatchupServer", 1); 8 | } 9 | 10 | void CatchupServer::Shutdown() 11 | { 12 | Close(); 13 | } 14 | 15 | void CatchupServer::InitConn(CatchupWriter* conn) 16 | { 17 | if (numActive > 1) 18 | { 19 | Log_Trace("@@@ have an active catchup connection, closing this @@@"); 20 | conn->Close(); 21 | DeleteConn(conn); 22 | return; 23 | } 24 | 25 | conn->Init(this); 26 | } 27 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ project|e }} 4 | {% trans docstitle=docstitle|e %}Search {{ docstitle }}{% endtrans %} 5 | utf-8 6 | 8 | {{ docstitle|e }} 9 | {% block extra %} {# Put e.g. an element here. #} {% endblock %} 10 | 11 | -------------------------------------------------------------------------------- /src/Application/HubSim/HubSim.h: -------------------------------------------------------------------------------- 1 | #ifndef HUBSIM_H 2 | #define HUBSIM_H 3 | 4 | #include "Link.h" 5 | 6 | #define MAX_NODES 10 7 | #define MAX_LINKS ((MAX_NODES * (MAX_NODES - 1)) / 2) 8 | 9 | class Node; 10 | 11 | class HubSim 12 | { 13 | public: 14 | Node* nodes[MAX_NODES]; 15 | int numNodes; 16 | Link* links[MAX_LINKS]; 17 | int numLinks; 18 | Link* goodLink; 19 | PacketLossLink* packetLossLink; 20 | ReorderingLink* reorderingLink; 21 | 22 | HubSim(); 23 | 24 | void AddLink(Link* link); 25 | void CreateNode(char *ip, int port); 26 | Node* GetNode(Endpoint &ep); 27 | Link* GetLink(Node* n1, Node* n2); 28 | }; 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/awsconf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cat << EOF 4 | paxos.nodeID = $1 5 | paxos.endpoints = 10.226.54.4:10000, 10.226.66.112:10000, 10.226.109.219:10000 6 | 7 | io.maxfd = 4096 8 | 9 | database.dir = test/$1 10 | database.checkpointSize = 100000 11 | database.checkpointInterval = 60 12 | database.pageSize = 4096 13 | database.cacheSize = 200M 14 | database.logBufferSize = 10M 15 | 16 | asyncDatabase.numReader = 6 17 | 18 | http.port = 8080 19 | memcached.port = 11110 20 | keyspace.port = 7080 21 | 22 | log.timestamping = true 23 | log.trace = true 24 | log.targets = stdout, file 25 | log.file = test/$1/keyspace.log 26 | 27 | timecheck.active = true 28 | EOF -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Memcache/MemcacheServer.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMCACHE_SERVER_H 2 | #define MEMCACHE_SERVER_H 3 | 4 | #include "System/IO/IOOperation.h" 5 | #include "System/IO/IOProcessor.h" 6 | #include "System/IO/Socket.h" 7 | #include "System/Containers/List.h" 8 | #include "Framework/Transport/TCPServer.h" 9 | #include "MemcacheConn.h" 10 | 11 | #define MEMCACHE_PORT 11111 12 | 13 | class KeyspaceDB; 14 | 15 | class MemcacheServer : public TCPServerT 16 | { 17 | public: 18 | void Init(KeyspaceDB* kdb); 19 | void InitConn(MemcacheConn* conn); 20 | private: 21 | KeyspaceDB* kdb; 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportTCPWriter.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPORT_TCP_WRITER_H 2 | #define TRANSPORT_TCP_WRITER_H 3 | 4 | #include "System/Events/Timer.h" 5 | #include "System/IO/IOProcessor.h" 6 | #include "Transport.h" 7 | #include "TCPConn.h" 8 | 9 | class TransportTCPWriter : public TCPConn 10 | { 11 | public: 12 | 13 | virtual bool Init(Endpoint &endpoint_); 14 | virtual void Write(ByteString &bs); 15 | 16 | private: 17 | void Connect(); 18 | void OnConnect(); 19 | void OnConnectTimeout(); 20 | 21 | // TCPConn interface 22 | virtual void OnRead(); 23 | virtual void OnClose(); 24 | 25 | Endpoint endpoint; 26 | }; 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/Application/HTTP/JSONSession.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SESSION_H 2 | #define JSON_SESSION_H 3 | 4 | #include "System/Buffer.h" 5 | 6 | class HttpConn; 7 | 8 | class JSONSession 9 | { 10 | public: 11 | void Init(HttpConn* conn, const ByteString& jsonCallback); 12 | 13 | void PrintStatus(const char* status, const char* type = NULL); 14 | 15 | void PrintString(const char* s, unsigned len); 16 | void PrintNumber(double number); 17 | void PrintBool(bool b); 18 | void PrintNull(); 19 | 20 | void PrintObjectStart(const char* name, unsigned len); 21 | void PrintObjectEnd(); 22 | 23 | private: 24 | ByteString jsonCallback; 25 | HttpConn* conn; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/PHP/test.php: -------------------------------------------------------------------------------- 1 | get("hol")); 9 | print($ks->count(array("count" => 10))); 10 | $ks->set("c", 2147483647); 11 | print($ks->add("c", 1) . "\n"); 12 | print($ks->result->transportStatus() . "\n"); 13 | var_dump($ks->listKeyValues(array("count" => 10))); 14 | var_dump($ks->listKeys(array("count" => 10))); 15 | var_dump($ks->listKeys(array("start_key" => "a", "count" => 10))); 16 | 17 | $ks2 = new KeyspaceClient(array("localhost:7080")); 18 | print($ks2->get("hol")); 19 | 20 | ?> 21 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/LogCache.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGCACHE_H 2 | #define LOGCACHE_H 3 | 4 | #include "System/Buffer.h" 5 | #include "Framework/Database/Table.h" 6 | #include "Framework/Paxos/PaxosConsts.h" 7 | 8 | #define LOGCACHE_DEFAULT_SIZE (100*1000) // # of Paxos rounds cached in db 9 | 10 | class LogCache 11 | { 12 | public: 13 | LogCache(); 14 | ~LogCache(); 15 | 16 | bool Init(uint64_t paxosID); 17 | bool Push(uint64_t paxosID, ByteString value, bool commit); 18 | bool Get(uint64_t paxosID, ByteString& value); 19 | 20 | private: 21 | void DeleteOldRounds(uint64_t paxosID); 22 | 23 | Table* table; 24 | ByteArray value; 25 | uint64_t logCacheSize; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/ReplicatedDB.h: -------------------------------------------------------------------------------- 1 | #ifndef REPLICATEDDB_H 2 | #define REPLICATEDDB_H 3 | 4 | #include "Framework/Database/Transaction.h" 5 | #include "Framework/ReplicatedLog/LogQueue.h" 6 | 7 | class Entry; 8 | 9 | class ReplicatedDB 10 | { 11 | public: 12 | virtual ~ReplicatedDB() {} 13 | 14 | virtual void OnAppend(Transaction* transaction, uint64_t paxosID, 15 | ByteString value, bool ownAppend) = 0; 16 | virtual void OnMasterLease() = 0; 17 | virtual void OnMasterLeaseExpired() = 0; 18 | virtual void OnDoCatchup(unsigned nodeID) = 0; 19 | 20 | virtual bool IsCatchingUp() = 0; 21 | 22 | // virtual void Stop() = 0; 23 | // virtual void Continue() = 0; 24 | 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportUDPWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "System/Buffer.h" 2 | #include "TransportUDPWriter.h" 3 | 4 | TransportUDPWriter::TransportUDPWriter() 5 | { 6 | } 7 | 8 | TransportUDPWriter::~TransportUDPWriter() 9 | { 10 | socket.Close(); 11 | } 12 | 13 | bool TransportUDPWriter::Init(Endpoint &endpoint_) 14 | { 15 | bool ret; 16 | 17 | endpoint = endpoint_; 18 | 19 | ret = true; 20 | ret &= socket.Create(Socket::UDP); 21 | ret &= socket.SetNonblocking(); 22 | return ret; 23 | } 24 | 25 | void TransportUDPWriter::Write(ByteString &bs) 26 | { 27 | // Log_Trace("sending %.*s to %s", bs.length, bs.buffer, endpoint.ToString()); 28 | 29 | socket.SendTo(bs.buffer, bs.length, endpoint); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupMsg.h: -------------------------------------------------------------------------------- 1 | #ifndef CATCHUPMSG_H 2 | #define CATCHUPMSG_H 3 | 4 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 5 | #include "System/Buffer.h" 6 | 7 | #define CATCHUP_KEY_VALUE 'k' 8 | #define CATCHUP_COMMIT 'c' 9 | 10 | class CatchupMsg 11 | { 12 | typedef ByteArray KeyBuffer; 13 | typedef ByteArray ValBuffer; 14 | public: 15 | char type; 16 | KeyBuffer key; 17 | ValBuffer value; 18 | uint64_t paxosID; 19 | 20 | void Init(char type_); 21 | void KeyValue(ByteString& key_, ByteString& value_); 22 | void Commit(uint64_t paxosID); 23 | 24 | bool Read(const ByteString& data); 25 | bool Write(ByteString& data); 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /doc/Sphinx/source/about.rst: -------------------------------------------------------------------------------- 1 | .. _about: 2 | 3 | ************** 4 | About Keyspace 5 | ************** 6 | 7 | Keyspace is a replicated key-value database, a product of Scalien, available at http://scalien.com. 8 | 9 | Keyspace is set apart from other key-value database because it uses so-called consistent replication, 10 | which means that all nodes see the database going through the same states. In other words, no 11 | split-brain scenario can occur, where different nodes see different versions of the database. 12 | 13 | More help 14 | ========= 15 | 16 | If you are experiencing difficulties please visit our Google Groups page: 17 | 18 | - group home page: http://groups.google.com/group/keyspace 19 | - group email address: keyspace@googlegroups.com 20 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceCommand.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_COMMAND_H 2 | #define KEYSPACE_COMMAND_H 3 | 4 | #include "System/Buffer.h" 5 | #include "System/Containers/List.h" 6 | 7 | namespace Keyspace 8 | { 9 | 10 | class Response; 11 | typedef List ResponseList; 12 | 13 | class Command 14 | { 15 | public: 16 | Command(); 17 | ~Command(); 18 | 19 | bool IsDirty() const; 20 | bool IsList() const; 21 | bool IsRead() const; 22 | bool IsWrite() const; 23 | 24 | void ClearResponse(); 25 | 26 | char type; 27 | ByteString key; 28 | DynArray<128> args; 29 | int nodeID; 30 | int status; 31 | uint64_t cmdID; 32 | 33 | ResponseList responses; 34 | }; 35 | 36 | }; // namespace 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/Application/EchoServer/UDPEchoServer.h: -------------------------------------------------------------------------------- 1 | #ifndef UDPECHOSERVER_H 2 | #define UDPECHOSERVER_H 3 | 4 | #include "System/IO/IOProcessor.h" 5 | #include "System/IO/Socket.h" 6 | #include "System/Events/Scheduler.h" 7 | 8 | #define UDPECHOSERVER_PORT 4000 9 | 10 | class UDPEchoServer 11 | { 12 | typedef ByteArray<1024> Buffer; 13 | typedef MFunc Func; 14 | 15 | public: 16 | UDPEchoServer(); 17 | 18 | bool Init(IOProcessor* ioproc_, Scheduler* scheduler_); 19 | void OnRead(); 20 | void OnWrite(); 21 | 22 | private: 23 | IOProcessor* ioproc; 24 | Scheduler* scheduler; 25 | Socket socket; 26 | UDPRead udpread; 27 | UDPWrite udpwrite; 28 | Buffer data; 29 | Func onRead; 30 | Func onWrite; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/System/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADPOOL_H 2 | #define THREADPOOL_H 3 | 4 | #include "System/Containers/List.h" 5 | 6 | class Callable; 7 | 8 | class ThreadPool 9 | { 10 | public: 11 | static ThreadPool* Create(int numThread); 12 | 13 | virtual ~ThreadPool() {} 14 | 15 | virtual void Start() = 0; 16 | virtual void Stop() = 0; 17 | 18 | virtual void Execute(Callable *callable) = 0; 19 | 20 | int NumPending() { return numPending; } 21 | int NumActive() { return numActive; } 22 | int NumTotal() { return numPending + numActive; /* atomicity bug */ } 23 | 24 | protected: 25 | List callables; 26 | int numPending; 27 | int numActive; 28 | int numThread; 29 | bool running; 30 | }; 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/Framework/Transport/TCPServer.cpp: -------------------------------------------------------------------------------- 1 | #include "System/IO/IOProcessor.h" 2 | #include "TCPServer.h" 3 | 4 | TCPServer::TCPServer() : 5 | onConnect(this, &TCPServer::OnConnect) 6 | { 7 | } 8 | 9 | bool TCPServer::Init(int port) 10 | { 11 | Log_Trace(); 12 | 13 | bool ret; 14 | 15 | ret = listener.Create(Socket::TCP); 16 | if (!ret) 17 | return false; 18 | ret = listener.Listen(port); 19 | if (!ret) 20 | return false; 21 | ret = listener.SetNonblocking(); 22 | if (!ret) 23 | return false; 24 | 25 | tcpread.fd = listener.fd; 26 | tcpread.listening = true; 27 | tcpread.onComplete = &onConnect; 28 | 29 | return IOProcessor::Add(&tcpread); 30 | } 31 | 32 | 33 | void TCPServer::Close() 34 | { 35 | // IOProcessor::Remove(&tcpread); 36 | listener.Close(); 37 | } 38 | -------------------------------------------------------------------------------- /src/Test/OpenDirect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "test.h" 6 | 7 | char *filename = "test.txt"; 8 | 9 | int 10 | open_direct_sync_io() 11 | { 12 | int fd; 13 | int ret; 14 | char buf[] = "open_direct_sync_io"; 15 | 16 | fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600); 17 | if (fd < 0) 18 | return TEST_FAILURE; 19 | 20 | ret = write(fd, buf, sizeof(buf) - 1); 21 | if (ret < 0) 22 | return TEST_FAILURE; 23 | 24 | close(fd); 25 | 26 | return TEST_SUCCESS; 27 | } 28 | 29 | 30 | int 31 | main(int argc, char *argv[]) 32 | { 33 | int ret = 0; 34 | 35 | if (argc >= 2) { 36 | filename = argv[1]; 37 | } 38 | 39 | ret += TEST(open_direct_sync_io); 40 | 41 | return test_eval(__FILE__, ret); 42 | } 43 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/ReplicatedLogMsg.cpp: -------------------------------------------------------------------------------- 1 | #include "ReplicatedLogMsg.h" 2 | 3 | bool ReplicatedLogMsg::Init(unsigned nodeID_, uint64_t restartCounter_, 4 | uint64_t leaseEpoch_, ByteString& value_) 5 | { 6 | nodeID = nodeID_; 7 | restartCounter = restartCounter_; 8 | leaseEpoch = leaseEpoch_; 9 | value.Set(value_); 10 | 11 | return true; 12 | } 13 | 14 | bool ReplicatedLogMsg::Read(const ByteString& data) 15 | { 16 | int read; 17 | 18 | read = snreadf(data.buffer, data.size, "%u:%U:%U:%N", 19 | &nodeID, &restartCounter, &leaseEpoch, &value); 20 | 21 | return (read == (signed)data.length ? true : false); 22 | } 23 | 24 | bool ReplicatedLogMsg::Write(ByteString& data) 25 | { 26 | return data.Writef("%u:%U:%U:%M", 27 | nodeID, restartCounter, leaseEpoch, &value); 28 | } 29 | -------------------------------------------------------------------------------- /test/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CONF=keyspace.conf 4 | 5 | create_gdb_conf() 6 | { 7 | cat > $1.gdb << EOF 8 | set confirm off 9 | handle SIG33 nostop 10 | run $CONF 11 | EOF 12 | } 13 | 14 | if [ "$1" = "" ]; then 15 | echo -e "usage: $0 config-number [command]\n" 16 | exit 1 17 | fi 18 | 19 | WD=`pwd` 20 | SCRIPT_DIR=`dirname $0` 21 | cd $SCRIPT_DIR/$1 22 | 23 | if [ "$2" = "" ]; then 24 | BIN=../../bin/scalien 25 | else 26 | if [ -x $2 ]; then 27 | BIN=$2 28 | else 29 | BIN=$WD/$2 30 | fi 31 | fi 32 | 33 | if [ "$3" = "-g" ]; then 34 | if [ ! -e $1.gdb ]; then 35 | create_gdb_conf $1 36 | fi 37 | CMD="gdb -x $1.gdb $BIN" 38 | elif [ "$3" = "-v" ]; then 39 | CMD="valgrind --leak-check=full --show-reachable=yes -v $BIN $CONF" 40 | else 41 | CMD="$BIN $CONF" 42 | fi 43 | 44 | $CMD 45 | exit $? 46 | -------------------------------------------------------------------------------- /test/single/keyspace.conf: -------------------------------------------------------------------------------- 1 | mode = single 2 | paxos.nodeID = 0 3 | paxos.endpoints = localhost:10000 4 | #paxos.endpoints = localhost:10000,192.168.1.2:10000,192.168.1.50:10000 5 | #paxos.endpoints = 94.76.202.195:10000 6 | 7 | io.maxfd = 4096 8 | 9 | database.dir = test/single 10 | database.type = hash # or btree 11 | database.checkpointSize = 100000 12 | database.checkpointTimeout = 0 13 | database.pageSize = 4096 14 | database.cacheSize = 100M 15 | database.directDB = true 16 | #database.txnNoSync = true 17 | database.txnWriteNoSync = true 18 | 19 | asyncDatabase.numReader = 6 20 | 21 | http.port = 8080 22 | memcached.port = 11110 23 | keyspace.port = 7080 24 | 25 | log.timestamping = true 26 | log.trace = false 27 | log.truncate = true 28 | log.targets = stdout, file 29 | log.file = test/single/keyspace.log 30 | -------------------------------------------------------------------------------- /doc/Sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Keyspace documentation master file, created by 2 | sphinx-quickstart on Wed Mar 10 16:38:55 2010. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Keyspace documentation 7 | ====================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :numbered: 14 | 15 | about.rst 16 | installation.rst 17 | configuration.rst 18 | running.rst 19 | understanding.rst 20 | http_api.rst 21 | python_api.rst 22 | java_api.rst 23 | csharp_api.rst 24 | c_api.rst 25 | php_api.rst 26 | ruby_api.rst 27 | perl_api.rst 28 | 29 | .. Indices and tables 30 | ================== 31 | 32 | * :ref:`genindex` 33 | * :ref:`modindex` 34 | * :ref:`search` 35 | 36 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/inttypes.h: -------------------------------------------------------------------------------- 1 | #ifndef INTTYPES_H 2 | #define INTTYPES_H 3 | 4 | // Compatibility header file for Visual C++ 5 | 6 | #include 7 | 8 | typedef struct 9 | { 10 | intmax_t quot, rem; 11 | } imaxdiv_t; 12 | 13 | inline intmax_t imaxabs(intmax_t i) 14 | { 15 | if (i < 0) 16 | return -i; 17 | 18 | return i; 19 | } 20 | 21 | inline imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) 22 | { 23 | imaxdiv_t retval; 24 | 25 | retval.quot = numer / denom; 26 | retval.rem = numer % denom; 27 | 28 | if (numer >= 0 && retval.rem < 0) 29 | { 30 | retval.quot++; 31 | retval.rem -= denom; 32 | } 33 | 34 | return (retval); 35 | } 36 | 37 | #define strtoimax _strtoi64 38 | #define strtoumax _strtoui64 39 | 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpServer.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_SERVER_H 2 | #define HTTP_SERVER_H 3 | 4 | #include "Framework/Transport/TCPServer.h" 5 | #include "HttpConn.h" 6 | 7 | class KeyspaceDB; 8 | class HttpRequest; 9 | class HttpServer; 10 | 11 | class HttpHandler 12 | { 13 | public: 14 | virtual ~HttpHandler() {} 15 | virtual bool HandleRequest(HttpConn* conn, const HttpRequest& request) = 0; 16 | 17 | HttpHandler* nextHttpHandler; 18 | }; 19 | 20 | class HttpServer : public TCPServerT 21 | { 22 | public: 23 | void Init(int port); 24 | void Shutdown(); 25 | 26 | void InitConn(HttpConn* conn); 27 | 28 | void RegisterHandler(HttpHandler* handler); 29 | bool HandleRequest(HttpConn* conn, const HttpRequest& request); 30 | 31 | private: 32 | HttpHandler* handlers; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /test/aws.sh: -------------------------------------------------------------------------------- 1 | # as root 2 | alias up='svn up; make clean debug' 3 | alias ntpsync='ntpdate-debian' 4 | alias conf='for i in `seq 0 2`; do test/awsconf.sh $i > test/$i/keyspace.conf; done' 5 | apt-get update 6 | apt-get -y install subversion libdb4.6++-dev db4.6-util joe telnet unzip gdb ntpdate less valgrind fakeroot iotop curl make g++ 7 | 8 | # as user 9 | #svn checkout http://svn.scalien.com/keyspace/trunk keyspace 10 | VERSION=`curl http://scalien.com/downloads/latest.txt` 11 | KEYSPACE_VERSION=keyspace-$VERSION 12 | KEYSPACE_TGZ=$KEYSPACE_VERSION.tgz 13 | curl http://scalien.com/releases/keyspace/$KEYSPACE_TGZ -o $KEYSPACE_TGZ 14 | tar xzvf $KEYSPACE_TGZ 15 | cd $KEYSPACE_VERSION 16 | make 17 | 18 | up 19 | echo 1 > /proc/sys/xen/independent_wallclock 20 | ntpdate-debian 21 | echo "*/10 * * * * root ntpdate-debian" >> /etc/crontab 22 | conf 23 | 24 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceResponse.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_RESPONSE_H 2 | #define KEYSPACE_RESPONSE_H 3 | 4 | #include "System/Buffer.h" 5 | 6 | namespace Keyspace 7 | { 8 | 9 | class Client; 10 | class Command; 11 | 12 | class Response 13 | { 14 | public: 15 | DynArray<128> key; 16 | DynArray<128> value; 17 | int commandStatus; 18 | char type; 19 | uint64_t id; 20 | 21 | bool Read(const ByteString& data); 22 | 23 | private: 24 | char* pos; 25 | char separator; 26 | ByteString data; 27 | ByteString msg; 28 | 29 | bool CheckOverflow(); 30 | bool ReadUint64(uint64_t& num); 31 | bool ReadChar(char& c); 32 | bool ReadSeparator(); 33 | bool ReadMessage(ByteString& bs); 34 | bool ReadData(ByteString& bs, uint64_t length); 35 | 36 | bool ValidateLength(); 37 | }; 38 | 39 | }; // namespace 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/SWIGTYPE_p_void.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 1.3.31 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package com.scalien.keyspace; 10 | 11 | public class SWIGTYPE_p_void { 12 | private long swigCPtr; 13 | 14 | protected SWIGTYPE_p_void(long cPtr, boolean futureUse) { 15 | swigCPtr = cPtr; 16 | } 17 | 18 | protected SWIGTYPE_p_void() { 19 | swigCPtr = 0; 20 | } 21 | 22 | protected static long getCPtr(SWIGTYPE_p_void obj) { 23 | return (obj == null) ? 0 : obj.swigCPtr; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/Application/EchoServer/TCPEchoConn.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPECHOCONN_H 2 | #define TCPECHOCONN_H 3 | 4 | #include "System/IO/IOProcessor.h" 5 | #include "System/IO/Socket.h" 6 | #include "System/Events/Scheduler.h" 7 | 8 | class TCPEchoConn 9 | { 10 | friend class TCPEchoServer; 11 | typedef ByteArray<1024> Buffer; 12 | typedef MFunc Func; 13 | 14 | public: 15 | TCPEchoConn(); 16 | 17 | bool Init(IOProcessor* ioproc_); 18 | void Shutdown(); 19 | void OnWelcome(); 20 | void OnRead(); 21 | void OnWrite(); 22 | void OnCloseRead(); 23 | void OnCloseWrite(); 24 | 25 | 26 | private: 27 | IOProcessor* ioproc; 28 | Socket socket; 29 | TCPRead tcpread; 30 | TCPWrite tcpwrite; 31 | Buffer data; 32 | Func onWelcome; 33 | Func onRead; 34 | Func onWrite; 35 | Func onCloseRead; 36 | Func onCloseWrite; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportUDPReader.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPORTUDPREADER_H 2 | #define TRANSPORTUDPREADER_H 3 | 4 | #include "System/IO/Socket.h" 5 | #include "System/Buffer.h" 6 | #include "System/Events/Callable.h" 7 | #include "System/IO/IOOperation.h" 8 | #include "Transport.h" 9 | 10 | class TransportUDPReader 11 | { 12 | typedef ByteArray Buffer; 13 | typedef MFunc Func; 14 | 15 | public: 16 | TransportUDPReader(); 17 | 18 | bool Init(int port); 19 | 20 | void SetOnRead(Callable* onRead); 21 | void GetMessage(ByteString& bs); 22 | void GetEndpoint(Endpoint& endpoint); 23 | void Stop(); 24 | void Continue(); 25 | bool IsActive(); 26 | void OnRead(); 27 | 28 | private: 29 | Socket socket; 30 | UDPRead udpread; 31 | Buffer data; 32 | Func onRead; 33 | Callable* userCallback; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/SWIGTYPE_p_p_char.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 1.3.31 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package com.scalien.keyspace; 10 | 11 | public class SWIGTYPE_p_p_char { 12 | private long swigCPtr; 13 | 14 | protected SWIGTYPE_p_p_char(long cPtr, boolean futureUse) { 15 | swigCPtr = cPtr; 16 | } 17 | 18 | protected SWIGTYPE_p_p_char() { 19 | swigCPtr = 0; 20 | } 21 | 22 | protected static long getCPtr(SWIGTYPE_p_p_char obj) { 23 | return (obj == null) ? 0 : obj.swigCPtr; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/Application/Fuse/HttpClient.cpp: -------------------------------------------------------------------------------- 1 | #include "HttpClient.h" 2 | 3 | #define CR 13 4 | #define LF 10 5 | #define CS_CR "\015" 6 | #define CS_LF "\012" 7 | #define CS_CRLF CS_CR CS_LF 8 | 9 | void HttpClient::Init() 10 | { 11 | TCPConn<>::Init(); 12 | response.Init(); 13 | } 14 | 15 | void HttpClient::GetRequest(const char* url) 16 | { 17 | char* hostname = NULL; 18 | 19 | Write("GET ", 4, false); 20 | Write(url, strlen(url), false); 21 | Write(" HTTP/1.1" CS_CRLF, 11, false); 22 | Write("Host: ", 6, false); 23 | if (hostname) 24 | Write(hostname, strlen(hostname), false); 25 | else 26 | Write("localhost", sizeof("localhost") - 1); 27 | Write(CS_CRLF CS_CRLF, 4, false); 28 | } 29 | 30 | void HttpClient::OnRead() 31 | { 32 | } 33 | 34 | void HttpClient::OnClose() 35 | { 36 | } 37 | 38 | int HttpClient::ParseResponse(char* buf, int len) 39 | { 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/System/IO/Endpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef ENDPOINT_H 2 | #define ENDPOINT_H 3 | 4 | #include "System/Platform.h" 5 | #include "System/Log.h" 6 | 7 | #define ENDPOINT_ANY_ADDRESS 0 8 | #define ENDPOINT_STRING_SIZE 32 9 | #define ENDPOINT_SOCKADDR_SIZE 16 10 | 11 | class Endpoint 12 | { 13 | public: 14 | Endpoint(); 15 | 16 | bool operator==(const Endpoint &other) const; 17 | bool operator!=(const Endpoint &other) const; 18 | 19 | bool Set(const char* ip, int port, bool resolve = false); 20 | bool Set(const char* ip_port, bool resolve = false); 21 | 22 | bool SetPort(int port); 23 | int GetPort(); 24 | 25 | uint32_t GetAddress(); 26 | 27 | const char* ToString(); 28 | const char* ToString(char s[ENDPOINT_STRING_SIZE]); 29 | 30 | char* GetSockAddr() { return saBuffer; } 31 | 32 | private: 33 | char buffer[ENDPOINT_STRING_SIZE]; 34 | char saBuffer[ENDPOINT_SOCKADDR_SIZE]; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/Test/ThreadPoolTest.cpp: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "System/Events/Callable.h" 3 | #include "System/ThreadPool.h" 4 | #include "System/Time.h" 5 | 6 | class DatabaseOperation 7 | { 8 | public: 9 | DatabaseOperation() : num(0), request(this, &DatabaseOperation::Request) {} 10 | 11 | int num; 12 | 13 | void Request(); 14 | MFunc request; 15 | }; 16 | 17 | void DatabaseOperation::Request() 18 | { 19 | TEST_LOG("thread = %08x, num = %d", (unsigned long) pthread_self(), num); 20 | Sleep(1000); 21 | } 22 | 23 | int ThreadPoolTest() 24 | { 25 | ThreadPool tp(1); 26 | DatabaseOperation ops[100]; 27 | 28 | tp.Start(); 29 | for (int i = 0; i < 100; i++) 30 | { 31 | DatabaseOperation *op = &ops[i]; 32 | op->num = i; 33 | 34 | tp.Execute(&op->request); 35 | } 36 | 37 | Sleep(10000); 38 | 39 | return TEST_SUCCESS; 40 | } 41 | 42 | TEST_MAIN(ThreadPoolTest); 43 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseAcceptor.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASEACCEPTOR_H 2 | #define PLEASEACCEPTOR_H 3 | 4 | #include "System/Common.h" 5 | #include "System/Events/Timer.h" 6 | #include "Framework/Transport/TransportTCPWriter.h" 7 | #include "PLeaseConsts.h" 8 | #include "PLeaseMsg.h" 9 | #include "PLeaseState.h" 10 | 11 | class ReplicatedLog; 12 | 13 | class PLeaseAcceptor 14 | { 15 | typedef TransportTCPWriter** Writers; 16 | typedef MFunc Func; 17 | typedef PLeaseAcceptorState State; 18 | 19 | public: 20 | PLeaseAcceptor(); 21 | 22 | void Init(Writers writers_); 23 | void ProcessMsg(PLeaseMsg &msg_); 24 | void OnLeaseTimeout(); 25 | 26 | private: 27 | void SendReply(unsigned nodeID); 28 | 29 | void OnPrepareRequest(); 30 | void OnProposeRequest(); 31 | 32 | Writers writers; 33 | ByteBuffer wdata; 34 | Func onLeaseTimeout; 35 | Timer leaseTimeout; 36 | PLeaseMsg msg; 37 | State state; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/ReplicatedConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef REPLICATEDCONFIG_H 2 | #define REPLICATEDCONFIG_H 3 | 4 | #include "System/Platform.h" 5 | #include "System/IO/Endpoint.h" 6 | 7 | #define MAX_CELL_SIZE 256 8 | #define WIDTH_NODEID 8 9 | #define WIDTH_RESTART_COUNTER 16 10 | 11 | #define RCONF (ReplicatedConfig::Get()) 12 | 13 | 14 | class ReplicatedConfig 15 | { 16 | public: 17 | static ReplicatedConfig* Get(); 18 | 19 | bool Init(); 20 | 21 | unsigned MinMajority(); 22 | uint64_t NextHighest(uint64_t proposalID); 23 | unsigned GetPort(); 24 | unsigned GetNodeID(); 25 | unsigned GetNumNodes(); 26 | uint64_t GetRestartCounter(); 27 | const Endpoint GetEndpoint(unsigned i); 28 | 29 | private: 30 | unsigned nodeID; 31 | unsigned numNodes; // same as endpoints.size 32 | uint64_t restartCounter; 33 | Endpoint endpoints[MAX_CELL_SIZE]; 34 | 35 | private: 36 | void InitRestartCounter(); 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/Application/EchoServer/TCPEchoServer.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPEchoServer.h" 2 | #include 3 | #include "System/Log.h" 4 | #include "TCPEchoConn.h" 5 | 6 | TCPEchoServer::TCPEchoServer() : 7 | onConnect(this, &TCPEchoServer::OnConnect) 8 | { 9 | } 10 | 11 | bool TCPEchoServer::Init(IOProcessor* ioproc_, Scheduler* scheduler_) 12 | { 13 | ioproc = ioproc_; 14 | scheduler = scheduler_; 15 | 16 | listener.Create(Socket::TCP); 17 | listener.Listen(TCPECHOSERVER_PORT); 18 | listener.SetNonblocking(); 19 | 20 | tcpread.fd = listener.fd; 21 | tcpread.listening = true; 22 | tcpread.onComplete = &onConnect; 23 | 24 | return ioproc->Add(&tcpread); 25 | } 26 | 27 | void TCPEchoServer::OnConnect() 28 | { 29 | TCPEchoConn* conn = new TCPEchoConn(); 30 | if (listener.Accept(&(conn->socket))) 31 | { 32 | conn->socket.SetNonblocking(); 33 | conn->Init(ioproc); 34 | } else 35 | { 36 | delete conn; 37 | } 38 | 39 | ioproc->Add(&tcpread); 40 | } 41 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/ListParams.java: -------------------------------------------------------------------------------- 1 | package com.scalien.keyspace; 2 | 3 | public class ListParams 4 | { 5 | public ListParams() { 6 | prefix = ""; 7 | startKey = ""; 8 | count = 0; 9 | skip = false; 10 | forward = true; 11 | } 12 | 13 | public ListParams setPrefix(String prefix) { 14 | this.prefix = prefix; 15 | return this; 16 | } 17 | 18 | public ListParams setStartKey(String startKey) { 19 | this.startKey = startKey; 20 | return this; 21 | } 22 | 23 | public ListParams setCount(long count) { 24 | this.count = count; 25 | return this; 26 | } 27 | 28 | public ListParams setSkip(boolean skip) { 29 | this.skip = skip; 30 | return this; 31 | } 32 | 33 | public ListParams setForward(boolean forward) { 34 | this.forward = forward; 35 | return this; 36 | } 37 | 38 | public String prefix; 39 | public String startKey; 40 | public long count; 41 | public boolean skip; 42 | public boolean forward; 43 | } 44 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/HTTP/HttpApiHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_API_HANDLER_H 2 | #define HTTP_API_HANDLER_H 3 | 4 | #include "Application/HTTP/HttpServer.h" 5 | 6 | class JSONSession; 7 | class UrlParam; 8 | 9 | class HttpApiHandler : public HttpHandler 10 | { 11 | public: 12 | HttpApiHandler(KeyspaceDB* kdb); 13 | 14 | virtual bool HandleRequest(HttpConn* conn, const HttpRequest& request); 15 | 16 | bool Checkpoint(JSONSession* jsonSession, const UrlParam& param); 17 | bool GetConfigVar(JSONSession* jsonSession, const UrlParam& param); 18 | bool LogTrace(JSONSession* jsonSession, const UrlParam& param); 19 | bool Status(JSONSession* jsonSession, const UrlParam& param); 20 | bool Segfault(JSONSession* jsonSession, const UrlParam& param); 21 | bool Exit(JSONSession* jsonSession, const UrlParam& param); 22 | bool Restart(JSONSession* jsonSession, const UrlParam& param); 23 | 24 | private: 25 | KeyspaceDB* kdb; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/SWIGTYPE_p_void.cs: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 2.0.0 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | 10 | using System; 11 | using System.Runtime.InteropServices; 12 | 13 | public class SWIGTYPE_p_void { 14 | private HandleRef swigCPtr; 15 | 16 | internal SWIGTYPE_p_void(IntPtr cPtr, bool futureUse) { 17 | swigCPtr = new HandleRef(this, cPtr); 18 | } 19 | 20 | protected SWIGTYPE_p_void() { 21 | swigCPtr = new HandleRef(null, IntPtr.Zero); 22 | } 23 | 24 | internal static HandleRef getCPtr(SWIGTYPE_p_void obj) { 25 | return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpServer.cpp: -------------------------------------------------------------------------------- 1 | #include "HttpServer.h" 2 | #include "System/IO/IOProcessor.h" 3 | 4 | #define CONN_BACKLOG 10 5 | 6 | void HttpServer::Init(int port) 7 | { 8 | if (!TCPServerT::Init(port, CONN_BACKLOG)) 9 | STOP_FAIL("Cannot initialize HttpServer", 1); 10 | handlers = NULL; 11 | } 12 | 13 | void HttpServer::Shutdown() 14 | { 15 | Close(); 16 | } 17 | 18 | void HttpServer::InitConn(HttpConn* conn) 19 | { 20 | conn->Init(this); 21 | } 22 | 23 | void HttpServer::RegisterHandler(HttpHandler* handler) 24 | { 25 | handler->nextHttpHandler = handlers; 26 | handlers = handler; 27 | } 28 | 29 | bool HttpServer::HandleRequest(HttpConn* conn, const HttpRequest& request) 30 | { 31 | HttpHandler* handler; 32 | bool ret; 33 | 34 | // call each handler until one handles the request 35 | ret = false; 36 | for (handler = handlers; handler && !ret; handler = handler->nextHttpHandler) 37 | ret = handler->HandleRequest(conn, request); 38 | 39 | return ret; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/SWIGTYPE_p_p_char.cs: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 2.0.0 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | 10 | using System; 11 | using System.Runtime.InteropServices; 12 | 13 | public class SWIGTYPE_p_p_char { 14 | private HandleRef swigCPtr; 15 | 16 | internal SWIGTYPE_p_p_char(IntPtr cPtr, bool futureUse) { 17 | swigCPtr = new HandleRef(this, cPtr); 18 | } 19 | 20 | protected SWIGTYPE_p_p_char() { 21 | swigCPtr = new HandleRef(null, IntPtr.Zero); 22 | } 23 | 24 | internal static HandleRef getCPtr(SWIGTYPE_p_p_char obj) { 25 | return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System/IO/Socket.h: -------------------------------------------------------------------------------- 1 | #ifndef SOCKET_H 2 | #define SOCKET_H 3 | 4 | #include "System/Platform.h" 5 | #include "Endpoint.h" 6 | #include "FD.h" 7 | 8 | class Socket 9 | { 10 | public: 11 | enum Proto { 12 | TCP, 13 | UDP 14 | }; 15 | 16 | Socket(); 17 | 18 | bool Create(Proto proto); 19 | 20 | bool SetNonblocking(); 21 | bool SetNodelay(); 22 | 23 | bool Bind(int port); 24 | bool Bind(const Endpoint& endpoint); 25 | bool Listen(int port, int backlog = 1024); 26 | bool Accept(Socket* newSocket); 27 | bool Connect(Endpoint &endpoint); 28 | 29 | bool GetEndpoint(Endpoint &endpoint); 30 | const char* ToString(char s[ENDPOINT_STRING_SIZE]); 31 | 32 | bool SendTo(void* data, int count, const Endpoint &endpoint); 33 | int Send(const char* data, int count, int timeout = 0); 34 | int Read(char* data, int count, int timeout = 0); 35 | 36 | void Close(); 37 | 38 | public: 39 | FD fd; 40 | int type; // TODO rename to proto 41 | bool listening; 42 | 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupWriter.h: -------------------------------------------------------------------------------- 1 | #ifndef CATCHUPCONN_H 2 | #define CATCHUPCONN_H 3 | 4 | #include "Framework/Transport/TCPConn.h" 5 | #include "Framework/Database/Transaction.h" 6 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 7 | #include "Framework/Paxos/PaxosConsts.h" 8 | #include "CatchupMsg.h" 9 | 10 | class CatchupServer; 11 | 12 | class CatchupWriter : public TCPConn<> 13 | { 14 | typedef ByteArray KeyBuffer; 15 | typedef ByteArray ValBuffer; 16 | 17 | public: 18 | CatchupWriter(); 19 | 20 | void Init(CatchupServer* server); 21 | 22 | void OnRead(); 23 | void OnWrite(); 24 | virtual void OnClose(); 25 | 26 | private: 27 | void WriteNext(); 28 | Buffer writeBuffer; 29 | Table* table; 30 | Cursor cursor; 31 | CatchupMsg msg; 32 | uint64_t paxosID; 33 | KeyBuffer key; 34 | ValBuffer value; 35 | CatchupServer* server; 36 | ByteArray<32> prefix; 37 | ByteArray msgData; 38 | 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceClientResp.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACECLIENTRESP_H 2 | #define KEYSPACECLIENTRESP_H 3 | 4 | #define KEYSPACECLIENT_OK 'o' 5 | #define KEYSPACECLIENT_FAILED 'f' 6 | #define KEYSPACECLIENT_NOT_MASTER 'n' 7 | #define KEYSPACECLIENT_LIST_ITEM 'i' 8 | #define KEYSPACECLIENT_LISTP_ITEM 'j' 9 | #define KEYSPACECLIENT_LIST_END '.' 10 | 11 | #include "System/Buffer.h" 12 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 13 | 14 | class KeyspaceClientResp 15 | { 16 | public: 17 | char type; 18 | uint64_t cmdID; 19 | ByteString key; 20 | ByteString value; 21 | bool sendValue; 22 | 23 | void Ok(uint64_t cmdID_); 24 | void Ok(uint64_t cmdID_, ByteString value_); 25 | void Failed(uint64_t cmdID_); 26 | void NotMaster(uint64_t cmdID_); 27 | void ListItem(uint64_t cmdID_, ByteString key_); 28 | void ListPItem(uint64_t cmdID_, ByteString key_, ByteString value_); 29 | void ListEnd(uint64_t cmdID_); 30 | 31 | bool Write(ByteString& data); 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/Framework/ReplicatedLog/LogQueue.cpp: -------------------------------------------------------------------------------- 1 | #include "LogQueue.h" 2 | 3 | LogQueue::~LogQueue() 4 | { 5 | ByteString** it; 6 | ByteString* bs; 7 | 8 | for (it = queue.Head(); it; ) 9 | { 10 | bs = *it; 11 | it = queue.Next(it); 12 | delete bs; 13 | } 14 | } 15 | 16 | bool LogQueue::Push(ByteString& value) 17 | { 18 | ByteString* bs = new ByteString(); 19 | 20 | bs->Set(value); 21 | 22 | queue.Add(bs); 23 | 24 | return true; 25 | } 26 | 27 | 28 | ByteString* LogQueue::Next() 29 | { 30 | ByteString** it; 31 | 32 | it = queue.Tail(); 33 | 34 | if (it == NULL) 35 | return NULL; 36 | 37 | return *it; 38 | } 39 | 40 | ByteString* LogQueue::Pop() 41 | { 42 | ByteString** it; 43 | ByteString* bs; 44 | 45 | it = queue.Tail(); 46 | 47 | if (it == NULL) 48 | return NULL; 49 | 50 | bs = *it; 51 | 52 | queue.Remove(bs); 53 | 54 | return bs; 55 | } 56 | 57 | void LogQueue::Clear() 58 | { 59 | queue.Clear(); 60 | } 61 | 62 | int LogQueue::Length() 63 | { 64 | return queue.Length(); 65 | } 66 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceServer.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACESERVER_H 2 | #define KEYSPACESERVER_H 3 | 4 | #include "../ProtocolServer.h" 5 | #include "System/Events/Timer.h" 6 | #include "Framework/Transport/TCPServer.h" 7 | #include "KeyspaceConn.h" 8 | 9 | #define KEYSPACE_POOL_MIN_THRUPUT 250*KB 10 | #define KEYSPACE_CONN_MIN_THRUPUT 10*KB 11 | 12 | class KeyspaceDB; 13 | 14 | class KeyspaceServer : public ProtocolServer, 15 | public TCPServerT 16 | { 17 | typedef MFunc Func; 18 | 19 | public: 20 | KeyspaceServer(); 21 | 22 | void Init(KeyspaceDB* kdb, int port); 23 | void Shutdown(); 24 | 25 | void InitConn(KeyspaceConn* conn); 26 | void DeleteConn(KeyspaceConn* conn); 27 | void OnThruputTimeout(); 28 | void OnDataRead(KeyspaceConn* conn, unsigned bytes); 29 | 30 | uint64_t bytesRead; 31 | 32 | private: 33 | KeyspaceDB* kdb; 34 | Func onThruputTimeout; 35 | CdownTimer thruputTimeout; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Makefile.clientlib: -------------------------------------------------------------------------------- 1 | CLIENTLIB_OBJECTS = \ 2 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceClient.o \ 3 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceClientConn.o \ 4 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceCommand.o \ 5 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceResponse.o \ 6 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceResult.o \ 7 | $(BUILD_DIR)/Application/Keyspace/Client/keyspace_client.o \ 8 | $(BUILD_DIR)/System/Common.o \ 9 | $(BUILD_DIR)/System/Config.o \ 10 | $(BUILD_DIR)/System/Log.o \ 11 | $(BUILD_DIR)/System/Platform.o \ 12 | $(BUILD_DIR)/System/Time_Posix.o \ 13 | $(BUILD_DIR)/System/Events/EventLoop.o \ 14 | $(BUILD_DIR)/System/Events/Scheduler.o \ 15 | $(BUILD_DIR)/System/IO/Endpoint.o \ 16 | $(BUILD_DIR)/System/IO/Socket_Posix.o \ 17 | $(BUILD_DIR)/System/IO/IOProcessor_$(PLATFORM).o \ 18 | 19 | SWIG_LIB_OBJECT = \ 20 | $(BUILD_DIR)/Application/Keyspace/Client/KeyspaceClientWrap.o 21 | 22 | PYTHON_CLIENT_OBJECT = \ 23 | $(BUILD_DIR)/Application/Keyspace/Client/Python/keyspace_client_python.o 24 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Database/SyncListVisitor.h: -------------------------------------------------------------------------------- 1 | #ifndef SYNCLISTVISITOR_H 2 | #define SYNCLISTVISITOR_H 3 | 4 | #include "System/Events/Callable.h" 5 | #include "System/Buffer.h" 6 | #include "Framework/Database/Table.h" 7 | #include "Framework/AsyncDatabase/MultiDatabaseOp.h" 8 | #include "KeyspaceService.h" 9 | 10 | #define LIST_RUN_GRANULARITY 1000 11 | 12 | class SyncListVisitor : public TableVisitor 13 | { 14 | public: 15 | SyncListVisitor(KeyspaceOp* op_); 16 | 17 | void AppendKey(const ByteString &key); 18 | void AppendKeyValue(const ByteString &key, 19 | const ByteString &value); 20 | virtual bool Accept(const ByteString &key, 21 | const ByteString &value); 22 | virtual const ByteString* GetStartKey(); 23 | virtual void OnComplete(); 24 | virtual bool IsForward(); 25 | 26 | bool completed; 27 | KeyspaceOp* op; 28 | const ByteString &prefix; 29 | DynArray<128> startKey; 30 | uint64_t count; 31 | uint64_t offset; 32 | uint64_t num; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/System/Containers/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | template 5 | class Queue 6 | { 7 | public: 8 | 9 | Queue() 10 | { 11 | size = 0; 12 | head = 0; 13 | tail = 0; 14 | Clear(); 15 | } 16 | 17 | int Size() { return size; } 18 | 19 | void Clear() 20 | { 21 | T* elem; 22 | 23 | do 24 | { 25 | elem = Get(); 26 | } while (elem); 27 | } 28 | 29 | void Append(T* elem) 30 | { 31 | assert(elem != 0); 32 | 33 | elem->*pnext = 0; 34 | if (tail) 35 | tail->*pnext = elem; 36 | else 37 | head = elem; 38 | tail = elem; 39 | size++; 40 | } 41 | 42 | T* Get() 43 | { 44 | T* elem; 45 | elem = head; 46 | if (elem) 47 | { 48 | head = elem->*pnext; 49 | if (tail == elem) 50 | tail = 0; 51 | elem->*pnext = 0; 52 | size--; 53 | } 54 | return elem; 55 | } 56 | 57 | T* Head() 58 | { 59 | return head; 60 | } 61 | 62 | T* Tail() 63 | { 64 | return tail; 65 | } 66 | 67 | private: 68 | T* head; 69 | T* tail; 70 | int size; 71 | }; 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseLearner.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASELEARNER_H 2 | #define PLEASELEARNER_H 3 | 4 | #include "System/Common.h" 5 | #include "System/Events/Timer.h" 6 | #include "Framework/Transport/TransportUDPWriter.h" 7 | #include "PLeaseMsg.h" 8 | #include "PLeaseState.h" 9 | 10 | class PLeaseLearner 11 | { 12 | typedef MFunc Func; 13 | typedef PLeaseLearnerState State; 14 | 15 | public: 16 | PLeaseLearner(); 17 | 18 | void Init(bool useSoftClock_); 19 | 20 | void ProcessMsg(PLeaseMsg &msg); 21 | void OnLeaseTimeout(); 22 | bool IsLeaseOwner(); 23 | bool IsLeaseKnown(); 24 | int GetLeaseOwner(); 25 | uint64_t GetLeaseEpoch(); 26 | void SetOnLearnLease(Callable* onLearnLeaseCallback_); 27 | void SetOnLeaseTimeout(Callable* onLeaseTimeoutCallback_); 28 | 29 | private: 30 | void OnLearnChosen(); 31 | void CheckLease(); 32 | 33 | Func onLeaseTimeout; 34 | Timer leaseTimeout; 35 | PLeaseMsg msg; 36 | State state; 37 | Callable* onLearnLeaseCallback; 38 | Callable* onLeaseTimeoutCallback; 39 | bool useSoftClock; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/genindex-split.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 |

{{ _('Index pages by letter') }}:

8 | 9 |

{% for key, dummy in genindexentries -%} 10 | {{ key }} 11 | {% if not loop.last %}| {% endif %} 12 | {%- endfor %}

13 | 14 |

{{ _('Full index on one page') }} 15 | ({{ _('can be huge') }})

16 | 17 | {% endblock %} 18 | 19 | {% block sidebarrel %} 20 | {% if split_index %} 21 |

Index

22 |

{% for key, dummy in genindexentries -%} 23 | {{ key }} 24 | {% if not loop.last %}| {% endif %} 25 | {%- endfor %}

26 | 27 |

{{ _('Full index on one page') }}

28 | {% endif %} 29 | {{ super() }} 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /src/System/Time_Windows.cpp: -------------------------------------------------------------------------------- 1 | #ifdef PLATFORM_WINDOWS 2 | 3 | #include "Platform.h" 4 | #include 5 | 6 | /* 7 | static int gettimeofday (struct timeval *tv, void* tz) 8 | { 9 | DYNAMIC_TIME_ZONE_INFORMATION dtzInfo; 10 | DWORD tzId; 11 | LONG bias; 12 | union { 13 | LONGLONG ns100; //time since 1 Jan 1601 in 100ns units 14 | FILETIME ft; 15 | } now; 16 | 17 | bias = 0; 18 | tzId = GetDynamicTimeZoneInformation(&dtzInfo); 19 | if (tzId == TIME_ZONE_ID_STANDARD) 20 | bias = dtzInfo.Bias + dtzInfo.StandardBias; 21 | else if (tzId = TIME_ZONE_ID_DAYLIGHT) 22 | bias = dtzInfo.Bias + dtzInfo.DaylightBias; 23 | 24 | GetSystemTimeAsFileTime (&now.ft); 25 | tv->tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); 26 | tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL - bias * 60); 27 | return (0); 28 | } 29 | */ 30 | 31 | uint64_t Now() 32 | { 33 | return GetMilliTimestamp(); 34 | } 35 | 36 | uint64_t NowMicro() 37 | { 38 | return GetMicroTimestamp(); 39 | } 40 | 41 | void MSleep(unsigned long msec) 42 | { 43 | Sleep(msec); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/Framework/Database/Database.h: -------------------------------------------------------------------------------- 1 | #ifndef DATABASE_H 2 | #define DATABASE_H 3 | 4 | #include 5 | #include "System/Common.h" 6 | #include "System/ThreadPool.h" 7 | #include "System/Events/Timer.h" 8 | #include "System/Events/Callable.h" 9 | #include "DatabaseConfig.h" 10 | 11 | class Table; 12 | class Transaction; 13 | 14 | class Database 15 | { 16 | friend class Table; 17 | friend class Transaction; 18 | typedef MFunc Func; 19 | 20 | public: 21 | Database(); 22 | ~Database(); 23 | 24 | bool Init(const DatabaseConfig& config); 25 | void Shutdown(); 26 | 27 | Table* GetTable(const char* name); 28 | 29 | void OnCheckpointTimeout(); 30 | void Checkpoint(); 31 | 32 | private: 33 | DatabaseConfig config; 34 | DbEnv* env; 35 | Table* keyspace; 36 | ThreadPool* cpThread; 37 | bool running; 38 | Func checkpoint; 39 | CdownTimer checkpointTimeout; 40 | Func onCheckpointTimeout; 41 | }; 42 | 43 | void WarmCache(char* dbPath, unsigned cacheSize); 44 | 45 | // global 46 | extern Database database; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupReader.h: -------------------------------------------------------------------------------- 1 | #ifndef CATCHUPCLIENT_H 2 | #define CATCHUPCLIENT_H 3 | 4 | #include "Framework/Transport/MessageConn.h" 5 | #include "Framework/Database/Table.h" 6 | #include "Framework/Database/Transaction.h" 7 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 8 | #include "CatchupMsg.h" 9 | 10 | #define CATCHUP_CONNECT_TIMEOUT 2000 11 | #define CATCHUP_COMMIT_GRANULARITY 1000 12 | 13 | class ReplicatedKeyspaceDB; 14 | 15 | class CatchupReader : public MessageConn<> 16 | { 17 | public: 18 | void Init(ReplicatedKeyspaceDB* keyspaceDB_, Table* table_); 19 | void Shutdown(); 20 | 21 | void Start(unsigned nodeID); 22 | void OnMessageRead(const ByteString& message); 23 | void OnClose(); 24 | virtual void OnConnect(); 25 | virtual void OnConnectTimeout(); 26 | 27 | private: 28 | void ProcessMsg(); 29 | void OnKeyValue(); 30 | void OnCommit(); 31 | 32 | Table* table; 33 | CatchupMsg msg; 34 | uint64_t paxosID; 35 | Transaction transaction; 36 | uint64_t count; // experimental 37 | ReplicatedKeyspaceDB* keyspaceDB; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Database/KeyspaceMsg.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACEMSG_H 2 | #define KEYSPACEMSG_H 3 | 4 | #include "System/Buffer.h" 5 | #include "KeyspaceConsts.h" 6 | 7 | #define KEYSPACE_SET 's' 8 | #define KEYSPACE_TEST_AND_SET 't' 9 | #define KEYSPACE_ADD 'a' 10 | #define KEYSPACE_DELETE 'd' 11 | #define KEYSPACE_PRUNE 'p' 12 | #define KEYSPACE_RENAME 'e' 13 | #define KEYSPACE_REMOVE 'r' 14 | #define KEYSPACE_SET_EXPIRY 'x' 15 | #define KEYSPACE_EXPIRE 'y' 16 | #define KEYSPACE_REMOVE_EXPIRY 'z' 17 | #define KEYSPACE_CLEAR_EXPIRIES 'w' 18 | class KeyspaceOp; 19 | 20 | class KeyspaceMsg 21 | { 22 | typedef ByteArray KeyBuffer; 23 | typedef ByteArray ValBuffer; 24 | public: 25 | char type; 26 | KeyBuffer key; 27 | KeyBuffer newKey; 28 | ValBuffer value; 29 | ValBuffer test; 30 | ValBuffer prefix; 31 | int64_t num; 32 | uint64_t prevExpiryTime; 33 | uint64_t nextExpiryTime; 34 | 35 | void Init(char type_); 36 | 37 | bool Read(ByteString& data, unsigned &nread); 38 | bool Write(ByteString& data); 39 | 40 | bool FromKeyspaceOp(KeyspaceOp* op); 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Keyspace is a consistently replicated fault-tolerant key-value store. 5 | Keyspace is a product of Scalien, the official homepage is at 6 | 7 | http://scalien.com 8 | 9 | You can reach us at info@scalien.com or http://twitter.com/scalien . 10 | We would like to hear about you! 11 | 12 | 13 | 14 | Setting up and running 15 | ====================== 16 | 17 | For detailed instructions about setting up and running Keyspace, 18 | see the INSTALL file. 19 | 20 | 21 | 22 | Licensing 23 | ========= 24 | 25 | Keyspace is licensed under the open-source Affero GPL license. 26 | For more more information see the LICENSE file. 27 | 28 | Some versions of Keyspace (e. g. Windows) includes BerkeleyDB 29 | include and header files. The licensing of the BerkeleyDB can 30 | be found in lib/LICENSE.txt. 31 | 32 | For custom licensing please contact info@scalien.com . 33 | 34 | 35 | 36 | Contact 37 | ======= 38 | 39 | If you are experiencing difficulties please visit our Google Groups page: 40 | 41 | - group home page: http://groups.google.com/group/keyspace 42 | - group email address: keyspace@googlegroups.com 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/Application/EchoServer/UDPEchoServer.cpp: -------------------------------------------------------------------------------- 1 | #include "UDPEchoServer.h" 2 | #include "System/Log.h" 3 | #include 4 | 5 | UDPEchoServer::UDPEchoServer() : 6 | onRead(this, &UDPEchoServer::OnRead), 7 | onWrite(this, &UDPEchoServer::OnWrite) 8 | { 9 | } 10 | 11 | bool UDPEchoServer::Init(IOProcessor* ioproc_, Scheduler* scheduler_) 12 | { 13 | ioproc = ioproc_; 14 | scheduler = scheduler_; 15 | 16 | socket.Create(Socket::UDP); 17 | socket.Bind(UDPECHOSERVER_PORT); 18 | socket.SetNonblocking(); 19 | Log_Trace("Bound to socket %d", socket.fd); 20 | 21 | udpread.fd = socket.fd; 22 | udpread.data = data; 23 | udpread.onComplete = &onRead; 24 | 25 | udpwrite.fd = socket.fd; 26 | udpwrite.data = data; 27 | udpwrite.onComplete = &onWrite; 28 | 29 | return ioproc->Add(&udpread); 30 | } 31 | 32 | void UDPEchoServer::OnRead() 33 | { 34 | Log_Trace(); 35 | 36 | udpread.data.buffer[udpread.data.length] = '\0'; 37 | 38 | udpwrite.data.length = udpread.data.length; 39 | udpwrite.endpoint = udpread.endpoint; 40 | ioproc->Add(&udpwrite); 41 | } 42 | 43 | void UDPEchoServer::OnWrite() 44 | { 45 | Log_Trace(); 46 | 47 | ioproc->Add(&udpread); 48 | } 49 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpConn.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_CONN_H 2 | #define HTTP_CONN_H 3 | 4 | #include "Framework/Transport/TCPConn.h" 5 | #include "HttpRequest.h" 6 | #include "Application/Keyspace/Database/KeyspaceDB.h" 7 | #include "Application/Keyspace/Database/KeyspaceService.h" 8 | 9 | class HttpServer; 10 | 11 | class HttpConn : public TCPConn<> 12 | { 13 | public: 14 | HttpConn(); 15 | 16 | void Init(HttpServer* server_); 17 | void SetOnClose(Callable* callable); 18 | 19 | void Print(const char* s); 20 | void Response(int code, const char* buf, 21 | int len, const char* header = NULL); 22 | void ResponseHeader(int code, const char* header = NULL); 23 | void Flush(); 24 | 25 | HttpServer* GetServer() { return server; } 26 | 27 | // TCPConn interface 28 | virtual void OnRead(); 29 | virtual void OnClose(); 30 | virtual void OnWrite(); 31 | 32 | protected: 33 | Callable* onCloseCallback; 34 | HttpServer* server; 35 | HttpRequest request; 36 | Endpoint endpoint; 37 | bool closeAfterSend; 38 | 39 | int Parse(char* buf, int len); 40 | int ProcessGetRequest(); 41 | const char* Status(int code); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/Application/HTTP/UrlParam.h: -------------------------------------------------------------------------------- 1 | #ifndef URL_PARAM_H 2 | #define URL_PARAM_H 3 | 4 | #include "System/Buffer.h" 5 | 6 | // helper function for parsing url strings, does *not* do url decoding! 7 | bool UrlParam_Parse(const char* url, char sep, unsigned num, /* ByteString* arg1, ByteString* arg2, */...); 8 | 9 | // this class does url decoding 10 | class UrlParam 11 | { 12 | public: 13 | UrlParam(); 14 | 15 | bool Init(const char* url, char sep); 16 | 17 | int GetNumParams() const; 18 | 19 | const char* GetParam(int nparam) const; 20 | int GetParamLen(int nparam) const; 21 | 22 | int GetParamIndex(const char* name, int namelen = -1) const; 23 | 24 | bool Get(unsigned num, /* ByteString* */...) const; 25 | bool GetNamed(const char* name, int namelen, ByteString& bs) const; 26 | 27 | private: 28 | const char* url; 29 | char sep; 30 | DynArray<32> params; 31 | DynArray<32> buffer; 32 | int numParams; 33 | 34 | bool Parse(); 35 | void AddParam(const char* s, int length); 36 | 37 | static char DecodeChar(const char* s); 38 | static char HexToChar(char uhex, char lhex); 39 | static char HexdigitToChar(char hexdigit); 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/Framework/Database/Transaction.cpp: -------------------------------------------------------------------------------- 1 | #include "Transaction.h" 2 | 3 | Transaction::Transaction() 4 | { 5 | active = false; 6 | database = NULL; 7 | } 8 | 9 | Transaction::Transaction(Database* database_) 10 | { 11 | active = false; 12 | database = database_; 13 | } 14 | 15 | Transaction::Transaction(Table* table) 16 | { 17 | active = false; 18 | database = table->database; 19 | } 20 | 21 | void Transaction::Set(Database* database_) 22 | { 23 | database = database_; 24 | } 25 | 26 | void Transaction::Set(Table* table) 27 | { 28 | database = table->database; 29 | } 30 | 31 | bool Transaction::IsActive() 32 | { 33 | return active; 34 | } 35 | 36 | bool Transaction::Begin() 37 | { 38 | Log_Trace(); 39 | 40 | if (database->env->txn_begin(NULL, &txn, 0) != 0) 41 | return false; 42 | 43 | active = true; 44 | return true; 45 | } 46 | 47 | bool Transaction::Commit() 48 | { 49 | Log_Trace(); 50 | 51 | active = false; 52 | 53 | if (txn->commit(0) != 0) 54 | return false; 55 | 56 | return true; 57 | } 58 | 59 | bool Transaction::Rollback() 60 | { 61 | Log_Trace(); 62 | 63 | active = false; 64 | 65 | if (txn->abort() != 0) 66 | return false; 67 | 68 | return true; 69 | } 70 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportTCPReader.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPORTTCPREADER_H 2 | #define TRANSPORTTCPREADER_H 3 | 4 | #include "Transport.h" 5 | #include "TCPServer.h" 6 | #include "MessageConn.h" 7 | 8 | class TransportTCPReader; // forward 9 | 10 | class TransportTCPConn : public MessageConn 11 | { 12 | public: 13 | TransportTCPConn(TransportTCPReader* reader_) 14 | { 15 | reader = reader_; 16 | } 17 | 18 | void OnMessageRead(const ByteString& message); 19 | void OnClose(); 20 | 21 | private: 22 | TransportTCPReader* reader; 23 | }; 24 | 25 | 26 | class TransportTCPReader : public TCPServer 27 | { 28 | friend class TransportTCPConn; 29 | typedef List ConnsList; 30 | 31 | public: 32 | ~TransportTCPReader(); 33 | 34 | bool Init(int port); 35 | 36 | void SetOnRead(Callable* onRead); 37 | void GetMessage(ByteString& msg_); 38 | void Stop(); 39 | void Continue(); 40 | bool IsActive(); 41 | void OnConnect(); 42 | void OnConnectionClose(TransportTCPConn* conn); 43 | 44 | private: 45 | void SetMessage(ByteString msg_); 46 | 47 | Callable* onRead; 48 | ByteString msg; 49 | ConnsList conns; 50 | bool running; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Makefile.Darwin: -------------------------------------------------------------------------------- 1 | # 2 | # Scalien Makefile for Darwin (OSX) 3 | # 4 | 5 | INCLUDE = \ 6 | -I$(KEYSPACE_DIR)/src \ 7 | -I/usr/local/include/db4 \ 8 | -I/usr/local/include/db42 \ 9 | -I/usr/local/include/db43 \ 10 | -I/usr/local/include/db44 \ 11 | -I/usr/local/include/db45 \ 12 | -I/usr/local/include/db46 \ 13 | -I/usr/local/include/db47 \ 14 | -I/usr/local/include/db48 \ 15 | -I/opt/local/include/db46 \ 16 | 17 | LDPATH = \ 18 | -L/usr/local/lib/db4 \ 19 | -L/usr/local/lib/db42 \ 20 | -L/usr/local/lib/db43 \ 21 | -L/usr/local/lib/db44 \ 22 | -L/usr/local/lib/db45 \ 23 | -L/usr/local/lib/db46 \ 24 | -L/usr/local/lib/db47 \ 25 | -L/usr/local/lib/db48 \ 26 | -L/opt/local/lib/db46 \ 27 | 28 | BASE_CFLAGS = -Wall $(INCLUDE) -DPLATFORM_$(PLATFORM_UCASE) -D__STDC_FORMAT_MACROS 29 | BASE_CXXFLAGS = $(BASE_CFLAGS) 30 | BASE_LDFLAGS = -lpthread -ldb_cxx $(LDPATH) 31 | 32 | ifeq ($(shell uname),Darwin) 33 | SOLINK = -Xlinker -x -fPIC -dylib -undefined dynamic_lookup -bundle 34 | SOEXT = dylib 35 | SWIG_LDFLAGS = -bundle -flat_namespace -undefined suppress 36 | BUNDLEEXT = bundle 37 | else 38 | SOLINK = -shared -fPIC -Wl,-soname,$(SONAME) 39 | SOEXT = so 40 | SWIG_LDFLAGS = -shared -fPIC 41 | BUNDLEEXT = so 42 | endif -------------------------------------------------------------------------------- /src/Framework/Paxos/PaxosLearner.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOSLEARNER_H 2 | #define PAXOSLEARNER_H 3 | 4 | #include "System/Common.h" 5 | #include "Framework/Transport/TransportTCPWriter.h" 6 | #include "Framework/AsyncDatabase/AsyncDatabase.h" 7 | #include "Framework/Database/Transaction.h" 8 | #include "PaxosMsg.h" 9 | #include "PaxosState.h" 10 | #include "Framework/ReplicatedLog/ReplicatedConfig.h" 11 | 12 | class PaxosLearner 13 | { 14 | friend class ReplicatedLog; 15 | typedef TransportTCPWriter** Writers; 16 | typedef PaxosLearnerState State; 17 | 18 | protected: 19 | PaxosLearner(); 20 | 21 | void Init(TransportTCPWriter** writers_); 22 | 23 | bool RequestChosen(unsigned nodeID); 24 | bool SendChosen(unsigned nodeID, 25 | uint64_t paxosID, 26 | ByteString& value); 27 | bool SendStartCatchup(unsigned nodeID, 28 | uint64_t paxosID); 29 | bool Learned(); 30 | ByteString Value(); 31 | 32 | protected: 33 | void OnLearnChosen(PaxosMsg& msg_); 34 | void OnRequestChosen(PaxosMsg& msg_); 35 | 36 | Writers writers; 37 | ByteBuffer wdata; 38 | uint64_t paxosID; 39 | PaxosMsg msg; 40 | State state; 41 | uint64_t lastRequestChosenTime; 42 | uint64_t lastRequestChosenPaxosID; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/Test/UDPTestClient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | struct sockaddr_in to, me; 13 | int s, slen = sizeof(to); 14 | 15 | if (argc != 4) 16 | { 17 | fprintf(stderr, "Usage: %s \n", argv[0]); 18 | return 1; 19 | } 20 | 21 | int from_port = atoi(argv[1]); 22 | int to_port = atoi(argv[2]); 23 | 24 | char* msg = argv[3]; 25 | int msglen = strlen(msg); 26 | 27 | if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 28 | exit(1); 29 | 30 | memset((char *) &me, 0, sizeof(me)); 31 | me.sin_family = AF_INET; 32 | me.sin_port = htons((uint16_t)from_port); 33 | me.sin_addr.s_addr = htonl(INADDR_ANY); 34 | if (bind(s, (const struct sockaddr*) &me, sizeof(me)) < 0) 35 | exit(1); 36 | 37 | memset((char *) &to, 0, sizeof(to)); 38 | to.sin_family = AF_INET; 39 | to.sin_port = htons(to_port); 40 | if (inet_aton("127.0.0.1", &to.sin_addr) == 0) 41 | exit(1); 42 | 43 | if (sendto(s, msg, msglen, 0, (const struct sockaddr*) &to, slen) < 0) 44 | exit(1); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/Application/Console/Console.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_H 2 | #define CONSOLE_H 3 | 4 | #include "Framework/Transport/TCPServer.h" 5 | 6 | #define CONSOLE_SIZE 256 7 | 8 | class Console; 9 | 10 | class ConsoleConn : public TCPConn 11 | { 12 | public: 13 | void Init(Console* console); 14 | void Disconnect(); 15 | 16 | private: 17 | Console* console; 18 | char endpointString[ENDPOINT_STRING_SIZE]; 19 | 20 | // TCPConn interface 21 | virtual void OnClose(); 22 | virtual void OnRead(); 23 | virtual void OnWrite(); 24 | 25 | void WritePrompt(); 26 | }; 27 | 28 | class ConsoleCommand 29 | { 30 | public: 31 | ConsoleCommand *nextConsoleCommand; 32 | 33 | virtual ~ConsoleCommand() {} 34 | 35 | virtual void Execute(const char *cmd, 36 | const char* args, ConsoleConn *conn) = 0; 37 | }; 38 | 39 | class Console : public TCPServerT 40 | { 41 | public: 42 | void Init(int port); 43 | void Execute(const char* cmd, 44 | const char* args, ConsoleConn *conn); 45 | void RegisterCommand(ConsoleCommand* command); 46 | 47 | private: 48 | typedef Queue 49 | CommandQueue; 50 | 51 | CommandQueue commands; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClientTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | using Keyspace; 6 | 7 | namespace KeyspaceClientTest 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | string[] nodes = { "localhost:7080" }; 14 | Client client = new Client(nodes); 15 | //client.Set("hol", "peru"); 16 | //string hol = client.Get("hol"); 17 | //Console.WriteLine(hol); 18 | 19 | //List keys = client.ListKeys("", "", 0, false, true); 20 | //foreach (string key in keys) 21 | // Console.WriteLine(key); 22 | 23 | //Dictionary keyValues = client.ListKeyValues("", "", 0, false, true); 24 | //foreach (KeyValuePair keyValue in keyValues) 25 | // Console.WriteLine(keyValue.Key + ", " + keyValue.Value); 26 | 27 | client.Prune(""); 28 | client.ClearExpiries(); 29 | 30 | // client.Set("a1", "b1"); 31 | client.SetExpiry("a1", 1); 32 | client.ClearExpiries(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Test/AsyncDBTest.cpp: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "System/Buffer.h" 3 | #include "System/IO/IOProcessor.h" 4 | #include "System/Events/EventLoop.h" 5 | #include "Framework/Database/Database.h" 6 | #include "Framework/Database/Transaction.h" 7 | #include "Framework/AsyncDatabase/AsyncDatabase.h" 8 | #include "Time.h" 9 | 10 | Database db; 11 | AsyncDatabase writer(1); 12 | MultiDatabaseOp dbop; 13 | long start; 14 | 15 | #define NUM 1 16 | #define NUMPUT 10000 17 | 18 | void cb() 19 | { 20 | TEST_LOG("callback"); 21 | 22 | long elapsed = Now() - start; 23 | printf("%d transactions took %ld msec *** %f tps\n", 24 | NUM, elapsed, (double)1000*NUM/elapsed); 25 | 26 | } 27 | 28 | CFunc callable(&cb); 29 | 30 | int test() 31 | { 32 | IOProcessor::Init(); 33 | 34 | 35 | Table* table = db.GetTable("test"); 36 | Transaction tx(table); 37 | 38 | ByteArray<32> key("hol"); 39 | ByteArray<32> value("peru"); 40 | 41 | dbop.SetCallback(&callable); 42 | 43 | for (int j = 0; j < NUMPUT; j++) 44 | { 45 | bool ret = dbop.Set(table, key, value); 46 | if (!ret) 47 | TEST_LOG("false"); 48 | } 49 | 50 | dbop.SetTransaction(&tx); 51 | 52 | start = Now(); 53 | 54 | writer.Add(&dbop); 55 | 56 | EventLoop::Run(); 57 | 58 | return TEST_SUCCESS; 59 | } 60 | 61 | TEST_MAIN(test); 62 | -------------------------------------------------------------------------------- /src/Test/UDPEchoClient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | struct sockaddr_in me, from, to; 13 | int s, i, nread, slen = sizeof(to); 14 | char buf[512]; 15 | 16 | if (( s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 17 | exit(1); 18 | 19 | memset((char *) &me, 0, sizeof(me)); 20 | me.sin_family = AF_INET; 21 | me.sin_port = htons((uint16_t)20066); 22 | me.sin_addr.s_addr = htonl(INADDR_ANY); 23 | if (bind(s, (const sockaddr*) &me, sizeof(me)) < 0) 24 | exit(1); 25 | 26 | memset((char *) &to, 0, sizeof(to)); 27 | to.sin_family = AF_INET; 28 | to.sin_port = htons(4000); 29 | if (inet_aton("127.0.0.1", &to.sin_addr) == 0) 30 | exit(1); 31 | 32 | for (i = 0; i < 3; i++) 33 | { 34 | sprintf(buf, "Message %d", i); 35 | if (sendto(s, buf, strlen(buf), 0, (const sockaddr*) &to, slen) < 0) 36 | exit(1); 37 | 38 | slen = sizeof(from); 39 | if ((nread = recvfrom(s, buf, sizeof(buf), 0, (sockaddr*) &from, (socklen_t*) &slen)) < 0) 40 | exit(1); 41 | buf[nread] = '\0'; 42 | printf("Message from %s:%d: %s\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port), buf); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Application/Fuse/Channel.cpp: -------------------------------------------------------------------------------- 1 | #include "System/Common.h" 2 | #include "Channel.h" 3 | 4 | Channel::Channel() 5 | { 6 | sending = true; 7 | receiving = false; 8 | 9 | pthread_mutex_init(&send_mutex, NULL); 10 | pthread_cond_init(&send_cond, NULL); 11 | 12 | pthread_mutex_init(&recv_mutex, NULL); 13 | pthread_cond_init(&recv_cond, NULL); 14 | } 15 | 16 | int Channel::Send(const char* buf_, int count_) 17 | { 18 | pthread_mutex_lock(&send_mutex); 19 | while (!sending) 20 | pthread_cond_wait(&send_cond, &send_mutex); 21 | 22 | buf = buf_; 23 | count = count_; 24 | 25 | sending = false; 26 | pthread_mutex_lock(&send_mutex); 27 | 28 | pthread_mutex_lock(&recv_mutex); 29 | receiving = true; 30 | pthread_cond_signal(&recv_cond); 31 | pthread_mutex_lock(&recv_mutex); 32 | 33 | return count; 34 | } 35 | 36 | int Channel::Receive(char* buf_, int count_) 37 | { 38 | pthread_mutex_lock(&recv_mutex); 39 | while (!receiving) 40 | pthread_cond_wait(&recv_cond, &recv_mutex); 41 | 42 | count_ = min(count, count_); 43 | memcpy(buf_, this->buf, count_); 44 | receiving = false; 45 | 46 | pthread_mutex_unlock(&recv_mutex); 47 | 48 | pthread_mutex_lock(&send_mutex); 49 | sending = true; 50 | pthread_cond_signal(&send_cond); 51 | pthread_mutex_unlock(&send_mutex); 52 | 53 | return count_; 54 | } 55 | -------------------------------------------------------------------------------- /test/concurrency/common.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import sys 4 | 5 | num = 1000 6 | print_granularity = 1000 7 | 8 | count = 0 9 | first = True 10 | start = 0 11 | gran_start = 0 12 | min = 0 13 | max = 0 14 | avg = 0 15 | sum = 0 16 | total = 0 17 | 18 | def set_print_granularity(p): 19 | global print_granularity 20 | print_granularity = p 21 | print("%s: print granularity = %s" % (sys.argv[0], print_granularity)) 22 | 23 | def loop_count(): 24 | global min, max, avg, total, gran_start, sum, start, first, count 25 | now = round(time.time() * 1000) 26 | if not first: 27 | elapsed = now - start 28 | if elapsed < min: min = elapsed 29 | if elapsed > max: max = elapsed 30 | sum = sum + elapsed 31 | start = now 32 | count = count + 1 33 | total = total + 1 34 | if count % print_granularity == 0 and not first: 35 | gran_elapsed = now - gran_start 36 | gran_start = now 37 | avg = sum / print_granularity 38 | print("%s: last %s run stats in msec \t\t elapsed = %s \t min = %s \t max = %s \t avg = %s \t\t total loops = %s" % (sys.argv[0], print_granularity, sum, min, max, avg, total)) 39 | # sys.stdout.write("-") 40 | # sys.stdout.flush() 41 | if first or count % print_granularity == 0: 42 | gran_start = now 43 | min = 10e10 44 | max = -10e10 45 | avg = 0 46 | sum = 0 47 | first = False 48 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpRequest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "HttpRequest.h" 3 | 4 | #define CR 13 5 | #define LF 10 6 | 7 | void HttpRequest::Init() 8 | { 9 | state = REQUEST_LINE; 10 | pos = 0; 11 | contentLength = -1; 12 | header.Init(); 13 | } 14 | 15 | void HttpRequest::Free() 16 | { 17 | header.Free(); 18 | } 19 | 20 | int HttpRequest::Parse(char* buf, int len) 21 | { 22 | int reqPos; 23 | int headPos; 24 | const char* cl; 25 | 26 | if (state == REQUEST_LINE) 27 | { 28 | reqPos = line.Parse(buf, len, 0); 29 | if (reqPos < 0) 30 | return 0; 31 | 32 | pos = reqPos; 33 | state = HEADER; 34 | } 35 | 36 | if (state == HEADER) 37 | { 38 | headPos = header.Parse(buf, len, pos); 39 | if (headPos < 0) 40 | return -1; 41 | if (headPos >= len) 42 | return -1; 43 | 44 | pos = headPos; 45 | if (buf[pos] == CR && buf[pos + 1] == LF) 46 | { 47 | state = CONTENT; 48 | pos += 2; 49 | } 50 | else 51 | return pos; 52 | } 53 | 54 | if (state == CONTENT) 55 | { 56 | if (contentLength < 0) 57 | { 58 | cl = header.GetField("content-length"); 59 | if (!cl) 60 | contentLength = 0; 61 | else 62 | contentLength = (int) strtol(cl, NULL, 10); 63 | 64 | pos += contentLength; 65 | } 66 | 67 | return pos; 68 | } 69 | 70 | return -1; 71 | } 72 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Memcache/MemcacheConn.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMCACHE_CONN_H 2 | #define MEMCACHE_CONN_H 3 | 4 | #include "System/Containers/List.h" 5 | #include "System/Events/Callable.h" 6 | #include "System/IO/Socket.h" 7 | #include "System/IO/IOOperation.h" 8 | #include "System/IO/IOProcessor.h" 9 | 10 | #include "Application/Keyspace/Database/KeyspaceDB.h" 11 | #include "Application/Keyspace/Database/KeyspaceService.h" 12 | 13 | class MemcacheServer; 14 | 15 | class MemcacheConn : public TCPConn<>, public KeyspaceService 16 | { 17 | public: 18 | void Init(MemcacheServer* server_, KeyspaceDB* kdb_); 19 | 20 | // TCPConn interface 21 | virtual void OnRead(); 22 | virtual void OnClose(); 23 | 24 | // KeyspaceService interface 25 | virtual void OnComplete(KeyspaceOp* op, bool status); 26 | 27 | private: 28 | class Token 29 | { 30 | public: 31 | const char* value; 32 | int len; 33 | }; 34 | 35 | MemcacheServer* server; 36 | const char* newline; 37 | 38 | int Tokenize(const char* data, int size, Token* tokens, int maxtokens); 39 | const char* Process(const char* data, int size); 40 | const char* ProcessGetCommand(const char* data, int size, Token* tokens, int numtoken); 41 | const char* ProcessSetCommand(const char* data, int size, Token* tokens, int numtoken); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/Framework/Paxos/PaxosAcceptor.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOSACCEPTOR_H 2 | #define PAXOSACCEPTOR_H 3 | 4 | #include "System/Common.h" 5 | #include "Framework/Transport/TransportTCPWriter.h" 6 | #include "Framework/AsyncDatabase/AsyncDatabase.h" 7 | #include "Framework/Database/Transaction.h" 8 | #include "PaxosMsg.h" 9 | #include "PaxosState.h" 10 | 11 | class PaxosAcceptor 12 | { 13 | friend class ReplicatedLog; 14 | typedef TransportTCPWriter** Writers; 15 | typedef PaxosAcceptorState State; 16 | typedef MFunc Func; 17 | public: 18 | PaxosAcceptor(); 19 | 20 | void Init(Writers writer_); 21 | void Shutdown(); 22 | bool Persist(Transaction* transaction); 23 | bool IsWriting() { return isWriting; } 24 | 25 | protected: 26 | bool WriteState(); 27 | bool ReadState(); 28 | void SendReply(unsigned nodeID); 29 | void OnPrepareRequest(PaxosMsg& msg_); 30 | void OnProposeRequest(PaxosMsg& msg_); 31 | void OnDBComplete(); 32 | 33 | Writers writers; 34 | ByteBuffer msgbuf; 35 | uint64_t paxosID; 36 | PaxosMsg msg; 37 | unsigned senderID; 38 | State state; 39 | Table* table; 40 | Transaction transaction; 41 | MultiDatabaseOp mdbop; 42 | ByteArray<128> buffers[4]; 43 | uint64_t writtenPaxosID; 44 | Func onDBComplete; 45 | bool isWriting; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/System/Events/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | 3 | static uint64_t now; 4 | static bool running; 5 | 6 | 7 | long EventLoop::RunTimers() 8 | { 9 | Timer** it; 10 | Timer* timer; 11 | uint64_t now; 12 | 13 | UpdateTime(); 14 | 15 | now = ::now; 16 | 17 | for (it = timers.Head(); it != NULL; it = timers.Head()) 18 | { 19 | timer = *it; 20 | 21 | UpdateTime(); 22 | 23 | if (timer->When() <= now) 24 | { 25 | Remove(timer); 26 | timer->Execute(); 27 | } 28 | else 29 | return timer->When() - now; 30 | } 31 | 32 | return -1; // no timers to wait for 33 | } 34 | 35 | bool EventLoop::RunOnce() 36 | { 37 | long sleep; 38 | 39 | sleep = RunTimers(); 40 | 41 | if (sleep < 0) 42 | sleep = SLEEP_MSEC; 43 | 44 | return IOProcessor::Poll(sleep); 45 | } 46 | 47 | void EventLoop::Run() 48 | { 49 | running = true; 50 | while(running) 51 | if (!RunOnce()) 52 | break; 53 | } 54 | 55 | void EventLoop::Init() 56 | { 57 | } 58 | 59 | void EventLoop::Shutdown() 60 | { 61 | Scheduler::Shutdown(); 62 | } 63 | 64 | uint64_t EventLoop::Now() 65 | { 66 | if (now == 0) 67 | UpdateTime(); 68 | 69 | return now; 70 | } 71 | 72 | void EventLoop::UpdateTime() 73 | { 74 | now = ::Now(); 75 | } 76 | 77 | void EventLoop::Stop() 78 | { 79 | running = false; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Catchup/CatchupMsg.cpp: -------------------------------------------------------------------------------- 1 | #include "CatchupMsg.h" 2 | 3 | void CatchupMsg::Init(char type_) 4 | { 5 | type = type_; 6 | } 7 | 8 | void CatchupMsg::KeyValue(ByteString& key_, ByteString& value_) 9 | { 10 | Init(CATCHUP_KEY_VALUE); 11 | key.Set(key_); 12 | value.Set(value_); 13 | } 14 | 15 | void CatchupMsg::Commit(uint64_t paxosID_) 16 | { 17 | Init(CATCHUP_COMMIT); 18 | paxosID = paxosID_; 19 | 20 | } 21 | 22 | bool CatchupMsg::Read(const ByteString& data) 23 | { 24 | int read; 25 | 26 | if (data.length < 1) 27 | return false; 28 | 29 | switch (data.buffer[0]) 30 | { 31 | case CATCHUP_KEY_VALUE: 32 | read = snreadf(data.buffer, data.length, "%c:%M:%M", 33 | &type, &key, &value); 34 | break; 35 | case CATCHUP_COMMIT: 36 | read = snreadf(data.buffer, data.length, "%c:%U", 37 | &type, &paxosID); 38 | break; 39 | default: 40 | return false; 41 | } 42 | 43 | return (read == (signed)data.length ? true : false); 44 | } 45 | 46 | bool CatchupMsg::Write(ByteString& data) 47 | { 48 | switch (type) 49 | { 50 | case CATCHUP_KEY_VALUE: 51 | return data.Writef("%c:%M:%M", 52 | type, &key, &value); 53 | break; 54 | case CATCHUP_COMMIT: 55 | return data.Writef("%c:%U", 56 | type, paxosID); 57 | break; 58 | default: 59 | return false; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Test/PaxosTester.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | struct sockaddr_in me, from, to; 13 | int s, i, nread, slen = sizeof(to); 14 | char buf[512]; 15 | 16 | if (argc != 2) 17 | exit(1); 18 | 19 | if (( s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 20 | exit(1); 21 | 22 | memset((char *) &me, 0, sizeof(me)); 23 | me.sin_family = AF_INET; 24 | me.sin_port = htons((uint16_t)11000); 25 | me.sin_addr.s_addr = htonl(INADDR_ANY); 26 | if (bind(s, (const sockaddr*) &me, sizeof(me)) < 0) 27 | exit(1); 28 | 29 | memset((char *) &to, 0, sizeof(to)); 30 | to.sin_family = AF_INET; 31 | to.sin_port = htons(10000); 32 | if (inet_aton("127.0.0.1", &to.sin_addr) == 0) 33 | exit(1); 34 | 35 | for (i = 0; i < 1; i++) 36 | { 37 | if (sendto(s, argv[1], strlen(argv[1]), 0, (const sockaddr*) &to, slen) < 0) 38 | exit(1); 39 | 40 | /* 41 | slen = sizeof(from); 42 | if ((nread = recvfrom(s, buf, sizeof(buf), 0, (sockaddr*) &from, (socklen_t*) &slen)) < 0) 43 | exit(1); 44 | buf[nread] = '\0'; 45 | printf("Message from %s:%d: %s\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port), buf); 46 | */ 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Application/HTTP/IMF.h: -------------------------------------------------------------------------------- 1 | #ifndef IMF_H 2 | #define IMF_H 3 | 4 | /* 5 | * Internet message format 6 | * RFC 2822 7 | * Suitable for parsing HTTP, SIP and MIME headers 8 | */ 9 | 10 | class IMFHeader 11 | { 12 | public: 13 | class KeyValue 14 | { 15 | public: 16 | int keyStart; 17 | int keyLength; 18 | int valueStart; 19 | int valueLength; 20 | }; 21 | 22 | class RequestLine 23 | { 24 | public: 25 | const char* method; 26 | int methodLen; 27 | const char* uri; 28 | int uriLen; 29 | const char* version; 30 | int versionLen; 31 | 32 | int Parse(char* buf, int len, int offs); 33 | }; 34 | 35 | class StatusLine 36 | { 37 | public: 38 | const char* version; 39 | int versionLen; 40 | const char* code; 41 | int codeLen; 42 | const char* reason; 43 | int reasonLen; 44 | 45 | int Parse(char* buf, int len, int offs); 46 | }; 47 | 48 | public: 49 | enum { KEYVAL_BUFFER_SIZE = 16 }; 50 | int numKeyval; 51 | int capKeyval; 52 | KeyValue* keyvalues; 53 | KeyValue keyvalBuffer[KEYVAL_BUFFER_SIZE]; 54 | char* data; 55 | 56 | IMFHeader(); 57 | ~IMFHeader(); 58 | 59 | void Init(); 60 | void Free(); 61 | int Parse(char* buf, int len, int offs); 62 | const char* GetField(const char* key); 63 | 64 | KeyValue* GetKeyValues(int newSize); 65 | }; 66 | 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/System/Containers/SortedList.h: -------------------------------------------------------------------------------- 1 | #ifndef SORTEDLIST_H 2 | #define SORTEDLIST_H 3 | 4 | #include "List.h" 5 | #include "System/Common.h" 6 | 7 | template 8 | class SortedList : public List 9 | { 10 | public: 11 | void Add(T t) 12 | { 13 | if (!Add(t, true)) 14 | ASSERT_FAIL(); // TODO: application-specific, 15 | // that's how we use SortedList<> 16 | } 17 | 18 | private: 19 | bool Add(T t, bool unique) 20 | { 21 | ListNode* node; 22 | ListNode** curr = &this->head; 23 | 24 | while(true) 25 | { 26 | if (*curr == NULL || LessThan(t, (*curr)->data)) { 27 | node = new ListNode; 28 | node->data = t; 29 | node->next = *curr; 30 | if (curr != &this->head) 31 | { 32 | node->prev = 33 | (ListNode*) 34 | ((char*)curr - offsetof(ListNode, next)); 35 | } 36 | else 37 | { 38 | node->prev = NULL; 39 | } 40 | if (*curr != NULL) 41 | (*curr)->prev = node; 42 | if (*curr == NULL) 43 | this->tail = node; 44 | *curr = node; 45 | this->length++; 46 | return true; 47 | } 48 | else 49 | { 50 | if (unique && (*curr)->data == t) 51 | return false; 52 | curr = &(*curr)->next; 53 | } 54 | } 55 | 56 | ASSERT_FAIL(); 57 | } 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClient/ListParam.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Keyspace 6 | { 7 | public class ListParam 8 | { 9 | public string prefix; 10 | public string startKey; 11 | public ulong count; 12 | public bool skip; 13 | public bool forward; 14 | 15 | public ListParam() 16 | { 17 | prefix = ""; 18 | startKey = ""; 19 | count = 0; 20 | skip = false; 21 | forward = true; 22 | } 23 | 24 | public ListParam SetPrefix(string prefix) 25 | { 26 | this.prefix = prefix; 27 | return this; 28 | } 29 | 30 | public ListParam SetStartKey(string startKey) 31 | { 32 | this.startKey = startKey; 33 | return this; 34 | } 35 | 36 | public ListParam SetCount(ulong count) 37 | { 38 | this.count = count; 39 | return this; 40 | } 41 | 42 | public ListParam SetSkip(bool skip) 43 | { 44 | this.skip = skip; 45 | return this; 46 | } 47 | 48 | public ListParam SetForward(bool forward) 49 | { 50 | this.forward = forward; 51 | return this; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseProposer.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASEPROPOSER_H 2 | #define PLEASEPROPOSER_H 3 | 4 | #include "System/Common.h" 5 | #include "System/Events/Timer.h" 6 | #include "Framework/Transport/TransportTCPWriter.h" 7 | #include "PLeaseConsts.h" 8 | #include "PLeaseMsg.h" 9 | #include "PLeaseState.h" 10 | 11 | class ReplicatedLog; 12 | 13 | class PLeaseProposer 14 | { 15 | typedef TransportTCPWriter** Writers; 16 | typedef MFunc Func; 17 | typedef PLeaseProposerState State; 18 | 19 | public: 20 | PLeaseProposer(); 21 | 22 | void Init(Writers writers_); 23 | 24 | void ProcessMsg(PLeaseMsg &msg_); 25 | void OnNewPaxosRound(); 26 | void OnAcquireLeaseTimeout(); 27 | void OnExtendLeaseTimeout(); 28 | void StartAcquireLease(); 29 | void StopAcquireLease(); 30 | 31 | uint64_t highestProposalID; 32 | 33 | private: 34 | void BroadcastMessage(); 35 | void OnPrepareResponse(); 36 | void OnProposeResponse(); 37 | void StartPreparing(); 38 | void StartProposing(); 39 | 40 | Writers writers; 41 | ByteBuffer wdata; 42 | State state; 43 | PLeaseMsg msg; 44 | Func onAcquireLeaseTimeout; 45 | CdownTimer acquireLeaseTimeout; 46 | Func onExtendLeaseTimeout; 47 | Timer extendLeaseTimeout; 48 | // keeping track of messages during prepare and propose phases 49 | unsigned numReceived; 50 | unsigned numAccepted; 51 | unsigned numRejected; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportUDPReader.cpp: -------------------------------------------------------------------------------- 1 | #include "TransportUDPReader.h" 2 | #include "System/IO/IOProcessor.h" 3 | #include "System/Events/EventLoop.h" 4 | 5 | TransportUDPReader::TransportUDPReader() : 6 | onRead(this, &TransportUDPReader::OnRead) 7 | { 8 | } 9 | 10 | bool TransportUDPReader::Init(int port) 11 | { 12 | bool ret; 13 | 14 | ret = true; 15 | ret &= socket.Create(Socket::UDP); 16 | ret &= socket.Bind(port); 17 | ret &= socket.SetNonblocking(); 18 | 19 | if (!ret) 20 | return false; 21 | 22 | udpread.fd = socket.fd; 23 | udpread.data.Set(data); 24 | udpread.onComplete = &onRead; 25 | 26 | return IOProcessor::Add(&udpread); 27 | } 28 | 29 | void TransportUDPReader::SetOnRead(Callable* onRead_) 30 | { 31 | userCallback = onRead_; 32 | } 33 | 34 | void TransportUDPReader::GetMessage(ByteString& bs) 35 | { 36 | bs.Set(udpread.data); 37 | } 38 | 39 | void TransportUDPReader::GetEndpoint(Endpoint& endpoint) 40 | { 41 | endpoint = udpread.endpoint; 42 | } 43 | 44 | void TransportUDPReader::Stop() 45 | { 46 | IOProcessor::Remove(&udpread); 47 | } 48 | 49 | void TransportUDPReader::Continue() 50 | { 51 | IOProcessor::Add(&udpread); 52 | } 53 | 54 | bool TransportUDPReader::IsActive() 55 | { 56 | return udpread.active; 57 | } 58 | 59 | void TransportUDPReader::OnRead() 60 | { 61 | Call(userCallback); 62 | 63 | udpread.data.Clear(); 64 | IOProcessor::Add(&udpread); 65 | } 66 | -------------------------------------------------------------------------------- /src/Framework/Database/DatabaseConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef DATABASE_CONFIG_H 2 | #define DATABASE_CONFIG_H 3 | 4 | #define DATABASE_CONFIG_DIR "." 5 | #define DATABASE_CONFIG_PAGE_SIZE 65536 6 | #define DATABASE_CONFIG_CACHE_SIZE 500*MB 7 | #define DATABASE_CONFIG_LOG_BUFFER_SIZE 250*MB 8 | #define DATABASE_CONFIG_LOG_MAX_FILE 0 9 | #define DATABASE_CONFIG_CHECKPOINT_TIMEOUT 60 10 | #define DATABASE_CONFIG_VERBOSE false 11 | 12 | #define DATABASE_CONFIG_DIRECT_DB true 13 | #define DATABASE_CONFIG_TXN_NOSYNC false 14 | #define DATABASE_CONFIG_TXN_WRITE_NOSYNC true 15 | 16 | class DatabaseConfig 17 | { 18 | public: 19 | DatabaseConfig() 20 | { 21 | dir = DATABASE_CONFIG_DIR; 22 | pageSize = DATABASE_CONFIG_PAGE_SIZE; 23 | cacheSize = DATABASE_CONFIG_CACHE_SIZE; 24 | logBufferSize = DATABASE_CONFIG_LOG_BUFFER_SIZE; 25 | logMaxFile = DATABASE_CONFIG_LOG_MAX_FILE; 26 | checkpointTimeout = DATABASE_CONFIG_CHECKPOINT_TIMEOUT; 27 | verbose = DATABASE_CONFIG_VERBOSE; 28 | 29 | directDB = DATABASE_CONFIG_DIRECT_DB; 30 | txnNoSync = DATABASE_CONFIG_TXN_NOSYNC; 31 | txnWriteNoSync = DATABASE_CONFIG_TXN_WRITE_NOSYNC; 32 | } 33 | 34 | const char* dir; 35 | int pageSize; 36 | int cacheSize; 37 | int logBufferSize; 38 | int logMaxFile; 39 | int checkpointTimeout; 40 | bool verbose; 41 | 42 | bool directDB; 43 | bool txnNoSync; 44 | bool txnWriteNoSync; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/changes/versionchanges.html: -------------------------------------------------------------------------------- 1 | {% macro entries(changes) %} 2 |
    {% for entry, docname, lineno in changes %} 3 |
  • {{ entry }}
  • 4 | {% endfor %}
5 | {% endmacro -%} 6 | 8 | 9 | 10 | 11 | 12 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 13 | 14 | 15 |
16 |
17 |

{% trans version=version|e %}Automatically generated list of changes in version {{ version }}{% endtrans %}

18 |

{{ _('Library changes') }}

19 | {% for modname, changes in libchanges %} 20 |

{{ modname }}

21 | {{ entries(changes) }} 22 | {% endfor %} 23 |

{{ _('C API changes') }}

24 | {{ entries(apichanges) }} 25 |

{{ _('Other changes') }}

26 | {% for (fn, title), changes in otherchanges %} 27 |

{{ title }} ({{ fn }})

28 | {{ entries(changes) }} 29 | {% endfor %} 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Framework/Paxos/PaxosState.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOSSTATE_H 2 | #define PAXOSSTATE_H 3 | 4 | #include 5 | #include "System/Buffer.h" 6 | #include "System/Platform.h" 7 | 8 | class PaxosProposerState 9 | { 10 | public: 11 | bool Active() 12 | { 13 | return (preparing || proposing); 14 | } 15 | 16 | void Init() 17 | { 18 | preparing = false; 19 | proposing = false; 20 | proposalID = 0; 21 | highestReceivedProposalID = 0; 22 | highestPromisedProposalID = 0; 23 | value.Clear(); 24 | leader = false; 25 | numProposals = 0; 26 | } 27 | 28 | public: 29 | bool preparing; 30 | bool proposing; 31 | uint64_t proposalID; 32 | uint64_t highestReceivedProposalID; 33 | uint64_t highestPromisedProposalID; 34 | ByteBuffer value; 35 | bool leader; // multi paxos 36 | unsigned numProposals; // number of proposal runs in this Paxos round 37 | }; 38 | 39 | class PaxosAcceptorState 40 | { 41 | public: 42 | void Init() 43 | { 44 | promisedProposalID = 0; 45 | accepted = false; 46 | acceptedProposalID = 0; 47 | acceptedValue.Clear(); 48 | } 49 | 50 | public: 51 | uint64_t promisedProposalID; 52 | bool accepted; 53 | uint64_t acceptedProposalID; 54 | ByteBuffer acceptedValue; 55 | 56 | }; 57 | 58 | class PaxosLearnerState 59 | { 60 | public: 61 | void Init() 62 | { 63 | learned = 0; 64 | value.Clear(); 65 | } 66 | 67 | public: 68 | bool learned; 69 | ByteBuffer value; 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/System/Events/Callable.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLABLE_H 2 | #define CALLABLE_H 3 | 4 | class Callable 5 | { 6 | public: 7 | virtual ~Callable() {} 8 | virtual void Execute() = 0; 9 | }; 10 | 11 | template 12 | class MFunc : public Callable 13 | { 14 | public: 15 | typedef void (T::*Callback)(); 16 | 17 | T* object; 18 | Callback callback; 19 | 20 | MFunc(T* object_, Callback callback_) 21 | { 22 | object = object_; 23 | callback = callback_; 24 | } 25 | 26 | void Execute() 27 | { 28 | (object->*callback)(); 29 | } 30 | }; 31 | 32 | template 33 | class MFuncParam : public Callable 34 | { 35 | public: 36 | typedef void (T::*Callback)(P param); 37 | 38 | T* object; 39 | Callback callback; 40 | P param; 41 | 42 | MFuncParam(T* object_, Callback callback_) 43 | { 44 | object = object_; 45 | callback = callback_; 46 | } 47 | 48 | void Execute() 49 | { 50 | (object->*callback)(param); 51 | } 52 | }; 53 | 54 | class CFunc : public Callable 55 | { 56 | public: 57 | typedef void (*Callback)(); 58 | 59 | Callback callback; 60 | 61 | CFunc(Callback callback_) 62 | { 63 | callback = callback_; 64 | } 65 | 66 | CFunc() 67 | { 68 | callback = 0; 69 | } 70 | 71 | void Execute() 72 | { 73 | if (callback) 74 | (*callback)(); 75 | } 76 | }; 77 | 78 | inline void Call(Callable* callable) 79 | { 80 | if (callable) 81 | callable->Execute(); 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/Framework/Paxos/PaxosProposer.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOSPROPOSER_H 2 | #define PAXOSPROPOSER_H 3 | 4 | #include "System/Common.h" 5 | #include "System/Events/Timer.h" 6 | #include "Framework/Transport/TransportTCPWriter.h" 7 | #include "PaxosMsg.h" 8 | #include "PaxosState.h" 9 | 10 | #define PAXOS_TIMEOUT 3000 // TODO: I increased this for testing 11 | 12 | class PaxosProposer 13 | { 14 | friend class ReplicatedLog; 15 | typedef TransportTCPWriter** Writers; 16 | typedef MFunc Func; 17 | typedef PaxosProposerState State; 18 | 19 | public: 20 | PaxosProposer(); 21 | 22 | void Init(TransportTCPWriter** writers_); 23 | 24 | void OnPrepareTimeout(); 25 | void OnProposeTimeout(); 26 | bool IsActive(); 27 | bool Propose(ByteString& value); 28 | void Stop(); 29 | 30 | protected: 31 | void BroadcastMessage(); 32 | void OnPrepareResponse(PaxosMsg& msg_); 33 | void OnProposeResponse(PaxosMsg& msg_); 34 | void StopPreparing(); 35 | void StopProposing(); 36 | void StartPreparing(); 37 | void StartProposing(); 38 | 39 | Writers writers; 40 | ByteBuffer wdata; 41 | State state; 42 | PaxosMsg msg; 43 | uint64_t paxosID; 44 | Func onPrepareTimeout; 45 | Func onProposeTimeout; 46 | CdownTimer prepareTimeout; 47 | CdownTimer proposeTimeout; 48 | // keeping track of messages during prepare and propose phases 49 | unsigned numReceived; 50 | unsigned numAccepted; 51 | unsigned numRejected; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/defindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Overview') %} 3 | {% block body %} 4 |

{{ docstitle|e }}

5 |

6 | Welcome! This is 7 | {% block description %}the documentation for {{ project|e }} 8 | {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}. 9 |

10 | {% block tables %} 11 |

{{ _('Indices and tables:') }}

12 | 13 | 24 |
14 | 16 | 18 | 19 | 21 | 23 |
25 | {% endblock %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/Test.java: -------------------------------------------------------------------------------- 1 | import com.scalien.keyspace.*; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Map; 6 | 7 | public class Test { 8 | public static void main(String[] args) { 9 | try { 10 | String[] nodes = {"127.0.0.1:7080"}; 11 | //Client.setTrace(true); 12 | Client ks = new Client(nodes); 13 | String hol = ks.get("hol"); 14 | System.out.println(hol); 15 | 16 | ArrayList keys = ks.listKeys("", "", 0, false, true); 17 | for (String key : keys) 18 | System.out.println(key); 19 | 20 | Map keyvals = ks.listKeyValues("", "", 0, false, true); 21 | for (String key : keyvals.keySet()) { 22 | String value = keyvals.get(key); 23 | System.out.println(key + " => " + value); 24 | } 25 | 26 | long cnt = ks.count(new ListParams().setLimit(100)); 27 | System.out.println(cnt); 28 | } catch (Exception e) { 29 | System.out.println(e.getMessage()); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClientTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleApplication1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleApplication1")] 13 | [assembly: AssemblyCopyright("Copyright © 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("17665c69-1df4-498d-9d87-371e3de94ece")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | [assembly: AssemblyVersion("1.0.0.0")] 33 | [assembly: AssemblyFileVersion("1.0.0.0")] 34 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Database/SingleKeyspaceDB.h: -------------------------------------------------------------------------------- 1 | #ifndef SINGLEKEYSPACEDB_H 2 | #define SINGLEKEYSPACEDB_H 3 | 4 | #include "Framework/Database/Database.h" 5 | #include "Framework/Database/Transaction.h" 6 | #include "KeyspaceDB.h" 7 | 8 | class SingleKeyspaceDB : public KeyspaceDB 9 | { 10 | typedef ByteArray KBuffer; 11 | typedef ByteArray VBuffer; 12 | typedef MFunc Func; 13 | typedef List OpList; 14 | 15 | public: 16 | SingleKeyspaceDB(); 17 | 18 | bool Init(); 19 | void InitExpiryTimer(); 20 | void Shutdown(); 21 | bool Add(KeyspaceOp* op) ; 22 | bool Submit(); 23 | unsigned GetNodeID() ; 24 | bool IsMasterKnown(); 25 | int GetMaster(); 26 | bool IsMaster(); 27 | bool IsReplicated() { return false; } 28 | void SetProtocolServer(ProtocolServer*) {} 29 | void Stop() {} 30 | void Continue() {} 31 | void OnExpiryTimer(); 32 | 33 | private: 34 | bool writePaxosID; 35 | KBuffer kdata; 36 | VBuffer vdata; 37 | Table* table; 38 | Transaction transaction; 39 | Func onExpiryTimer; 40 | Timer expiryTimer; 41 | OpList listOps; 42 | Func onListWorkerTimeout; 43 | CdownTimer listTimer; 44 | 45 | void ExecuteListWorkers(); 46 | void ExecuteListWorker(KeyspaceOp** it); 47 | void OnListWorkerTimeout(); 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/System/Log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H 2 | #define LOG_H 3 | 4 | #define LOG_TYPE_ERRNO 0 5 | #define LOG_TYPE_MSG 1 6 | #define LOG_TYPE_TRACE 2 7 | 8 | #define LOG_TARGET_NOWHERE 0 9 | #define LOG_TARGET_STDOUT 1 10 | #define LOG_TARGET_STDERR 2 11 | #define LOG_TARGET_FILE 4 12 | #define LOG_TARGET_SYSLOG 8 13 | 14 | #ifdef NO_LOGGING 15 | #define Log_Errno() 16 | #define Log_Message(...) 17 | #define Log_Trace(...) 18 | #else 19 | #ifdef _WIN32 20 | #define __func__ __FUNCTION__ 21 | #endif 22 | #define Log_Errno() Log(__FILE__, __LINE__, __func__, LOG_TYPE_ERRNO, "") 23 | #define Log_Message(...) Log(__FILE__, __LINE__, __func__, LOG_TYPE_MSG, __VA_ARGS__) 24 | #define Log_Trace(...) Log_Trace_("" __VA_ARGS__) 25 | #define Log_Trace_(...) Log(__FILE__, __LINE__, __func__, LOG_TYPE_TRACE, __VA_ARGS__) 26 | #endif 27 | 28 | #ifdef GCC 29 | #define ATTRIBUTE_FORMAT_PRINTF(fmt, ellipsis) __attribute__ ((format (printf, fmt, ellipsis))); 30 | #else 31 | #define ATTRIBUTE_FORMAT_PRINTF(fmt, ellipsis) 32 | #endif 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | void Log(const char* file, int line, const char* func, int type, const char* fmt, ...) ATTRIBUTE_FORMAT_PRINTF(5, 6); 39 | bool Log_SetTrace(bool trace); 40 | void Log_SetTimestamping(bool ts); 41 | void Log_SetMaxLine(int maxLine); 42 | void Log_SetTarget(int target); 43 | bool Log_SetOutputFile(const char* file, bool truncate); 44 | void Log_Shutdown(); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/System/Platform.cpp: -------------------------------------------------------------------------------- 1 | #include "Platform.h" 2 | 3 | #ifdef _WIN32 4 | #include 5 | #include 6 | #else 7 | #include 8 | #include 9 | #include 10 | #endif 11 | 12 | bool ChangeUser(const char *user) 13 | { 14 | #ifdef WIN32 15 | // cannot really do on Windows 16 | return true; 17 | #else 18 | if (user != NULL && *user && (getuid() == 0 || geteuid() == 0)) 19 | { 20 | struct passwd *pw = getpwnam(user); 21 | if (!pw) 22 | return false; 23 | 24 | setuid(pw->pw_uid); 25 | } 26 | 27 | return true; 28 | #endif 29 | } 30 | 31 | #ifdef WIN32 32 | 33 | int gettimeofday (struct timeval *tv, void* tz) 34 | { 35 | union { 36 | LONGLONG ns100; /*time since 1 Jan 1601 in 100ns units */ 37 | FILETIME ft; 38 | } now; 39 | 40 | GetSystemTimeAsFileTime (&now.ft); 41 | tv->tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); 42 | tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL); 43 | return (0); 44 | } 45 | 46 | #endif 47 | 48 | uint64_t GetMilliTimestamp() 49 | { 50 | uint64_t now; 51 | struct timeval tv; 52 | 53 | gettimeofday(&tv, NULL); 54 | 55 | now = tv.tv_sec; 56 | now *= 1000; 57 | now += tv.tv_usec / 1000; 58 | 59 | return now; 60 | } 61 | 62 | uint64_t GetMicroTimestamp() 63 | { 64 | uint64_t now; 65 | struct timeval tv; 66 | 67 | gettimeofday(&tv, NULL); 68 | 69 | now = tv.tv_sec; 70 | now *= 1000000; 71 | now += tv.tv_usec; 72 | 73 | return now; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceConn.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACECONN_H 2 | #define KEYSPACECONN_H 3 | 4 | #include "System/Containers/LinkedList.h" 5 | #include "Framework/Transport/MessageConn.h" 6 | #include "Application/Keyspace/Database/KeyspaceDB.h" 7 | #include "Application/Keyspace/Database/KeyspaceService.h" 8 | #include "Application/Keyspace/Protocol/Keyspace/KeyspaceClientReq.h" 9 | #include "Application/Keyspace/Protocol/Keyspace/KeyspaceClientResp.h" 10 | 11 | #define KEYSPACE_CONN_TIMEOUT 3000 12 | 13 | class KeyspaceServer; 14 | 15 | class KeyspaceConn : public MessageConn, 16 | public KeyspaceService 17 | { 18 | friend class KeyspaceServer; 19 | typedef MFunc Func; 20 | typedef ByteArray Buffer; 21 | public: 22 | KeyspaceConn(); 23 | 24 | void Init(KeyspaceDB* kdb_, KeyspaceServer* server_); 25 | 26 | // KeyspaceService interface 27 | virtual void OnComplete(KeyspaceOp* op, bool final); 28 | virtual bool IsAborted(); 29 | 30 | // TCPConn interface 31 | virtual void OnClose(); 32 | virtual void OnWrite(); 33 | virtual void OnMessageRead(const ByteString& message); 34 | 35 | private: 36 | 37 | void Write(ByteString &bs); 38 | void ProcessMsg(); 39 | void AppendOps(); 40 | 41 | Buffer data; 42 | KeyspaceServer* server; 43 | KeyspaceClientReq req; 44 | KeyspaceClientResp resp; 45 | bool closeAfterSend; 46 | char endpointString[ENDPOINT_STRING_SIZE]; 47 | unsigned bytesRead; 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/Status.java: -------------------------------------------------------------------------------- 1 | package com.scalien.keyspace; 2 | 3 | public class Status 4 | { 5 | public final static int KEYSPACE_SUCCESS = 0; 6 | public final static int KEYSPACE_API_ERROR = -1; 7 | 8 | public final static int KEYSPACE_PARTIAL = -101; 9 | public final static int KEYSPACE_FAILURE = -102; 10 | 11 | public final static int KEYSPACE_NOMASTER = -201; 12 | public final static int KEYSPACE_NOCONNECTION = -202; 13 | 14 | public final static int KEYSPACE_MASTER_TIMEOUT = -301; 15 | public final static int KEYSPACE_GLOBAL_TIMEOUT = -302; 16 | 17 | public final static int KEYSPACE_NOSERVICE = -401; 18 | public final static int KEYSPACE_FAILED = -402; 19 | 20 | public static String toString(int status) 21 | { 22 | switch (status) { 23 | case KEYSPACE_SUCCESS: 24 | return "KEYSPACE_SUCCESS"; 25 | case KEYSPACE_API_ERROR: 26 | return "KEYSPACE_API_ERROR"; 27 | case KEYSPACE_PARTIAL: 28 | return "KEYSPACE_PARTIAL"; 29 | case KEYSPACE_FAILURE: 30 | return "KEYSPACE_FAILURE"; 31 | case KEYSPACE_NOMASTER: 32 | return "KEYSPACE_NOMASTER"; 33 | case KEYSPACE_NOCONNECTION: 34 | return "KEYSPACE_NOCONNECTION"; 35 | case KEYSPACE_MASTER_TIMEOUT: 36 | return "KEYSPACE_MASTER_TIMEOUT"; 37 | case KEYSPACE_GLOBAL_TIMEOUT: 38 | return "KEYSPACE_GLOBAL_TIMEOUT"; 39 | case KEYSPACE_NOSERVICE: 40 | return "KEYSPACE_NOSERVICE"; 41 | case KEYSPACE_FAILED: 42 | return "KEYSPACE_FAILED"; 43 | } 44 | 45 | return ""; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/Result.java: -------------------------------------------------------------------------------- 1 | package com.scalien.keyspace; 2 | 3 | import java.util.TreeMap; 4 | 5 | public class Result 6 | { 7 | private SWIGTYPE_p_void cptr; 8 | 9 | public Result(SWIGTYPE_p_void cptr) { 10 | this.cptr = cptr; 11 | } 12 | 13 | public void finalize() { 14 | keyspace_client.Keyspace_ResultClose(cptr); 15 | } 16 | 17 | public String getKey() { 18 | return keyspace_client.Keyspace_ResultKey(cptr); 19 | } 20 | 21 | public String getValue() { 22 | return keyspace_client.Keyspace_ResultValue(cptr); 23 | } 24 | 25 | public void begin() { 26 | keyspace_client.Keyspace_ResultBegin(cptr); 27 | } 28 | 29 | public void next() { 30 | keyspace_client.Keyspace_ResultNext(cptr); 31 | } 32 | 33 | public boolean isEnd() { 34 | return keyspace_client.Keyspace_ResultIsEnd(cptr); 35 | } 36 | 37 | public int getTransportStatus() { 38 | return keyspace_client.Keyspace_ResultTransportStatus(cptr); 39 | } 40 | 41 | public int getConnectivityStatus() { 42 | return keyspace_client.Keyspace_ResultConnectivityStatus(cptr); 43 | } 44 | 45 | public int getTimeoutStatus() { 46 | return keyspace_client.Keyspace_ResultTimeoutStatus(cptr); 47 | } 48 | 49 | public int getCommandStatus() { 50 | return keyspace_client.Keyspace_ResultCommandStatus(cptr); 51 | } 52 | 53 | public TreeMap getKeyValues() { 54 | TreeMap keyvals = new TreeMap(); 55 | for (begin(); !isEnd(); next()) 56 | keyvals.put(getKey(), getValue()); 57 | 58 | return keyvals; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Framework/Database/Table.h: -------------------------------------------------------------------------------- 1 | #ifndef TABLE_H 2 | #define TABLE_H 3 | 4 | #include "Database.h" 5 | #include "Cursor.h" 6 | #include "System/Buffer.h" 7 | 8 | class TableVisitor 9 | { 10 | public: 11 | virtual ~TableVisitor() {} 12 | virtual bool Accept(const ByteString &key, const ByteString &value) = 0; 13 | virtual const ByteString* GetStartKey() { return 0; } 14 | virtual void OnComplete() {} 15 | virtual bool IsForward() { return true; } 16 | }; 17 | 18 | class Table 19 | { 20 | friend class Transaction; 21 | 22 | public: 23 | Table(Database* database, const char *name, int pageSize = 0); 24 | ~Table(); 25 | 26 | bool Iterate(Transaction* tx, Cursor& cursor); 27 | 28 | bool Get(Transaction* tx, const ByteString &key, ByteString &value); 29 | bool Get(Transaction* tx, const char* key, ByteString &value); 30 | bool Get(Transaction* tx, const char* key, uint64_t &value); 31 | 32 | bool Set(Transaction* tx, const ByteString &key, const ByteString &value); 33 | bool Set(Transaction* tx, const char* key, const ByteString &value); 34 | bool Set(Transaction* tx, const char* key, const char* value); 35 | bool Set(Transaction* tx, const ByteString &key, uint64_t value); 36 | 37 | bool Delete(Transaction* tx, const ByteString &key); 38 | bool Prune(Transaction* tx, const ByteString &prefix, bool pruneExpiries = false); 39 | bool Truncate(Transaction* tx = NULL); 40 | 41 | bool Visit(TableVisitor &tv); 42 | 43 | private: 44 | Database* database; 45 | Db* db; 46 | 47 | bool VisitBackward(TableVisitor &tv); 48 | }; 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "KeyspaceCommand.h" 2 | #include "KeyspaceResponse.h" 3 | #include "KeyspaceClientConsts.h" 4 | #include "Application/Keyspace/Protocol/Keyspace/KeyspaceClientReq.h" 5 | 6 | using namespace Keyspace; 7 | 8 | Command::Command() 9 | { 10 | type = 0; 11 | nodeID = -1; 12 | status = KEYSPACE_NOSERVICE; 13 | cmdID = 0; 14 | } 15 | 16 | Command::~Command() 17 | { 18 | ClearResponse(); 19 | } 20 | 21 | bool Command::IsDirty() const 22 | { 23 | switch(type) 24 | { 25 | case KEYSPACECLIENT_DIRTY_GET: 26 | case KEYSPACECLIENT_DIRTY_LIST: 27 | case KEYSPACECLIENT_DIRTY_LISTP: 28 | case KEYSPACECLIENT_DIRTY_COUNT: 29 | return true; 30 | 31 | default: 32 | return false; 33 | } 34 | } 35 | 36 | bool Command::IsList() const 37 | { 38 | if (type == KEYSPACECLIENT_LIST || 39 | type == KEYSPACECLIENT_LISTP || 40 | type == KEYSPACECLIENT_DIRTY_LIST || 41 | type == KEYSPACECLIENT_DIRTY_LISTP) 42 | { 43 | return true; 44 | } 45 | 46 | return false; 47 | } 48 | 49 | bool Command::IsRead() const 50 | { 51 | if (type == KEYSPACECLIENT_GET || 52 | type == KEYSPACECLIENT_DIRTY_GET || 53 | type == KEYSPACECLIENT_COUNT || 54 | type == KEYSPACECLIENT_DIRTY_COUNT || 55 | IsList()) 56 | { 57 | return true; 58 | } 59 | 60 | return false; 61 | } 62 | 63 | bool Command::IsWrite() const 64 | { 65 | return !IsRead(); 66 | } 67 | 68 | void Command::ClearResponse() 69 | { 70 | Response** it; 71 | 72 | for (it = responses.Head(); it != NULL;) 73 | { 74 | delete *it; 75 | it = responses.Remove(it); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Makefile.dirs: -------------------------------------------------------------------------------- 1 | $(BUILD_DIR): 2 | -mkdir -p $(BUILD_DIR) \ 3 | $(BIN_DIR) \ 4 | $(BUILD_DIR)/Application/ \ 5 | $(BUILD_DIR)/Application/Console/ \ 6 | $(BUILD_DIR)/Application/EchoServer/ \ 7 | $(BUILD_DIR)/Application/HTTP/ \ 8 | $(BUILD_DIR)/Application/HubSim/ \ 9 | $(BUILD_DIR)/Application/TestDB/ \ 10 | $(BUILD_DIR)/Application/Keyspace/ \ 11 | $(BUILD_DIR)/Application/Keyspace/Catchup \ 12 | $(BUILD_DIR)/Application/Keyspace/Client/ \ 13 | $(BUILD_DIR)/Application/Keyspace/Client/Java \ 14 | $(BUILD_DIR)/Application/Keyspace/Client/Perl \ 15 | $(BUILD_DIR)/Application/Keyspace/Client/PHP \ 16 | $(BUILD_DIR)/Application/Keyspace/Client/Python \ 17 | $(BUILD_DIR)/Application/Keyspace/Client/Ruby \ 18 | $(BUILD_DIR)/Application/Keyspace/Database/ \ 19 | $(BUILD_DIR)/Application/Keyspace/Protocol/ \ 20 | $(BUILD_DIR)/Application/Keyspace/Protocol/HTTP \ 21 | $(BUILD_DIR)/Application/Keyspace/Protocol/Keyspace \ 22 | $(BUILD_DIR)/Application/Keyspace/Protocol/Memcache \ 23 | $(BUILD_DIR)/Application/Tools/BDBTool \ 24 | $(BUILD_DIR)/Framework/ReplicatedLog/ \ 25 | $(BUILD_DIR)/Framework/Transport/ \ 26 | $(BUILD_DIR)/Framework/MasterLease/ \ 27 | $(BUILD_DIR)/Framework/ \ 28 | $(BUILD_DIR)/Framework/Paxos/ \ 29 | $(BUILD_DIR)/Framework/AsyncDatabase/ \ 30 | $(BUILD_DIR)/Framework/Database/ \ 31 | $(BUILD_DIR)/Framework/PaxosLease/ \ 32 | $(BUILD_DIR)/Framework/ReplicatedDB/ \ 33 | $(BUILD_DIR)/System/ \ 34 | $(BUILD_DIR)/System/Events/ \ 35 | $(BUILD_DIR)/System/Containers/ \ 36 | $(BUILD_DIR)/System/IO/ \ 37 | $(BUILD_DIR)/Test/ \ 38 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceClientReq.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACECLIENTREQ_H 2 | #define KEYSPACECLIENTREQ_H 3 | 4 | #include "System/Buffer.h" 5 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 6 | 7 | #define KEYSPACECLIENT_GET_MASTER 'm' 8 | #define KEYSPACECLIENT_GET 'g' 9 | #define KEYSPACECLIENT_DIRTY_GET 'G' 10 | #define KEYSPACECLIENT_LIST 'l' 11 | #define KEYSPACECLIENT_DIRTY_LIST 'L' 12 | #define KEYSPACECLIENT_LISTP 'p' 13 | #define KEYSPACECLIENT_DIRTY_LISTP 'P' 14 | #define KEYSPACECLIENT_COUNT 'c' 15 | #define KEYSPACECLIENT_DIRTY_COUNT 'C' 16 | #define KEYSPACECLIENT_SET 's' 17 | #define KEYSPACECLIENT_TEST_AND_SET 't' 18 | #define KEYSPACECLIENT_DELETE 'd' 19 | #define KEYSPACECLIENT_PRUNE 'z' 20 | #define KEYSPACECLIENT_ADD 'a' 21 | #define KEYSPACECLIENT_REMOVE 'r' 22 | #define KEYSPACECLIENT_RENAME 'e' 23 | #define KEYSPACECLIENT_SET_EXPIRY 'x' 24 | #define KEYSPACECLIENT_REMOVE_EXPIRY 'X' 25 | #define KEYSPACECLIENT_CLEAR_EXPIRIES 'w' 26 | #define KEYSPACECLIENT_SUBMIT '*' 27 | 28 | class KeyspaceOp; 29 | 30 | class KeyspaceClientReq 31 | { 32 | public: 33 | char type; 34 | ByteString key; 35 | ByteString newKey; 36 | ByteString value; 37 | ByteString test; 38 | ByteString prefix; 39 | uint64_t cmdID; 40 | uint64_t count; 41 | uint64_t offset; 42 | int64_t num; 43 | uint64_t expiryTime; 44 | char direction; 45 | 46 | void Init(); 47 | bool Read(const ByteString& data); 48 | bool ToKeyspaceOp(KeyspaceOp* op); 49 | 50 | bool IsRead(); 51 | bool IsWrite(); 52 | bool IsDirty(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceResult.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_RESULT_H 2 | #define KEYSPACE_RESULT_H 3 | 4 | #include "System/Containers/List.h" 5 | #include "System/Buffer.h" 6 | 7 | namespace Keyspace 8 | { 9 | 10 | class ClientConn; 11 | class Client; 12 | class Command; 13 | class Response; 14 | 15 | typedef List CommandList; 16 | 17 | class Result 18 | { 19 | friend class ClientConn; 20 | friend class Client; 21 | 22 | public: 23 | ~Result(); 24 | 25 | void Close(); 26 | 27 | void Begin(); 28 | // void End(); 29 | 30 | void Next(); 31 | // void Prev(); 32 | 33 | // bool IsBegin(); 34 | bool IsEnd(); 35 | 36 | int Key(ByteString& key) const; 37 | int Value(ByteString& value) const; 38 | 39 | int CommandStatus() const; 40 | int GetNodeID() const; 41 | 42 | int TransportStatus() const; 43 | int ConnectivityStatus() const; 44 | int TimeoutStatus() const; 45 | 46 | private: 47 | bool isBatched; 48 | CommandList commands; 49 | int numCompleted; 50 | ByteString empty; 51 | int transportStatus; 52 | int connectivityStatus; 53 | int timeoutStatus; 54 | Command** commandCursor; 55 | Response** responseCursor; 56 | 57 | Command** cmdMap; 58 | 59 | 60 | Result(); 61 | 62 | void AppendCommandResponse(Command* cmd, Response* resp); 63 | void AppendCommand(Command* cmd); 64 | 65 | int ListKey(Command* cmd, ByteString& key) const; 66 | int ListValue(Command* cmd, ByteString& value) const; 67 | 68 | void InitCommandMap(); 69 | void FreeCommandMap(); 70 | }; 71 | 72 | 73 | 74 | }; // namespace 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/Test/QueueTest.cpp: -------------------------------------------------------------------------------- 1 | #include "Test.h" 2 | #include "System/Containers/Queue.h" 3 | #include "System/Containers/LinkedList.h" 4 | #include "System/Buffer.h" 5 | 6 | typedef DynArray<32> Buffer; 7 | int BasicQueueTest() 8 | { 9 | Buffer *buffer; 10 | Queue q; 11 | 12 | for (int i = 0; i < 3; i++) 13 | { 14 | buffer = new Buffer(); 15 | buffer->Printf("%i", i); 16 | q.Append(buffer); 17 | } 18 | 19 | for (int i = 0; i < 3; i++) 20 | { 21 | buffer = q.Get(); 22 | TEST_LOG("%.*s", buffer->length, buffer->buffer); 23 | delete buffer; 24 | } 25 | 26 | return TEST_SUCCESS; 27 | } 28 | 29 | class Elem 30 | { 31 | public: 32 | // this node will be part of listA 33 | Elem* nextA; 34 | Elem* prevA; 35 | Buffer buffer; 36 | // this node will be part of listB 37 | Elem* nextB; 38 | Elem* prevB; 39 | 40 | int i; 41 | LinkedListNode node; 42 | LLNode llnode; 43 | }; 44 | 45 | int BasicLinkedListTest() 46 | { 47 | LinkedList2 listA; 48 | LinkedList2 listB; 49 | LinkedList listC; 50 | LList llist; 51 | 52 | for (int i = 0; i < 3; i++) 53 | { 54 | Elem* elem; 55 | 56 | elem = new Elem; 57 | elem->buffer.Printf("%i", i); 58 | //listC.Append(*elem); 59 | llist.Add(*elem); 60 | } 61 | 62 | Elem* next = NULL; 63 | for (Elem* e = listC.Head(); e; e = next) 64 | { 65 | TEST_LOG("%.*s", e->buffer.length, e->buffer.data); 66 | next = listC.Remove(e); 67 | delete e; 68 | } 69 | 70 | return TEST_SUCCESS; 71 | } 72 | 73 | TEST_MAIN(BasicQueueTest, BasicLinkedListTest); 74 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KeyspaceClient")] 9 | [assembly: AssemblyDescription("Keyspace Client library for .NET")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Scalien Software")] 12 | [assembly: AssemblyProduct("KeyspaceClient")] 13 | [assembly: AssemblyCopyright("Copyright © 2010 Scalien Software Kft.")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("526fb2d6-1efd-4d63-be58-636b6ad7493a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /src/Framework/AsyncDatabase/MultiDatabaseOp.h: -------------------------------------------------------------------------------- 1 | #ifndef ASYNCDATABASEOP_H 2 | #define ASYNCDATABASEOP_H 3 | 4 | #include "System/Buffer.h" 5 | #include "System/Events/Callable.h" 6 | 7 | class Table; 8 | class TableVisitor; 9 | class Transaction; 10 | class ByteString; 11 | class AsyncDatabase; 12 | 13 | class DatabaseOp 14 | { 15 | public: 16 | enum Type { 17 | GET, 18 | SET, 19 | VISIT 20 | }; 21 | 22 | Type type; 23 | Table* table; 24 | ByteString key; 25 | ByteString value; 26 | TableVisitor* visitor; 27 | bool ret; 28 | }; 29 | 30 | class MultiDatabaseOp 31 | { 32 | friend class AsyncDatabase; 33 | typedef MFunc Func; 34 | 35 | public: 36 | MultiDatabaseOp(); 37 | 38 | void Init(); 39 | 40 | bool Get(Table* table, const ByteString& key, ByteString& value); 41 | bool Set(Table* table, const ByteString& key, ByteString& value); 42 | bool Set(Table* table, const char* key, ByteString &value); 43 | bool Set(Table* table, const char* key, const char* value); 44 | bool Visit(Table* table, TableVisitor &tv); 45 | bool Add(DatabaseOp& op); 46 | 47 | void SetTransaction(Transaction* tx = 0); 48 | 49 | void SetCallback(Callable* userCallback); 50 | Callable* GetOperation(); 51 | ByteString* GetValue(int i); 52 | bool GetReturnValue(int i); 53 | int GetNumOp(); 54 | bool IsActive() { return active; } 55 | 56 | private: 57 | bool active; 58 | DatabaseOp ops[1024]; 59 | size_t numop; 60 | 61 | Callable* userCallback; 62 | Transaction* tx; 63 | 64 | void OnComplete(); 65 | Func onComplete; 66 | 67 | void Operation(); 68 | Func operation; 69 | }; 70 | 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/Framework/Transport/TransportTCPWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "TransportTCPWriter.h" 2 | #include "System/Events/EventLoop.h" 3 | 4 | #define CONNECT_TIMEOUT 2000 5 | 6 | 7 | bool TransportTCPWriter::Init(Endpoint &endpoint_) 8 | { 9 | endpoint = endpoint_; 10 | TCPConn<>::Connect(endpoint, CONNECT_TIMEOUT); 11 | return true; 12 | } 13 | 14 | void TransportTCPWriter::Write(ByteString &bs) 15 | { 16 | Log_Trace(); 17 | 18 | char lbuf[20]; 19 | int llen; 20 | 21 | if (state == CONNECTED) 22 | { 23 | llen = snwritef(lbuf, sizeof(lbuf), "%d:", bs.length); 24 | 25 | TCPConn<>::Write(lbuf, llen, false); 26 | TCPConn<>::Write(bs.buffer, bs.length); 27 | } 28 | else if (state == DISCONNECTED && !connectTimeout.IsActive()) 29 | Connect(); 30 | } 31 | 32 | void TransportTCPWriter::Connect() 33 | { 34 | Log_Trace(); 35 | 36 | TCPConn<>::Connect(endpoint, CONNECT_TIMEOUT); 37 | } 38 | 39 | void TransportTCPWriter::OnConnect() 40 | { 41 | TCPConn<>::OnConnect(); 42 | 43 | Log_Trace("endpoint = %s", endpoint.ToString()); 44 | 45 | AsyncRead(); 46 | } 47 | 48 | void TransportTCPWriter::OnConnectTimeout() 49 | { 50 | TCPConn<>::OnConnectTimeout(); 51 | 52 | Log_Trace("endpoint = %s", endpoint.ToString()); 53 | 54 | Close(); 55 | Connect(); 56 | } 57 | 58 | void TransportTCPWriter::OnRead() 59 | { 60 | Log_Trace("endpoint = %s", endpoint.ToString()); 61 | 62 | // drop any data 63 | readBuffer.Clear(); 64 | AsyncRead(); 65 | } 66 | 67 | void TransportTCPWriter::OnClose() 68 | { 69 | Log_Trace("endpoint = %s", endpoint.ToString()); 70 | 71 | if (!connectTimeout.IsActive()) 72 | { 73 | Log_Trace("reset"); 74 | EventLoop::Reset(&connectTimeout); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/System/Events/Timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | 4 | #include "System/Time.h" 5 | #include "Callable.h" 6 | 7 | class Timer 8 | { 9 | friend class Scheduler; 10 | 11 | public: 12 | Timer() 13 | { 14 | when = 0; 15 | callable = NULL; 16 | active = false; 17 | } 18 | 19 | virtual ~Timer() {} 20 | 21 | Timer(Callable* callable_) 22 | { 23 | when = 0; 24 | callable = callable_; 25 | active = false; 26 | } 27 | 28 | void Set(uint64_t when_) 29 | { 30 | when = when_; 31 | } 32 | 33 | bool IsActive() 34 | { 35 | return active; 36 | } 37 | 38 | uint64_t When() 39 | { 40 | return when; 41 | } 42 | 43 | void Execute() 44 | { 45 | Call(callable); 46 | } 47 | 48 | virtual void OnAdd() 49 | { 50 | } 51 | 52 | protected: 53 | bool active; 54 | uint64_t when; 55 | Callable* callable; 56 | }; 57 | 58 | class CdownTimer : public Timer 59 | { 60 | public: 61 | CdownTimer() : Timer() 62 | { 63 | delay = 0; 64 | } 65 | 66 | CdownTimer(Callable* callable_) : Timer(callable_) 67 | { 68 | delay = 0; 69 | } 70 | 71 | CdownTimer(uint64_t delay_, Callable* callable_) : Timer(callable_) 72 | { 73 | delay = delay_; 74 | } 75 | 76 | void SetDelay(uint64_t delay_) 77 | { 78 | delay = delay_; 79 | } 80 | 81 | uint64_t GetDelay() 82 | { 83 | return delay; 84 | } 85 | 86 | virtual void OnAdd() 87 | { 88 | when = Now() + delay; 89 | } 90 | 91 | private: 92 | uint64_t delay; 93 | }; 94 | 95 | inline bool LessThan(Timer* a, Timer* b) 96 | { 97 | return (a->When() < b->When()); 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/Java/imaxdiv_t.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 1.3.31 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package com.scalien.keyspace; 10 | 11 | public class imaxdiv_t { 12 | private long swigCPtr; 13 | protected boolean swigCMemOwn; 14 | 15 | protected imaxdiv_t(long cPtr, boolean cMemoryOwn) { 16 | swigCMemOwn = cMemoryOwn; 17 | swigCPtr = cPtr; 18 | } 19 | 20 | protected static long getCPtr(imaxdiv_t obj) { 21 | return (obj == null) ? 0 : obj.swigCPtr; 22 | } 23 | 24 | protected void finalize() { 25 | delete(); 26 | } 27 | 28 | public synchronized void delete() { 29 | if(swigCPtr != 0 && swigCMemOwn) { 30 | swigCMemOwn = false; 31 | keyspace_clientJNI.delete_imaxdiv_t(swigCPtr); 32 | } 33 | swigCPtr = 0; 34 | } 35 | 36 | public void setQuot(long value) { 37 | keyspace_clientJNI.imaxdiv_t_quot_set(swigCPtr, this, value); 38 | } 39 | 40 | public long getQuot() { 41 | return keyspace_clientJNI.imaxdiv_t_quot_get(swigCPtr, this); 42 | } 43 | 44 | public void setRem(long value) { 45 | keyspace_clientJNI.imaxdiv_t_rem_set(swigCPtr, this, value); 46 | } 47 | 48 | public long getRem() { 49 | return keyspace_clientJNI.imaxdiv_t_rem_get(swigCPtr, this); 50 | } 51 | 52 | public imaxdiv_t() { 53 | this(keyspace_clientJNI.new_imaxdiv_t(), true); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/KeyspaceClientConn.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYSPACE_CLIENT_CONN_H 2 | #define KEYSPACE_CLIENT_CONN_H 3 | 4 | #include "System/Containers/List.h" 5 | #include "Framework/Transport/MessageConn.h" 6 | #include "Application/Keyspace/Database/KeyspaceConsts.h" 7 | 8 | #define KEYSPACE_MOD_GETMASTER 0 9 | #define KEYSPACE_MOD_COMMAND 1 10 | 11 | namespace Keyspace 12 | { 13 | 14 | class Client; 15 | class Response; 16 | class Command; 17 | typedef List CommandList; 18 | 19 | class ClientConn : public MessageConn 20 | { 21 | typedef MFunc Func; 22 | 23 | public: 24 | ClientConn(Client &client, int nodeID, const Endpoint &endpoint_); 25 | ~ClientConn(); 26 | 27 | void Connect(); 28 | void Send(Command &cmd); 29 | void SendSubmit(); 30 | void SendGetMaster(); 31 | 32 | // MessageConn interface 33 | virtual void OnMessageRead(const ByteString& msg); 34 | virtual void OnWrite(); 35 | virtual void OnClose(); 36 | virtual void OnConnect(); 37 | virtual void OnConnectTimeout(); 38 | 39 | void OnReadTimeout(); 40 | void OnGetMaster(); 41 | 42 | Endpoint& GetEndpoint(); 43 | bool ReadMessage(ByteString &msg); 44 | bool ProcessResponse(Response* msg); 45 | bool ProcessGetMaster(Response* resp); 46 | bool ProcessCommand(Response* resp); 47 | void GetMaster(); 48 | void DeleteCommands(); 49 | 50 | private: 51 | friend class Client; 52 | 53 | bool submit; 54 | Client& client; 55 | Endpoint endpoint; 56 | int nodeID; 57 | uint64_t getMasterTime; 58 | Func onGetMasterTimeout; 59 | CdownTimer getMasterTimeout; 60 | CommandList getMasterCommands; 61 | }; 62 | 63 | }; // namespace 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PaxosLease.h: -------------------------------------------------------------------------------- 1 | #ifndef PAXOSLEASE_H 2 | #define PAXOSLEASE_H 3 | 4 | #include "Framework/Transport/TransportTCPReader.h" 5 | #include "Framework/Transport/TransportTCPWriter.h" 6 | #include "Framework/ReplicatedLog/ReplicatedConfig.h" 7 | #include "System/Events/Timer.h" 8 | #include "PLeaseConsts.h" 9 | #include "PLeaseMsg.h" 10 | #include "PLeaseProposer.h" 11 | #include "PLeaseAcceptor.h" 12 | #include "PLeaseLearner.h" 13 | 14 | class ReplicatedLog; 15 | 16 | class PaxosLease 17 | { 18 | typedef TransportTCPReader* Reader; 19 | typedef TransportTCPWriter** Writers; 20 | typedef MFunc Func; 21 | public: 22 | PaxosLease(); 23 | 24 | void Init(bool useSoftClock); 25 | void Shutdown(); 26 | void OnRead(); 27 | void AcquireLease(); 28 | bool IsLeaseOwner(); 29 | bool IsLeaseKnown(); 30 | unsigned GetLeaseOwner(); 31 | uint64_t GetLeaseEpoch(); 32 | void SetOnLearnLease(Callable* onLearnLeaseCallback); 33 | void SetOnLeaseTimeout(Callable* onLeaseTimeoutCallback); 34 | void Stop(); 35 | void Continue(); 36 | bool IsActive(); 37 | void OnNewPaxosRound(); 38 | void OnLearnLease(); 39 | void OnLeaseTimeout(); 40 | void OnStartupTimeout(); 41 | 42 | private: 43 | void InitTransport(); 44 | 45 | bool acquireLease; 46 | Reader reader; 47 | Writers writers; 48 | Func onRead; 49 | Func onLearnLease; 50 | Func onLeaseTimeout; 51 | Func onStartupTimeout; 52 | CdownTimer startupTimeout; 53 | Callable* onLearnLeaseCallback; 54 | Callable* onLeaseTimeoutCallback; 55 | PLeaseMsg msg; 56 | PLeaseProposer proposer; 57 | PLeaseAcceptor acceptor; 58 | PLeaseLearner learner; 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/genindex-single.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{% trans key=key %}Index – {{ key }}{% endtrans %}

6 | 7 |
8 |
9 | {%- set breakat = count // 2 %} 10 | {%- set numcols = 1 %} 11 | {%- set numitems = 0 %} 12 | {% for entryname, (links, subitems) in entries %} 13 |
{%- if links -%}{{ entryname|e }} 14 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 15 | {%- else -%} 16 | {{ entryname|e }} 17 | {%- endif -%}
18 | {%- if subitems %} 19 |
20 | {%- for subentryname, subentrylinks in subitems %} 21 |
{{ subentryname|e }} 22 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 23 |
24 | {%- endfor %} 25 |
26 | {%- endif -%} 27 | {%- set numitems = numitems + 1 + (subitems|length) -%} 28 | {%- if numcols < 2 and numitems > breakat -%} 29 | {%- set numcols = numcols+1 -%} 30 |
31 | {%- endif -%} 32 | {%- endfor %} 33 |
34 | 35 | {% endblock %} 36 | 37 | {% block sidebarrel %} 38 |

Index

39 |

{% for key, dummy in genindexentries -%} 40 | {{ key }} 41 | {% if not loop.last %}| {% endif %} 42 | {%- endfor %}

43 | 44 |

{{ _('Full index on one page') }}

45 | {{ super() }} 46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /script/keyspace: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # keyspace: Scalien Keyspace replicated key-value database 4 | 5 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 6 | DESC="Keyspace" 7 | RUNSAFE="yes" 8 | DEFAULT=/etc/default/keyspace 9 | 10 | if [ `id -u` != "0" ] 11 | then 12 | echo "You must be root to start this appication." 13 | exit 1 14 | fi 15 | 16 | test -f $DEFAULT || exit 0 17 | . $DEFAULT 18 | 19 | test -x $DAEMON || exit 0 20 | 21 | pidof_daemon() { 22 | pid=`ps auxw | grep "$DAEMON" | grep -v grep | grep -v "$SAFE_DAEMON" | awk '{print $2}'` 23 | } 24 | 25 | wait_stop() { 26 | i=0 27 | while [ $i -lt $1 ]; do 28 | pidof_daemon 29 | if [ "$pid" = "" ]; then 30 | return 31 | fi 32 | sleep 1 33 | i=`expr $i + 1` 34 | done 35 | kill -9 $pid 36 | } 37 | 38 | case "$1" in 39 | start) 40 | echo -n "Starting $DESC: " 41 | 42 | pidof_daemon 43 | if [ "$pid" != "" ]; then 44 | echo "$DAEMON is already running!" 45 | exit 1 46 | fi 47 | 48 | $SAFE_DAEMON $DAEMON $DEFAULT_CONFIG $DATABASE_DIR 49 | 50 | if [ $? -eq 0 ]; then 51 | echo "$NAME." 52 | fi 53 | ;; 54 | stop) 55 | echo -n "Stopping $DESC: " 56 | pidof_daemon 57 | if [ "$pid" != "" ]; then 58 | kill $pid 59 | pidof_daemon 60 | if [ "$pid" != "" ]; then 61 | wait_stop 20 62 | pidof_daemon 63 | if [ "$pid" != "" ]; then 64 | echo "$NAME ($pid) could not be stopped!" 65 | exit 1 66 | fi 67 | fi 68 | echo "$NAME." 69 | else 70 | echo "$NAME is not running." 71 | fi 72 | ;; 73 | restart|force-reload) 74 | $0 stop 75 | $0 start 76 | ;; 77 | *) 78 | N=/etc/init.d/$NAME 79 | echo "Usage: $N {start|stop|restart}" >&2 80 | exit 1 81 | ;; 82 | esac 83 | 84 | exit 0 85 | -------------------------------------------------------------------------------- /client/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | +-------------------+ 3 | | | 4 | | BSD LICENCE | 5 | | | 6 | +-------------------+ 7 | 8 | 9 | Copyright (c) 2009, Scalien Software Kft. 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the Scalien Software Kft. nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY Scalien Software Kft. ''AS IS'' AND ANY 24 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL Scalien Software Kft. BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClient.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C# Express 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyspaceClient", "KeyspaceClient\KeyspaceClient.csproj", "{EE1009F6-8E67-495B-A358-96D8673315B8}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyspaceClientTest", "KeyspaceClientTest\KeyspaceClientTest.csproj", "{51A04E37-82BF-4B02-8683-F27569312A79}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {EE1009F6-8E67-495B-A358-96D8673315B8} = {EE1009F6-8E67-495B-A358-96D8673315B8} 9 | EndProjectSection 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {EE1009F6-8E67-495B-A358-96D8673315B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {EE1009F6-8E67-495B-A358-96D8673315B8}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {EE1009F6-8E67-495B-A358-96D8673315B8}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {EE1009F6-8E67-495B-A358-96D8673315B8}.Release|Any CPU.Build.0 = Release|Any CPU 21 | {51A04E37-82BF-4B02-8683-F27569312A79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {51A04E37-82BF-4B02-8683-F27569312A79}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {51A04E37-82BF-4B02-8683-F27569312A79}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {51A04E37-82BF-4B02-8683-F27569312A79}.Release|Any CPU.Build.0 = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /src/Application/EchoServer/TCPEchoConn.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPEchoConn.h" 2 | 3 | TCPEchoConn::TCPEchoConn() : 4 | onWelcome(this, &TCPEchoConn::OnWelcome), 5 | onRead(this, &TCPEchoConn::OnRead), 6 | onWrite(this, &TCPEchoConn::OnWrite), 7 | onCloseRead(this, &TCPEchoConn::OnCloseRead), 8 | onCloseWrite(this, &TCPEchoConn::OnCloseWrite) 9 | { 10 | } 11 | 12 | bool TCPEchoConn::Init(IOProcessor* ioproc_) 13 | { 14 | ioproc = ioproc_; 15 | 16 | tcpwrite.fd = socket.fd; 17 | tcpwrite.data = data; 18 | 19 | #define WELCOME_MSG "Welcome to TCPEchoServer!\n\n" 20 | sprintf(tcpwrite.data.buffer, WELCOME_MSG); 21 | tcpwrite.data.length = strlen(WELCOME_MSG); 22 | tcpwrite.onComplete = &onWelcome; 23 | tcpwrite.onClose = &onCloseWrite; 24 | ioproc->Add(&tcpwrite); 25 | 26 | return true; 27 | } 28 | 29 | void TCPEchoConn::OnWelcome() 30 | { 31 | Log_Trace(); 32 | 33 | tcpread.fd = socket.fd; 34 | tcpread.data = data; 35 | tcpread.requested = IO_READ_ANY; 36 | tcpread.onComplete = &onRead; 37 | tcpread.onClose = &onCloseRead; 38 | ioproc->Add(&tcpread); 39 | 40 | tcpwrite.onComplete = &onWrite; 41 | } 42 | 43 | void TCPEchoConn::Shutdown() 44 | { 45 | Log_Trace(); 46 | 47 | socket.Close(); 48 | } 49 | 50 | void TCPEchoConn::OnRead() 51 | { 52 | Log_Trace(); 53 | 54 | tcpwrite.data.length = tcpread.data.length; 55 | tcpwrite.transferred = 0; 56 | ioproc->Add(&tcpwrite); 57 | } 58 | 59 | void TCPEchoConn::OnWrite() 60 | { 61 | Log_Trace(); 62 | 63 | tcpread.data.length = 0; 64 | ioproc->Add(&tcpread); 65 | } 66 | 67 | void TCPEchoConn::OnCloseRead() 68 | { 69 | Log_Trace(); 70 | 71 | Shutdown(); 72 | delete this; 73 | } 74 | 75 | void TCPEchoConn::OnCloseWrite() 76 | { 77 | Log_Trace(); 78 | 79 | Shutdown(); 80 | delete this; 81 | } 82 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/search.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Search') %} 3 | {% set script_files = script_files + ['_static/searchtools.js'] %} 4 | {% block body %} 5 |

{{ _('Search') }}

6 |
7 | 8 |

9 | {% trans %}Please activate JavaScript to enable the search 10 | functionality.{% endtrans %} 11 |

12 |
13 |

14 | {% trans %}From here you can search these documents. Enter your search 15 | words into the box below and click "search". Note that the search 16 | function will automatically search for all of the words. Pages 17 | containing fewer words won't appear in the result list.{% endtrans %} 18 |

19 |
20 | 21 | 22 | 23 |
24 | {% if search_performed %} 25 |

{{ _('Search Results') }}

26 | {% if not search_results %} 27 |

{{ _('Your search did not match any results.') }}

28 | {% endif %} 29 | {% endif %} 30 |
31 | {% if search_results %} 32 |
    33 | {% for href, caption, context in search_results %} 34 |
  • {{ caption }} 35 |
    {{ context|e }}
    36 |
  • 37 | {% endfor %} 38 |
39 | {% endif %} 40 |
41 | {% endblock %} 42 | {% block footer %} 43 | {{ super() }} 44 | 45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /src/Test/TimeCheckTest.cpp: -------------------------------------------------------------------------------- 1 | #include "System/Config.h" 2 | #include "System/Events/EventLoop.h" 3 | #include "System/IO/IOProcessor.h" 4 | #include "Framework/ReplicatedLog/ReplicatedLog.h" 5 | #include "Application/Keyspace/Database/SingleKeyspaceDB.h" 6 | #include "Application/Keyspace/Database/ReplicatedKeyspaceDB.h" 7 | #include "Application/Keyspace/Protocol/HTTP/HttpServer.h" 8 | #include "Application/Keyspace/Protocol/Keyspace/KeyspaceServer.h" 9 | #include "Application/TimeCheck/TimeCheck.h" 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | int logTargets; 14 | 15 | if (argc != 2) 16 | { 17 | fprintf(stderr, "usage: %s \n", argv[0]); 18 | return 1; 19 | } 20 | 21 | if (!Config::Init(argv[1])) 22 | STOP_FAIL("Cannot open config file", 1); 23 | 24 | logTargets = 0; 25 | for (int i = 0; i < Config::GetListNum("log.targets"); i++) 26 | { 27 | if (strcmp(Config::GetListValue("log.targets", i, ""), "file") == 0) 28 | { 29 | logTargets |= LOG_TARGET_FILE; 30 | Log_SetOutputFile(Config::GetValue("log.file", NULL)); 31 | } 32 | if (strcmp(Config::GetListValue("log.targets", i, NULL), "stdout") == 0) 33 | logTargets |= LOG_TARGET_STDOUT; 34 | if (strcmp(Config::GetListValue("log.targets", i, NULL), "stderr") == 0) 35 | logTargets |= LOG_TARGET_STDERR; 36 | 37 | } 38 | Log_SetTarget(logTargets); 39 | Log_SetTrace(Config::GetBoolValue("log.trace", false)); 40 | Log_SetTimestamping(Config::GetBoolValue("log.timestamping", false)); 41 | 42 | if (!IOProcessor::Init(Config::GetIntValue("io.maxfd", 1024))) 43 | STOP_FAIL("Cannot initalize IOProcessor!", 1); 44 | 45 | if (!RCONF->Init()) 46 | STOP_FAIL("Cannot initialize paxos!", 1); 47 | 48 | TimeCheck tc; 49 | tc.Init(true, false); 50 | 51 | EventLoop::Run(); 52 | } 53 | -------------------------------------------------------------------------------- /src/Test/Test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Test.h -- basic unit test framework 3 | */ 4 | #ifndef __TEST_H 5 | #define __TEST_H 6 | 7 | #include 8 | #include 9 | 10 | #ifdef _MSC_VER 11 | #define __func__ __FUNCTION__ 12 | #endif 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | // NOTE the token-paste operator (##) behaves specially with __VA_ARGS__ after commas 19 | #define TEST_LOG(fmt, ...) {printf("%s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);} 20 | #define TEST(testfn) test(testfn, #testfn) 21 | #define TESTARG(testfn) (testfn),(#testfn) 22 | #define TEST_MAIN(...) \ 23 | int main(int, char **) { \ 24 | testfn_t test_functions[] = {__VA_ARGS__}; \ 25 | char test_names[] = #__VA_ARGS__; \ 26 | int size = sizeof(test_functions) / sizeof(void *); \ 27 | int names[size]; \ 28 | test_names_parse(test_functions, test_names, names, size); \ 29 | int i; \ 30 | int ret = 0; \ 31 | for (i = 0; i < sizeof(test_functions) / sizeof(void *); i++) { \ 32 | ret += test_time(test_functions[i], (const char *) &test_names[names[i]]); \ 33 | } \ 34 | return test_eval(__FILE__, ret); \ 35 | } \ 36 | 37 | #define TEST_SUCCESS 0 38 | #define TEST_FAILURE 1 39 | 40 | typedef int (*testfn_t)(void); 41 | 42 | int test(testfn_t testfn, const char *testname); 43 | int test_iter(testfn_t testfn, const char *testname, unsigned long niter); 44 | int test_time(testfn_t testfn, const char *testname); 45 | int test_iter_time(testfn_t testfn, const char *testname, unsigned long niter); 46 | int test_eval(const char *ident, int result); 47 | int test_system(const char *cmdline); 48 | 49 | // helper function for TEST_MAIN 50 | int test_names_parse(testfn_t *test_functions, char *test_names, int *names, int size); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/Application/HTTP/JSONSession.cpp: -------------------------------------------------------------------------------- 1 | #include "JSONSession.h" 2 | #include "HttpConn.h" 3 | #include "HttpConsts.h" 4 | 5 | void JSONSession::Init(HttpConn* conn_, const ByteString& jsonCallback_) 6 | { 7 | conn = conn_; 8 | jsonCallback = jsonCallback_; 9 | } 10 | 11 | void JSONSession::PrintStatus(const char* status, const char* type_) 12 | { 13 | conn->ResponseHeader(HTTP_STATUS_CODE_OK, 14 | "Content-type: application/json" HTTP_CS_CRLF); 15 | if (jsonCallback.length) 16 | { 17 | conn->Write(jsonCallback.buffer, jsonCallback.length, false); 18 | conn->Print("("); 19 | } 20 | conn->Print("{\"status\":\""); 21 | conn->Print(status); 22 | if (type_) 23 | { 24 | conn->Print("\",\"type\":\""); 25 | conn->Print(type_); 26 | } 27 | conn->Print("\"}"); 28 | 29 | if (jsonCallback.length) 30 | conn->Print(")"); 31 | 32 | conn->Flush(); 33 | } 34 | 35 | void JSONSession::PrintString(const char *s, unsigned len) 36 | { 37 | conn->Write("\"", 1, false); 38 | for (unsigned i = 0; i < len; i++) 39 | { 40 | if (s[i] == '"') 41 | conn->Write("\\", 1, false); 42 | conn->Write(s + i, 1, false); 43 | } 44 | conn->Write("\"", 1, false); 45 | } 46 | 47 | void JSONSession::PrintNumber(double number) 48 | { 49 | ByteArray<32> text; 50 | 51 | text.length = snprintf(text.buffer, text.length, "%lf", number); 52 | conn->Write(text.buffer, text.length, false); 53 | } 54 | 55 | void JSONSession::PrintBool(bool b) 56 | { 57 | if (b) 58 | conn->Write("true", 4, false); 59 | else 60 | conn->Write("false", 5, false); 61 | } 62 | 63 | void JSONSession::PrintNull() 64 | { 65 | conn->Write("null", 4, false); 66 | } 67 | 68 | void JSONSession::PrintObjectStart(const char* /*name*/, unsigned /*len*/) 69 | { 70 | // TODO 71 | } 72 | 73 | void JSONSession::PrintObjectEnd() 74 | { 75 | // TODO 76 | } 77 | -------------------------------------------------------------------------------- /src/Framework/Database/Cursor.cpp: -------------------------------------------------------------------------------- 1 | #include "Cursor.h" 2 | 3 | bool Cursor::Start(ByteString &key) 4 | { 5 | Dbt dbkey, dbvalue; 6 | 7 | dbkey.set_data(key.buffer); 8 | dbkey.set_size(key.length); 9 | 10 | if (cursor->get(&dbkey, &dbvalue, DB_SET) == 0) 11 | { 12 | if (key.Set((char*)dbkey.get_data(), dbkey.get_size())) 13 | return true; 14 | else 15 | return false; 16 | } 17 | return false; 18 | } 19 | 20 | bool Cursor::Start(ByteString &key, ByteString &value) 21 | { 22 | Dbt dbkey, dbvalue; 23 | 24 | dbkey.set_data(key.buffer); 25 | dbkey.set_size(key.length); 26 | 27 | if (cursor->get(&dbkey, &dbvalue, DB_SET_RANGE) == 0) 28 | { 29 | if (key.Set((char*)dbkey.get_data(), dbkey.get_size()) && 30 | value.Set((char*)dbvalue.get_data(), dbvalue.get_size())) 31 | return true; 32 | else 33 | return false; 34 | } 35 | return false; 36 | } 37 | 38 | bool Cursor::Delete() 39 | { 40 | return (cursor->del(0) == 0); 41 | } 42 | 43 | bool Cursor::Next(ByteString &key, ByteString &value) 44 | { 45 | Dbt dbkey, dbvalue; 46 | 47 | if (cursor->get(&dbkey, &dbvalue, DB_NEXT) == 0) 48 | { 49 | if (key.Set((char*)dbkey.get_data(), dbkey.get_size()) && 50 | value.Set((char*)dbvalue.get_data(), dbvalue.get_size())) 51 | return true; 52 | else 53 | return false; 54 | } 55 | else 56 | return false; 57 | } 58 | 59 | bool Cursor::Prev(ByteString &key, ByteString &value) 60 | { 61 | Dbt dbkey, dbvalue; 62 | 63 | if (cursor->get(&dbkey, &dbvalue, DB_PREV) == 0) 64 | { 65 | if (key.Set((char*)dbkey.get_data(), dbkey.get_size()) && 66 | value.Set((char*)dbvalue.get_data(), dbvalue.get_size())) 67 | return true; 68 | else 69 | return false; 70 | } 71 | else 72 | return false; 73 | } 74 | 75 | bool Cursor::Close() 76 | { 77 | return (cursor->close() == 0); 78 | } 79 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/modindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Global Module Index') %} 3 | {% block extrahead %} 4 | {{ super() }} 5 | {% if not embedded and collapse_modindex %} 6 | 9 | {% endif %} 10 | {% endblock %} 11 | {% block body %} 12 | 13 |

{{ _('Global Module Index') }}

14 | 15 | {%- for letter in letters %} 16 | {{ letter }} {% if not loop.last %}| {% endif %} 17 | {%- endfor %} 18 |
19 | 20 | 21 | {%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} 22 | {%- if not modname -%} 23 | 24 | 25 | {%- else -%} 26 | 27 | 31 | 38 | {%- endif -%} 39 | {% endfor %} 40 |
 
{{ fname }}
{% if collapse -%} 28 | 30 | {%- endif %}{% if indent %}   {% endif %} 32 | {% if fname %}{% endif -%} 33 | {{ stripped|e }}{{ modname|e }} 34 | {%- if fname %}{% endif %} 35 | {%- if pform and pform[0] %} ({{ pform|join(', ') }}){% endif -%} 36 | {% if dep %}{{ _('Deprecated')}}:{% endif %} 37 | {{ synops|e }}
41 | 42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseState.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASESTATE_H 2 | #define PLEASESTATE_H 3 | 4 | #include "System/Platform.h" 5 | #include "System/Buffer.h" 6 | 7 | class PLeaseProposerState 8 | { 9 | public: 10 | bool Active() 11 | { 12 | return (preparing || proposing); 13 | } 14 | 15 | void Init() 16 | { 17 | preparing = false; 18 | proposing = false; 19 | proposalID = 0; 20 | highestReceivedProposalID = 0; 21 | duration = 0; 22 | expireTime = 0; 23 | } 24 | 25 | public: 26 | bool preparing; 27 | bool proposing; 28 | uint64_t proposalID; 29 | uint64_t highestReceivedProposalID; 30 | unsigned leaseOwner; 31 | unsigned duration; 32 | uint64_t expireTime; 33 | 34 | }; 35 | 36 | class PLeaseAcceptorState 37 | { 38 | public: 39 | void Init() 40 | { 41 | promisedProposalID = 0; 42 | 43 | accepted = false; 44 | acceptedProposalID = 0; 45 | acceptedLeaseOwner = 0; 46 | acceptedDuration = 0; 47 | acceptedExpireTime = 0; 48 | } 49 | 50 | void OnLeaseTimeout() 51 | { 52 | accepted = false; 53 | acceptedProposalID = 0; 54 | acceptedLeaseOwner = 0; 55 | acceptedDuration = 0; 56 | acceptedExpireTime = 0; 57 | } 58 | public: 59 | uint64_t promisedProposalID; 60 | bool accepted; 61 | uint64_t acceptedProposalID; 62 | unsigned acceptedLeaseOwner; 63 | unsigned acceptedDuration; 64 | uint64_t acceptedExpireTime; 65 | }; 66 | 67 | class PLeaseLearnerState 68 | { 69 | public: 70 | void Init() 71 | { 72 | learned = 0; 73 | leaseOwner = 0; 74 | expireTime = 0; 75 | leaseEpoch = 0; 76 | } 77 | 78 | void OnLeaseTimeout() 79 | { 80 | learned = 0; 81 | leaseOwner = 0; 82 | expireTime = 0; 83 | leaseEpoch++; 84 | } 85 | 86 | public: 87 | bool learned; 88 | unsigned leaseOwner; 89 | uint64_t expireTime; 90 | uint64_t leaseEpoch; 91 | }; 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/Framework/PaxosLease/PLeaseMsg.h: -------------------------------------------------------------------------------- 1 | #ifndef PLEASEMSG_H 2 | #define PLEASEMSG_H 3 | 4 | #include "System/Buffer.h" 5 | 6 | #define PLEASE_PREPARE_REQUEST '1' 7 | #define PLEASE_PREPARE_REJECTED '2' 8 | #define PLEASE_PREPARE_PREVIOUSLY_ACCEPTED '3' 9 | #define PLEASE_PREPARE_CURRENTLY_OPEN '4' 10 | #define PLEASE_PROPOSE_REQUEST '5' 11 | #define PLEASE_PROPOSE_REJECTED '6' 12 | #define PLEASE_PROPOSE_ACCEPTED '7' 13 | #define PLEASE_LEARN_CHOSEN '8' 14 | 15 | class PLeaseMsg 16 | { 17 | public: 18 | char type; 19 | unsigned nodeID; 20 | uint64_t proposalID; 21 | 22 | uint64_t acceptedProposalID; 23 | unsigned leaseOwner; 24 | unsigned duration; 25 | uint64_t localExpireTime; 26 | uint64_t paxosID; // so only up-to-date nodes can become masters 27 | 28 | void Init(char type_, unsigned nodeID_); 29 | 30 | bool PrepareRequest(unsigned nodeID_, 31 | uint64_t proposalID_, uint64_t paxosID_); 32 | bool PrepareRejected(unsigned nodeID_, uint64_t proposalID_); 33 | bool PreparePreviouslyAccepted(unsigned nodeID_, 34 | uint64_t proposalID_, uint64_t acceptedProposalID_, 35 | unsigned leaseOwner_, unsigned duration_); 36 | bool PrepareCurrentlyOpen(unsigned nodeID_, 37 | uint64_t proposalID_); 38 | bool ProposeRequest(unsigned nodeID_, uint64_t proposalID_, 39 | unsigned leaseOwner_, unsigned duration_); 40 | bool ProposeRejected(unsigned nodeID_, uint64_t proposalID_); 41 | bool ProposeAccepted(unsigned nodeID_, uint64_t proposalID_); 42 | bool LearnChosen(unsigned nodeID, 43 | unsigned leaseOwner_, unsigned duration_, 44 | uint64_t localExpireTime_); 45 | 46 | bool IsRequest(); 47 | bool IsPrepareResponse(); 48 | bool IsProposeResponse(); 49 | bool IsResponse(); 50 | 51 | bool Read(const ByteString& data); 52 | bool Write(ByteString& data); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/Test/IOTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "System/Events/EventLoop.h" 6 | 7 | IOProcessor* ioproc; 8 | ByteArray<32> ba; 9 | FileWrite fw; 10 | FileRead fr; 11 | char c = 'a'; 12 | 13 | void OnFileWrite() 14 | { 15 | if (c++ < 'z') 16 | { 17 | for (int i = 0; i < ba.size - 1; i++) 18 | ba.buffer[i] = c; 19 | ba.buffer[ba.size - 1] = '\n'; 20 | 21 | fw.offset += fw.nbytes; 22 | ioproc->Add(&fw); 23 | } 24 | else 25 | { 26 | exit(0); 27 | } 28 | } 29 | 30 | void OnFileRead() 31 | { 32 | if (fr.data.length < 1) 33 | exit(0); 34 | 35 | printf("%d, %.32s", fr.data.length, fr.data.buffer); 36 | 37 | fr.nbytes = fr.data.size; 38 | fr.offset += fr.data.length; 39 | ioproc->Add(&fr); 40 | } 41 | 42 | int main(int argc, char* argv[]) 43 | { 44 | EventLoop* eventloop; 45 | char* filename = "test.txt"; 46 | #ifdef PLATFORM_DARWIN 47 | const int DIRECT_MODE = 0; 48 | #else 49 | const int DIRECT_MODE = 0; 50 | #endif 51 | 52 | if (argc > 2) 53 | { 54 | filename = argv[1]; 55 | } 56 | 57 | ioproc = IOProcessor::Get(); 58 | eventloop = new EventLoop(ioproc); 59 | 60 | ioproc->Init(); 61 | 62 | for (int i = 0; i < ba.size - 1; i++) 63 | ba.buffer[i] = c; 64 | ba.buffer[ba.size - 1] = '\n'; 65 | ba.length = ba.size; 66 | 67 | if ((fw.fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | DIRECT_MODE, 0600)) < 0) 68 | { 69 | Log_Errno(); 70 | return 1; 71 | } 72 | 73 | fw.data = ba; 74 | fw.nbytes = ba.length; 75 | CFunc onFileWrite(&OnFileWrite); 76 | fw.onComplete = &onFileWrite; 77 | ioproc->Add(&fw); 78 | /* 79 | 80 | if ((fr.fd = open(filename, O_RDONLY)) < 0) 81 | { 82 | Log_Errno(); 83 | return 1; 84 | } 85 | 86 | fr.data = ba; 87 | fr.nbytes = ba.size; 88 | CFunc onFileRead(&OnFileRead); 89 | fr.onComplete = &onFileRead; 90 | ioproc->Add(&fr); 91 | */ 92 | 93 | eventloop->Run(); 94 | } 95 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceServer.cpp: -------------------------------------------------------------------------------- 1 | #include "KeyspaceServer.h" 2 | #include "System/IO/IOProcessor.h" 3 | #include "Framework/ReplicatedLog/ReplicatedLog.h" 4 | 5 | #define KEYSPACE_PORT 7080 6 | #define CONN_BACKLOG 10 7 | 8 | KeyspaceServer::KeyspaceServer() : 9 | onThruputTimeout(this, &KeyspaceServer::OnThruputTimeout), 10 | thruputTimeout(1000, &onThruputTimeout) 11 | { 12 | } 13 | 14 | void KeyspaceServer::Init(KeyspaceDB* kdb_, int port_) 15 | { 16 | if (!TCPServerT 17 | ::Init(port_, CONN_BACKLOG)) 18 | STOP_FAIL("Cannot initialize KeyspaceServer", 1); 19 | kdb = kdb_; 20 | kdb->SetProtocolServer(this); 21 | OnThruputTimeout(); 22 | bytesRead = 0; 23 | } 24 | 25 | void KeyspaceServer::Shutdown() 26 | { 27 | Close(); 28 | } 29 | 30 | void KeyspaceServer::InitConn(KeyspaceConn* conn) 31 | { 32 | conn->Init(kdb, this); 33 | } 34 | 35 | void KeyspaceServer::DeleteConn(KeyspaceConn* conn) 36 | { 37 | TCPServerT 38 | ::DeleteConn(conn); 39 | } 40 | 41 | void KeyspaceServer::OnThruputTimeout() 42 | { 43 | // KeyspaceConn** it; 44 | // 45 | // if (!kdb->IsReplicated()) 46 | // return; 47 | // 48 | // bytesRead = 0; 49 | // 50 | // for (it = activeConns.Head(); it != NULL; it = activeConns.Next(it)) 51 | // { 52 | // (*it)->bytesRead = 0; 53 | // (*it)->Continue(); 54 | // } 55 | // 56 | // EventLoop::Reset(&thruputTimeout); 57 | } 58 | 59 | void KeyspaceServer::OnDataRead(KeyspaceConn* /*conn*/, unsigned /*bytes*/) 60 | { 61 | // uint64_t t; 62 | // 63 | // if (!kdb->IsReplicated()) 64 | // return; 65 | // 66 | // bytesRead += bytes; 67 | // 68 | // t = MAX(2 * RLOG->GetLastRound_Thruput(), KEYSPACE_POOL_MIN_THRUPUT); 69 | // 70 | // if (bytesRead > t && 71 | // conn->bytesRead > KEYSPACE_CONN_MIN_THRUPUT) 72 | // { 73 | // Log_Trace("Throttling connection; bytesRead: %d", bytesRead); 74 | // conn->Stop(); 75 | // } 76 | } 77 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClient/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Keyspace 6 | { 7 | public class Status 8 | { 9 | public const int KEYSPACE_SUCCESS = 0; 10 | public const int KEYSPACE_API_ERROR = -1; 11 | 12 | public const int KEYSPACE_PARTIAL = -101; 13 | public const int KEYSPACE_FAILURE = -102; 14 | 15 | public const int KEYSPACE_NOMASTER = -201; 16 | public const int KEYSPACE_NOCONNECTION = -202; 17 | 18 | public const int KEYSPACE_MASTER_TIMEOUT = -301; 19 | public const int KEYSPACE_GLOBAL_TIMEOUT = -302; 20 | 21 | public const int KEYSPACE_NOSERVICE = -401; 22 | public const int KEYSPACE_FAILED = -402; 23 | 24 | public static string ToString(int status) 25 | { 26 | switch (status) 27 | { 28 | case KEYSPACE_SUCCESS: 29 | return "KEYSPACE_SUCCESS"; 30 | case KEYSPACE_API_ERROR: 31 | return "KEYSPACE_API_ERROR"; 32 | case KEYSPACE_PARTIAL: 33 | return "KEYSPACE_PARTIAL"; 34 | case KEYSPACE_FAILURE: 35 | return "KEYSPACE_FAILURE"; 36 | case KEYSPACE_NOMASTER: 37 | return "KEYSPACE_NOMASTER"; 38 | case KEYSPACE_NOCONNECTION: 39 | return "KEYSPACE_NOCONNECTION"; 40 | case KEYSPACE_MASTER_TIMEOUT: 41 | return "KEYSPACE_MASTER_TIMEOUT"; 42 | case KEYSPACE_GLOBAL_TIMEOUT: 43 | return "KEYSPACE_GLOBAL_TIMEOUT"; 44 | case KEYSPACE_NOSERVICE: 45 | return "KEYSPACE_NOSERVICE"; 46 | case KEYSPACE_FAILED: 47 | return "KEYSPACE_FAILED"; 48 | } 49 | 50 | return ""; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Database/AsyncListVisitor.h: -------------------------------------------------------------------------------- 1 | #ifndef ASYNCLISTVISITOR_H 2 | #define ASYNCLISTVISITOR_H 3 | 4 | #include "System/Events/Callable.h" 5 | #include "System/Buffer.h" 6 | #include "Framework/Database/Table.h" 7 | #include "Framework/AsyncDatabase/MultiDatabaseOp.h" 8 | #include "KeyspaceService.h" 9 | 10 | #define VISITOR_LIMIT 4096 11 | 12 | class AsyncVisitorCallback : public Callable 13 | { 14 | public: 15 | // TODO better initial value 16 | typedef ByteArray KeyBuffer; 17 | typedef DynArray<100 * VISITOR_LIMIT> ValueBuffer; 18 | 19 | ByteString keys[VISITOR_LIMIT]; 20 | unsigned long valuepos[VISITOR_LIMIT]; 21 | unsigned int valuelen[VISITOR_LIMIT]; 22 | KeyBuffer keybuf; 23 | ValueBuffer valuebuf; 24 | uint64_t numkey; 25 | KeyspaceOp* op; 26 | bool complete; 27 | 28 | AsyncVisitorCallback(); 29 | ~AsyncVisitorCallback(); 30 | 31 | void Increment(); 32 | bool AppendKey(const ByteString &key); 33 | bool AppendKeyValue(const ByteString &key, 34 | const ByteString &value); 35 | void Execute(); 36 | }; 37 | 38 | class AsyncListVisitor : public TableVisitor 39 | { 40 | public: 41 | AsyncListVisitor(KeyspaceOp* op_); 42 | 43 | void Init(); 44 | void AppendKey(const ByteString &key); 45 | void AppendKeyValue(const ByteString &key, 46 | const ByteString &value); 47 | virtual bool Accept(const ByteString &key, 48 | const ByteString &value); 49 | virtual const ByteString* GetStartKey(); 50 | virtual void OnComplete(); 51 | virtual bool IsForward(); 52 | 53 | private: 54 | KeyspaceOp* op; 55 | const ByteString &prefix; 56 | DynArray<128> startKey; 57 | uint64_t count; 58 | uint64_t offset; 59 | uint64_t num; 60 | AsyncVisitorCallback* avc; 61 | }; 62 | 63 | class AsyncMultiDatabaseOp : public Callable, public MultiDatabaseOp 64 | { 65 | public: 66 | AsyncMultiDatabaseOp(); 67 | 68 | void Execute(); 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/System/Common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Log.h" 9 | #include "Platform.h" 10 | 11 | #define KB 1000 12 | #define MB 1000000 13 | 14 | #define MEMCMP(b1, l1, b2, l2) ((l1) == (l2) && memcmp((b1), (b2), l1) == 0) 15 | 16 | #define SIZE(a) (sizeof((a)) / sizeof((a[0]))) 17 | 18 | #define ASSERT_FAIL() assert(false) 19 | 20 | #define STOP_FAIL(msg, code) { Log_SetTarget(LOG_TARGET_STDERR|LOG_TARGET_FILE); Log_Message(msg); _exit(code); } 21 | 22 | #define RESTART(msg) { Log_Message(msg); _exit(2); } 23 | 24 | #define CS_INT_SIZE(int_type) ((size_t)(0.30103 * sizeof(int_type) * 8) + 2 + 1) 25 | 26 | #define ABS(a) ((a) > 0 ? (a) : -1*(a)) 27 | 28 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 29 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 30 | 31 | int randint(int min, int max); 32 | 33 | int64_t strntoint64(const char* buffer, int length, unsigned* nread); 34 | 35 | uint64_t strntouint64(const char* buffer, int length, unsigned* nread); 36 | 37 | char* strnchr(const char* s, int c, size_t len); 38 | 39 | char* strrep(char* s, char src, char dst); 40 | 41 | bool DeleteWC(const char* wc); // wildcard support 42 | 43 | const char* rprintf(const char* format, ...); 44 | 45 | void* Alloc(int num, int size = 1); 46 | 47 | inline bool Xor(bool a, bool b, bool c) { return (((int)a + (int)b + (int)c) == 1); } 48 | 49 | inline bool Xor(bool a, bool b) { return Xor(a, b, false); } 50 | 51 | inline unsigned NumLen(int n) 52 | { return n == 0 ? 1 : (unsigned) floor(log10((float)n) + 1); } 53 | 54 | void BlockSignals(); 55 | 56 | bool IsFolder(const char* path); 57 | 58 | int snreadf(char* buffer, unsigned size, const char* format, ...); 59 | int vsnreadf(char* buffer, unsigned size, const char* format, va_list ap); 60 | 61 | int snwritef(char* buffer, unsigned size, const char* format, ...); 62 | int vsnwritef(char* buffer, unsigned size, const char* format, va_list ap); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Protocol/Keyspace/KeyspaceClientResp.cpp: -------------------------------------------------------------------------------- 1 | #include "KeyspaceClientResp.h" 2 | 3 | void KeyspaceClientResp::Ok(uint64_t cmdID_) 4 | { 5 | type = KEYSPACECLIENT_OK; 6 | sendValue = false; 7 | cmdID = cmdID_; 8 | key.length = 0; 9 | value.length = 0; 10 | } 11 | 12 | void KeyspaceClientResp::Ok(uint64_t cmdID_, ByteString value_) 13 | { 14 | type = KEYSPACECLIENT_OK; 15 | sendValue = true; 16 | cmdID = cmdID_; 17 | key.length = 0; 18 | value.Set(value_); 19 | } 20 | 21 | void KeyspaceClientResp::Failed(uint64_t cmdID_) 22 | { 23 | type = KEYSPACECLIENT_FAILED; 24 | sendValue = false; 25 | cmdID = cmdID_; 26 | key.length = 0; 27 | value.length = 0; 28 | } 29 | 30 | void KeyspaceClientResp::NotMaster(uint64_t cmdID_) 31 | { 32 | type = KEYSPACECLIENT_NOT_MASTER; 33 | sendValue = false; 34 | cmdID = cmdID_; 35 | key.length = 0; 36 | value.length = 0; 37 | } 38 | 39 | void KeyspaceClientResp::ListItem(uint64_t cmdID_, ByteString key_) 40 | { 41 | type = KEYSPACECLIENT_LIST_ITEM; 42 | sendValue = false; 43 | cmdID = cmdID_; 44 | key.Set(key_); 45 | value.length = 0; 46 | } 47 | 48 | void KeyspaceClientResp::ListPItem(uint64_t cmdID_, 49 | ByteString key_, ByteString value_) 50 | { 51 | type = KEYSPACECLIENT_LISTP_ITEM; 52 | sendValue = true; 53 | cmdID = cmdID_; 54 | key.Set(key_); 55 | value.Set(value_); 56 | } 57 | 58 | void KeyspaceClientResp::ListEnd(uint64_t cmdID_) 59 | { 60 | type = KEYSPACECLIENT_LIST_END; 61 | sendValue = false; 62 | cmdID = cmdID_; 63 | key.length = 0; 64 | value.length = 0; 65 | } 66 | 67 | bool KeyspaceClientResp::Write(ByteString& data) 68 | { 69 | if (key.length > 0 && sendValue) 70 | return data.Writef("%c:%U:%M:%M", 71 | type, cmdID, &key, &value); 72 | else if (key.length > 0) 73 | return data.Writef("%c:%U:%M", 74 | type, cmdID, &key); 75 | else if (sendValue) 76 | return data.Writef("%c:%U:%M", 77 | type, cmdID, &value); 78 | else 79 | return data.Writef("%c:%U", 80 | type, cmdID); 81 | } 82 | -------------------------------------------------------------------------------- /doc/Sphinx/source/keyspace/genindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 | {% for key, dummy in genindexentries -%} 8 | {{ key }} {% if not loop.last %}| {% endif %} 9 | {%- endfor %} 10 | 11 |
12 | 13 | {% for key, entries in genindexentries %} 14 |

{{ key }}

15 |
16 |
17 | {%- set breakat = genindexcounts[loop.index0] // 2 %} 18 | {%- set numcols = 1 %} 19 | {%- set numitems = 0 %} 20 | {% for entryname, (links, subitems) in entries %} 21 |
{%- if links -%}{{ entryname|e }} 22 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 23 | {%- else -%} 24 | {{ entryname|e }} 25 | {%- endif -%}
26 | {%- if subitems %} 27 |
28 | {%- for subentryname, subentrylinks in subitems %} 29 |
{{ subentryname|e }} 30 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 31 |
32 | {%- endfor %} 33 |
34 | {%- endif -%} 35 | {%- set numitems = numitems + 1 + (subitems|length) -%} 36 | {%- if numcols < 2 and numitems > breakat -%} 37 | {%- set numcols = numcols+1 -%} 38 |
39 | {%- endif -%} 40 | {%- endfor %} 41 |
42 | {% endfor %} 43 | 44 | {% endblock %} 45 | 46 | {% block sidebarrel %} 47 | {% if split_index %} 48 |

{{ _('Index') }}

49 |

{% for key, dummy in genindexentries -%} 50 | {{ key }} 51 | {% if not loop.last %}| {% endif %} 52 | {%- endfor %}

53 | 54 |

{{ _('Full index on one page') }}

55 | {% endif %} 56 | {{ super() }} 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/imaxdiv_t.cs: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 2.0.0 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | 10 | using System; 11 | using System.Runtime.InteropServices; 12 | 13 | public class imaxdiv_t : IDisposable { 14 | private HandleRef swigCPtr; 15 | protected bool swigCMemOwn; 16 | 17 | internal imaxdiv_t(IntPtr cPtr, bool cMemoryOwn) { 18 | swigCMemOwn = cMemoryOwn; 19 | swigCPtr = new HandleRef(this, cPtr); 20 | } 21 | 22 | internal static HandleRef getCPtr(imaxdiv_t obj) { 23 | return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; 24 | } 25 | 26 | ~imaxdiv_t() { 27 | Dispose(); 28 | } 29 | 30 | public virtual void Dispose() { 31 | lock(this) { 32 | if (swigCPtr.Handle != IntPtr.Zero) { 33 | if (swigCMemOwn) { 34 | swigCMemOwn = false; 35 | keyspace_clientPINVOKE.delete_imaxdiv_t(swigCPtr); 36 | } 37 | swigCPtr = new HandleRef(null, IntPtr.Zero); 38 | } 39 | GC.SuppressFinalize(this); 40 | } 41 | } 42 | 43 | public long quot { 44 | set { 45 | keyspace_clientPINVOKE.imaxdiv_t_quot_set(swigCPtr, value); 46 | } 47 | get { 48 | long ret = keyspace_clientPINVOKE.imaxdiv_t_quot_get(swigCPtr); 49 | return ret; 50 | } 51 | } 52 | 53 | public long rem { 54 | set { 55 | keyspace_clientPINVOKE.imaxdiv_t_rem_set(swigCPtr, value); 56 | } 57 | get { 58 | long ret = keyspace_clientPINVOKE.imaxdiv_t_rem_get(swigCPtr); 59 | return ret; 60 | } 61 | } 62 | 63 | public imaxdiv_t() : this(keyspace_clientPINVOKE.new_imaxdiv_t(), true) { 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/Application/HTTP/HttpFileHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "HttpFileHandler.h" 2 | #include "HttpConsts.h" 3 | #include "Mime.h" 4 | 5 | #include 6 | 7 | typedef DynArray<128> HeaderArray; 8 | void HttpHeaderAppend(HeaderArray& ha, const char* k, size_t klen, const char* v, size_t vlen) 9 | { 10 | ha.Append(k, klen); 11 | ha.Append(": ", 2); 12 | ha.Append(v, vlen); 13 | ha.Append(HTTP_CS_CRLF, 2); 14 | } 15 | 16 | HttpFileHandler::HttpFileHandler(const char* docroot, const char* prefix_) 17 | { 18 | documentRoot = docroot; 19 | prefix = prefix_; 20 | } 21 | 22 | bool HttpFileHandler::HandleRequest(HttpConn* conn, const HttpRequest& request) 23 | { 24 | DynArray<128> path; 25 | DynArray<128> tmp; 26 | DynArray<128> ha; 27 | char buf[128 * 1024]; 28 | FILE* fp; 29 | size_t nread; 30 | size_t fsize; 31 | const char* mimeType; 32 | 33 | if (strncmp(request.line.uri, prefix, strlen(prefix))) 34 | return false; 35 | 36 | path.Writef("%s%s", documentRoot, request.line.uri); 37 | path.Append("", 1); 38 | 39 | mimeType = MimeTypeFromExtension(strrchr(path.buffer, '.')); 40 | 41 | fp = fopen(path.buffer, "rb"); 42 | if (!fp) 43 | return false; 44 | 45 | fseek(fp, 0L, SEEK_END); 46 | fsize = ftell(fp); 47 | fseek(fp, 0L, SEEK_SET); 48 | 49 | HttpHeaderAppend(ha, 50 | HTTP_HEADER_CONTENT_TYPE, sizeof(HTTP_HEADER_CONTENT_TYPE) - 1, 51 | mimeType, strlen(mimeType)); 52 | 53 | tmp.Writef("%u", fsize); 54 | HttpHeaderAppend(ha, 55 | HTTP_HEADER_CONTENT_LENGTH, sizeof(HTTP_HEADER_CONTENT_LENGTH) - 1, 56 | tmp.buffer, tmp.length); 57 | 58 | // zero-terminate 59 | ha.Append("", 1); 60 | 61 | conn->ResponseHeader(HTTP_STATUS_CODE_OK, ha.buffer); 62 | 63 | while (true) 64 | { 65 | nread = fread(buf, 1, sizeof(buf), fp); 66 | if (feof(fp)) 67 | { 68 | fclose(fp); 69 | conn->Write(buf, nread, true); 70 | break; 71 | } 72 | if (ferror(fp)) 73 | { 74 | fclose(fp); 75 | break; 76 | } 77 | 78 | conn->Write(buf, nread); 79 | } 80 | 81 | conn->Flush(); 82 | return true; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /doc/FSFConf/FSFConf.aux: -------------------------------------------------------------------------------- 1 | \relax 2 | \catcode 096=12 3 | \catcode``\active 4 | \select@language{hungarian} 5 | \@writefile{toc}{\select@language{hungarian}} 6 | \@writefile{lof}{\select@language{hungarian}} 7 | \@writefile{lot}{\select@language{hungarian}} 8 | \select@language{english} 9 | \@writefile{toc}{\select@language{english}} 10 | \@writefile{lof}{\select@language{english}} 11 | \@writefile{lot}{\select@language{english}} 12 | \select@language{hungarian} 13 | \@writefile{toc}{\select@language{hungarian}} 14 | \@writefile{lof}{\select@language{hungarian}} 15 | \@writefile{lot}{\select@language{hungarian}} 16 | \@writefile{toc}{\contentsline {section}{\numberline {1.} Bevezet\'es }{1}} 17 | \citation{SharedNothing} 18 | \citation{CAP} 19 | \@writefile{toc}{\contentsline {section}{\numberline {2.} Elosztott rendszerek alapelvei }{2}} 20 | \@writefile{lof}{\contentsline {figure}{\numberline {1.}{\ignorespaces A CAP h\'aromsz\"og.}}{2}} 21 | \citation{Chubby} 22 | \citation{GFS} 23 | \citation{MapReduce} 24 | \citation{Bigtable} 25 | \citation{PaxosMadeSimple} 26 | \@writefile{toc}{\contentsline {section}{\numberline {3.} A Google architekt\'ur\'aja }{3}} 27 | \citation{Dynamo} 28 | \@writefile{toc}{\contentsline {section}{\numberline {4.} Amazon Dynamo }{4}} 29 | \@writefile{toc}{\contentsline {section}{\numberline {5.} Scalien Keyspace }{5}} 30 | \@writefile{lot}{\contentsline {table}{\numberline {1.}{\ignorespaces Rendelkez\'esre \'all\'as k\"ul\"onb\"oz\H o m\'eret\H u Keyspace cell\'ak eset\'eben. }}{5}} 31 | \@writefile{lof}{\contentsline {figure}{\numberline {2.}{\ignorespaces Keyspace bulk adat\'atviteli sebess\'egek.}}{6}} 32 | \bibcite{SharedNothing}{1} 33 | \bibcite{CAP}{2} 34 | \bibcite{PaxosMadeSimple}{3} 35 | \bibcite{Chubby}{4} 36 | \@writefile{toc}{\contentsline {section}{\numberline {6.} M\'as ny\IeC {\'\i }lt forr\'ask\'od\'u elosztott rendszerek }{7}} 37 | \@writefile{toc}{\contentsline {section}{\numberline {7.} Konkl\'uzi\'o }{7}} 38 | \bibcite{GFS}{5} 39 | \bibcite{MapReduce}{6} 40 | \bibcite{Bigtable}{7} 41 | \bibcite{Dynamo}{8} 42 | \bibcite{Keyspace}{9} 43 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 1.6.0 2 | ===== 3 | 4 | - New SWIG based client libraries, starting with Python 5 | 6 | - New and improved documentation 7 | 8 | - Safe script no longer necessary for proper catchup 9 | 10 | - Changes in configuration file 11 | 12 | 13 | 1.5.1 14 | ===== 15 | 16 | - Fixed catchup bug. 17 | 18 | 19 | 1.5.0 20 | ===== 21 | 22 | - Fixed many small issues, ready for production use 23 | 24 | 25 | 1.4.2 26 | ===== 27 | 28 | - Fixed Windows IOProcessor bug 29 | 30 | 31 | 1.4.1 32 | ===== 33 | 34 | - Windows performance improvements 35 | 36 | - Fixed bugs and memory leak issues 37 | 38 | 39 | 1.4 40 | === 41 | 42 | - New and improved C++ client library 43 | 44 | - Changed the C API interface to match the C++ library 45 | 46 | - Changed PaxosLease protocol from UDP to TCP 47 | 48 | 49 | 1.3.2 50 | ===== 51 | 52 | - Added library project to Visual Studio solution file 53 | 54 | 55 | 1.3.1 56 | ===== 57 | 58 | - Minor fixes to Windows version 59 | 60 | 61 | 1.3 62 | === 63 | 64 | - Windows version 65 | 66 | 67 | 1.2 68 | === 69 | 70 | - Relicensed under the permissive BSD licence 71 | 72 | - New JSON API 73 | 74 | - Added Python client API 75 | 76 | - Added PHP client API 77 | 78 | 79 | 1.1 80 | === 81 | 82 | - New PaxosLease algorithm does not require clock synchronization (!). 83 | 84 | - Added COUNT and DIRTYCOUNT command. 85 | 86 | - Added /html/ part to HTTP interface, which pretty prints the list output. 87 | 88 | - Added possibility to reverse list direction. 89 | 90 | - The http://server/ prints the version number and master information. 91 | 92 | - Added database.numReaders config option. 93 | 94 | 95 | 1.0.1 96 | ===== 97 | 98 | - Keyspace would not start without a config file in default mode. Resolution: fixed. 99 | 100 | - Keyspace printed a non-informative error message when a directory 'keyspace' was present and it tried to create the database file 'keyspace'. Resolution: More informative error message. 101 | 102 | - Some Linux optimizations were accidentally removed in the 1.0 release. Resolution: added to 1.0.1 103 | -------------------------------------------------------------------------------- /src/Application/Keyspace/Client/CSharp/KeyspaceClient/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Keyspace 6 | { 7 | public class Result 8 | { 9 | private SWIGTYPE_p_void cptr; 10 | 11 | public Result(SWIGTYPE_p_void cptr) 12 | { 13 | this.cptr = cptr; 14 | } 15 | 16 | ~Result() 17 | { 18 | keyspace_client.Keyspace_ResultClose(cptr); 19 | } 20 | 21 | public string GetKey() 22 | { 23 | return keyspace_client.Keyspace_ResultKey(cptr); 24 | } 25 | 26 | public string GetValue() 27 | { 28 | return keyspace_client.Keyspace_ResultValue(cptr); 29 | } 30 | 31 | public void Begin() 32 | { 33 | keyspace_client.Keyspace_ResultBegin(cptr); 34 | } 35 | 36 | public void Next() 37 | { 38 | keyspace_client.Keyspace_ResultNext(cptr); 39 | } 40 | 41 | public bool IsEnd() 42 | { 43 | return keyspace_client.Keyspace_ResultIsEnd(cptr); 44 | } 45 | 46 | public int GetTransportStatus() 47 | { 48 | return keyspace_client.Keyspace_ResultTransportStatus(cptr); 49 | } 50 | 51 | public int GetConnectivityStatus() 52 | { 53 | return keyspace_client.Keyspace_ResultConnectivityStatus(cptr); 54 | } 55 | 56 | public int GetTimeoutStatus() 57 | { 58 | return keyspace_client.Keyspace_ResultTimeoutStatus(cptr); 59 | } 60 | 61 | public int GetCommandStatus() 62 | { 63 | return keyspace_client.Keyspace_ResultCommandStatus(cptr); 64 | } 65 | 66 | public Dictionary GetKeyValues() 67 | { 68 | Dictionary keyvals = new Dictionary(); 69 | for (Begin(); !IsEnd(); Next()) 70 | keyvals.Add(GetKey(), GetValue()); 71 | 72 | return keyvals; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/System/Platform.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_H 2 | #define PLATFORM_H 3 | 4 | #ifdef _WIN32 5 | //#define _WIN32_WINNT 0x0400 // Windows NT 4.0 6 | //#define WIN32_LEAN_AND_MEAN 7 | 8 | #include // for intptr_t 9 | #include // for _alloca() 10 | 11 | #pragma warning(disable: 4244) // conversion to smaller type, possible loss of data 12 | #pragma warning(disable: 4267) // conversion from size_t to smaller type, possible loss of data 13 | #pragma warning(disable: 4355) // 'this' : used in base member initializer list 14 | 15 | // VC++ 8.0 is not C99-compatible 16 | typedef __int8 int8_t; 17 | typedef __int16 int16_t; 18 | typedef __int32 int32_t; 19 | typedef __int64 int64_t; 20 | 21 | typedef unsigned __int8 uint8_t; 22 | typedef unsigned __int16 uint16_t; 23 | typedef unsigned __int32 uint32_t; 24 | typedef unsigned __int64 uint64_t; 25 | 26 | #define snprintf _snprintf 27 | #define strdup _strdup 28 | 29 | // 64bit compatible format string specifiers according to this document 30 | // http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx 31 | #define PRIu64 "I64i" 32 | #define PRIi64 "I64i" 33 | 34 | #define alloca _alloca 35 | #define alloca16(x) ((void *)((((intptr_t)alloca((x) + 15)) + 15) & ~15)) 36 | 37 | #define localtime_r(t, tm) localtime_s(tm, t) 38 | 39 | 40 | #else 41 | #include 42 | #include 43 | #include 44 | #endif 45 | 46 | // PLATFORM_STRING selection 47 | #ifdef PLATFORM_WINDOWS 48 | 49 | #ifdef _WIN64 50 | #define PLATFORM_STRING "Windows 64bit" 51 | #else 52 | #define PLATFORM_STRING "Windows" 53 | #endif 54 | 55 | #else 56 | 57 | #ifdef PLATFORM_LINUX 58 | #ifdef __amd64__ 59 | #define PLATFORM_STRING "Linux 64bit" 60 | #else 61 | #define PLATFORM_STRING "Linux" 62 | #endif 63 | #endif 64 | 65 | #ifdef PLATFORM_DARWIN 66 | #ifdef __amd64__ 67 | #define PLATFORM_STRING "Darwin 64bit" 68 | #else 69 | #define PLATFORM_STRING "Darwin" 70 | #endif 71 | #endif 72 | 73 | #endif 74 | 75 | bool ChangeUser(const char *username); 76 | uint64_t GetMicroTimestamp(); 77 | uint64_t GetMilliTimestamp(); 78 | 79 | #endif 80 | --------------------------------------------------------------------------------