Merge branch 'master' of github.com:msgpack/msgpack

This commit is contained in:
FURUHASHI Sadayuki 2011-06-26 22:52:06 +09:00
commit 255bac642d
10 changed files with 125 additions and 24 deletions

View File

@ -5,7 +5,7 @@ Extremely efficient object serialization library. It's like JSON, but very fast
## What's MessagePack? ## What's MessagePack?
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. **MessagePack** is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.
Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows: Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows:
@ -13,25 +13,30 @@ Typical small integer (like flags or error code) is saved only in 1 byte, and ty
msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03" msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
MessagePack.unpack(msg) #=> [1,2,3] MessagePack.unpack(msg) #=> [1,2,3]
**MessagePack-RPC** is cross-language RPC library for client, server and cluster applications. Because it releases you from complicated network programming completely and provides well-designed API, you can easily implement advanced network applications with MessagePack-RPC.
## Performance require 'msgpack/rpc'
class MyHandler
def add(x,y) return x+y end
end
svr = MessagePack::RPC::Server.new
svr.listen('0.0.0.0', 18800, MyHandler.new)
svr.run
![Serialization + Deserialization Speed Test](http://msgpack.sourceforge.net/index/speedtest.png) require 'msgpack/rpc'
c = MessagePack::RPC::Client.new('127.0.0.1',18800)
In this test, it measured the elapsed time of serializing and deserializing 200,000 target objects. The target object consists of the three integers and 512 bytes string. result = c.call(:add, 1, 2) #=> 3
The source code of this test is available from [frsyuki' serializer-speed-test repository.](http://github.com/frsyuki/serializer-speed-test)
## Getting Started ## Getting Started
Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/) Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.org/)
## Learn More ## Learn More
- [Project Web Site](http://msgpack.sourceforge.net/) - [Web Site](http://msgpack.org/)
- [MessagePack format specification](http://msgpack.sourceforge.net/spec) - [Wiki](http://wiki.msgpack.org/display/MSGPACK/Home)
- [Repository at github](http://github.com/msgpack/msgpack) - [Issues](http://jira.msgpack.org/browse/MSGPACK)
- [Wiki](http://msgpack.sourceforge.net/start) - [Sources](https://github.com/msgpack)
- [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc)

View File

@ -16,7 +16,7 @@ AC_PROG_CC
AC_MSG_CHECKING([if C++ API is enabled]) AC_MSG_CHECKING([if C++ API is enabled])
AC_ARG_ENABLE(cxx, AC_ARG_ENABLE(cxx,
AS_HELP_STRING([--disable-cxx], AS_HELP_STRING([--disable-cxx],
[don't build C++ API]) ) [don't build C++ API]) ) #'
AC_MSG_RESULT([$enable_cxx]) AC_MSG_RESULT([$enable_cxx])
if test "$enable_cxx" != "no"; then if test "$enable_cxx" != "no"; then
AC_PROG_CXX AC_PROG_CXX
@ -50,17 +50,41 @@ AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [
], [], msgpack_cv_atomic_ops="yes") ], [], msgpack_cv_atomic_ops="yes")
]) ])
if test "$msgpack_cv_atomic_ops" != "yes"; then if test "$msgpack_cv_atomic_ops" != "yes"; then
AC_MSG_ERROR([__sync_* atomic operations are not supported. if test "$enable_cxx" = "no"; then
AC_MSG_ERROR([__sync_* atomic operations are not found. Try to enable C++ support.
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
Note that gcc < 4.1 is not supported. $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
])
fi
AC_LANG_PUSH([C++])
AC_CACHE_CHECK([for __gnu_cxx::__exchange_and_add], msgpack_cv_gcc_cxx_atomic_ops, [
AC_TRY_LINK([
#include <bits/atomicity.h>
int atomic_sub(int i) { return __gnu_cxx::__exchange_and_add(&i, -1); }
int atomic_add(int i) { return __gnu_cxx::__exchange_and_add(&i, 1); }
], [], msgpack_cv_gcc_cxx_atomic_ops="yes")
])
AC_LANG_POP([C++])
if test "$msgpack_cv_gcc_cxx_atomic_ops" != "yes"; then
AC_MSG_ERROR([__sync_* atomic operations nor __gnu_cxx::__exchange_and_add are not found.
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows: add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
]) ])
else
enable_gcc_cxx_atomic=yes
fi
fi fi
AM_CONDITIONAL(ENABLE_GCC_CXX_ATOMIC, test "$enable_gcc_cxx_atomic" = "yes")
major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`

View File

@ -13,6 +13,12 @@ libmsgpack_la_SOURCES += \
object.cpp object.cpp
endif endif
if ENABLE_GCC_CXX_ATOMIC
libmsgpack_la_SOURCES += \
gcc_atomic.cpp
endif
# -version-info CURRENT:REVISION:AGE # -version-info CURRENT:REVISION:AGE
libmsgpack_la_LDFLAGS = -version-info 3:0:0 libmsgpack_la_LDFLAGS = -version-info 3:0:0

17
cpp/src/gcc_atomic.cpp Normal file
View File

@ -0,0 +1,17 @@
#if defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41)
#include "gcc_atomic.h"
#include <bits/atomicity.h>
int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr)
{
return __gnu_cxx::__exchange_and_add(ptr, -1);
}
int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr)
{
return __gnu_cxx::__exchange_and_add(ptr, 1);
}
#endif // old gcc workaround

33
cpp/src/gcc_atomic.h Normal file
View File

@ -0,0 +1,33 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_GCC_ATOMIC_H__
#define MSGPACK_GCC_ATOMIC_H__
#if defined(__cplusplus)
extern "C" {
#endif
typedef int _msgpack_atomic_counter_t;
int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr);
int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr);
#if defined(__cplusplus)
}
#endif
#endif // MSGPACK_GCC_ATOMIC_H__

View File

@ -3,7 +3,7 @@
<info organisation="org" <info organisation="org"
module="${name}" revision="${version}"> module="${name}" revision="${version}">
<ivyauthor name="MessagePack Project" url="http://msgpack.sourceforge.net/"/> <ivyauthor name="MessagePack Project" url="http://msgpack.org/"/>
<description>MessagePack</description> <description>MessagePack</description>
</info> </info>

View File

@ -36,19 +36,19 @@ typedef unsigned __int64 uint64_t;
#include <stdbool.h> #include <stdbool.h>
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#define _msgpack_atomic_counter_header <windows.h> #define _msgpack_atomic_counter_header <windows.h>
typedef long _msgpack_atomic_counter_t; typedef long _msgpack_atomic_counter_t;
#define _msgpack_sync_decr_and_fetch(ptr) InterlockedDecrement(ptr) #define _msgpack_sync_decr_and_fetch(ptr) InterlockedDecrement(ptr)
#define _msgpack_sync_incr_and_fetch(ptr) InterlockedIncrement(ptr) #define _msgpack_sync_incr_and_fetch(ptr) InterlockedIncrement(ptr)
#elif defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41)
#define _msgpack_atomic_counter_header "gcc_atomic.h"
#else #else
typedef unsigned int _msgpack_atomic_counter_t; typedef unsigned int _msgpack_atomic_counter_t;
#define _msgpack_sync_decr_and_fetch(ptr) __sync_sub_and_fetch(ptr, 1) #define _msgpack_sync_decr_and_fetch(ptr) __sync_sub_and_fetch(ptr, 1)
#define _msgpack_sync_incr_and_fetch(ptr) __sync_add_and_fetch(ptr, 1) #define _msgpack_sync_incr_and_fetch(ptr) __sync_add_and_fetch(ptr, 1)
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#ifdef __cplusplus #ifdef __cplusplus
@ -141,9 +141,25 @@ typedef unsigned int _msgpack_atomic_counter_t;
do { uint64_t val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0) do { uint64_t val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0)
#define _msgpack_load16(cast, from) ((cast)_msgpack_be16(*(uint16_t*)from)) #define _msgpack_load16(cast, from) ((cast)_msgpack_be16( \
#define _msgpack_load32(cast, from) ((cast)_msgpack_be32(*(uint32_t*)from)) (((uint8_t*)from)[1] << 8) | ((uint8_t*)from)[0]))
#define _msgpack_load64(cast, from) ((cast)_msgpack_be64(*(uint64_t*)from))
#define _msgpack_load32(cast, from) ((cast)_msgpack_be32( \
(((uint8_t*)from)[3] << 24) | \
(((uint8_t*)from)[2] << 16) | \
(((uint8_t*)from)[1] << 8) | \
(((uint8_t*)from)[0] ) ))
#define _msgpack_load64(cast, from) ((cast)_msgpack_be64( \
(((uint64_t)(((uint8_t*)from)[7])) << 56) | \
(((uint64_t)(((uint8_t*)from)[6])) << 48) | \
(((uint64_t)(((uint8_t*)from)[5])) << 40) | \
(((uint64_t)(((uint8_t*)from)[4])) << 32) | \
(((uint64_t)((uint8_t*)from)[3]) << 24) | \
(((uint64_t)((uint8_t*)from)[2]) << 16) | \
(((uint64_t)((uint8_t*)from)[1]) << 8) | \
(((uint8_t*)from)[0] )))
#endif /* msgpack/sysdep.h */ #endif /* msgpack/sysdep.h */

View File

@ -8,4 +8,4 @@ But unlike JSON, it is very fast and small.
Resources Resources
--------- ---------
* [msgpack](http://msgpack.sourceforge.net/) * [msgpack](http://msgpack.org/)

View File

@ -4,7 +4,7 @@
New feature New feature
----------- -----------
* Add ``encoding`` and ``unicode_erros`` option to packer and unpacker. * Add ``encoding`` and ``unicode_errors`` option to packer and unpacker.
When this option is specified, (un)packs unicode object instead of bytes. When this option is specified, (un)packs unicode object instead of bytes.
This enables using msgpack as a replacement of json. This enables using msgpack as a replacement of json.

View File

@ -6,7 +6,7 @@ Gem::Specification.new do |s|
s.summary = "MessagePack, a binary-based efficient data interchange format." s.summary = "MessagePack, a binary-based efficient data interchange format."
s.author = "FURUHASHI Sadayuki" s.author = "FURUHASHI Sadayuki"
s.email = "frsyuki@users.sourceforge.jp" s.email = "frsyuki@users.sourceforge.jp"
s.homepage = "http://msgpack.sourceforge.net/" s.homepage = "http://msgpack.org/"
s.rubyforge_project = "msgpack" s.rubyforge_project = "msgpack"
s.has_rdoc = true s.has_rdoc = true
s.rdoc_options = ["ext"] s.rdoc_options = ["ext"]