summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE.itoa_ljust39
-rw-r--r--Makefile.am3
-rw-r--r--itoa_ljust.c149
-rw-r--r--itoa_ljust.h28
-rw-r--r--memcached.h1
5 files changed, 219 insertions, 1 deletions
diff --git a/LICENSE.itoa_ljust b/LICENSE.itoa_ljust
new file mode 100644
index 0000000..c5a0bca
--- /dev/null
+++ b/LICENSE.itoa_ljust
@@ -0,0 +1,39 @@
+Copyright (c) 2016, Arturo Martin-de-Nicolas
+arturomdn@gmail.com
+https://github.com/amdn/itoa_ljust/
+All rights reserved.
+
+This implementation is loosely based on the structure of FastInt32ToBufferLeft
+in:
+
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc. All rights reserved.
+https://developers.google.com/protocol-buffers/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+* Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile.am b/Makefile.am
index 2352301..8b79525 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,7 +21,8 @@ memcached_SOURCES = memcached.c memcached.h \
trace.h cache.h sasl_defs.h \
bipbuffer.c bipbuffer.h \
logger.c logger.h \
- crawler.c crawler.h
+ crawler.c crawler.h \
+ itoa_ljust.c itoa_ljust.h
if BUILD_CACHE
memcached_SOURCES += cache.c
diff --git a/itoa_ljust.c b/itoa_ljust.c
new file mode 100644
index 0000000..4ed9267
--- /dev/null
+++ b/itoa_ljust.c
@@ -0,0 +1,149 @@
+//=== itoa_ljust.cpp - Fast integer to ascii conversion --*- C++ -*-//
+//
+// Substantially simplified (and slightly faster) version
+// based on the following functions in Google's protocol buffers:
+//
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Differences:
+// 1) Greatly simplified
+// 2) Avoids GOTO statements - uses "switch" instead and relies on
+// compiler constant folding and propagation for high performance
+// 3) Avoids unary minus of signed types - undefined behavior if value
+// is INT_MIN in platforms using two's complement representation
+// 4) Uses memcpy to store 2 digits at a time - lets the compiler
+// generate a 2-byte load/store in platforms that support
+// unaligned access, this is faster (and less code) than explicitly
+// loading and storing each byte
+//
+// Copyright (c) 2016 Arturo Martin-de-Nicolas
+// arturomdn@gmail.com
+// https://github.com/amdn/itoa_ljust/
+//
+// Released under the BSD 3-Clause License, see Google's original copyright
+// and license below.
+//===----------------------------------------------------------------------===//
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===----------------------------------------------------------------------===//
+
+#include "itoa_ljust.h"
+#include <string.h>
+
+static const char lut[201] =
+ "0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899";
+
+#define dd(u) ((const uint16_t)(lut[u]))
+
+static inline char* out2(const int d, char* p) {
+ memcpy(p, &((uint16_t *)lut)[d], 2);
+ return p + 2;
+}
+
+static inline char* out1(const char in, char* p) {
+ memcpy(p, &in, 1);
+ return p + 1;
+}
+
+static inline int digits( uint32_t u, unsigned k, int* d, char** p, int n ) {
+ if (u < k*10) {
+ *d = u / k;
+ *p = out1('0'+*d, *p);
+ --n;
+ }
+ return n;
+}
+
+static inline char* itoa(uint32_t u, char* p, int d, int n) {
+ switch(n) {
+ case 10: d = u / 100000000; p = out2( d, p );
+ case 9: u -= d * 100000000;
+ case 8: d = u / 1000000; p = out2( d, p );
+ case 7: u -= d * 1000000;
+ case 6: d = u / 10000; p = out2( d, p );
+ case 5: u -= d * 10000;
+ case 4: d = u / 100; p = out2( d, p );
+ case 3: u -= d * 100;
+ case 2: d = u / 1; p = out2( d, p );
+ case 1: ;
+ }
+ *p = '\0';
+ return p;
+}
+
+char* itoa_u32(uint32_t u, char* p) {
+ int d,n;
+ if (u >=100000000) n = digits(u, 100000000, &d, &p, 10);
+ else if (u < 100) n = digits(u, 1, &d, &p, 2);
+ else if (u < 10000) n = digits(u, 100, &d, &p, 4);
+ else if (u < 1000000) n = digits(u, 10000, &d, &p, 6);
+ else n = digits(u, 1000000, &d, &p, 8);
+ return itoa( u, p, d, n );
+}
+
+char* itoa_32(int32_t i, char* p) {
+ uint32_t u = i;
+ if (i < 0) {
+ *p++ = '-';
+ u = -u;
+ }
+ return itoa_u32(u, p);
+}
+
+char* itoa_u64(uint64_t u, char* p) {
+ int d;
+
+ uint32_t lower = (uint32_t)u;
+ if (lower == u) return itoa_u32(lower, p);
+
+ uint64_t upper = u / 1000000000;
+ p = itoa_u64(upper, p);
+ lower = u - (upper * 1000000000);
+ d = lower / 100000000;
+ p = out1('0'+d,p);
+ return itoa( lower, p, d, 9 );
+}
+
+char* itoa_64(int64_t i, char* p) {
+ uint64_t u = i;
+ if (i < 0) {
+ *p++ = '-';
+ u = -u;
+ }
+ return itoa_u64(u, p);
+}
diff --git a/itoa_ljust.h b/itoa_ljust.h
new file mode 100644
index 0000000..18fc94d
--- /dev/null
+++ b/itoa_ljust.h
@@ -0,0 +1,28 @@
+#ifndef ITOA_LJUST_H
+#define ITOA_LJUST_H
+
+//=== itoa_ljust.h - Fast integer to ascii conversion
+//
+// Fast and simple integer to ASCII conversion:
+//
+// - 32 and 64-bit integers
+// - signed and unsigned
+// - user supplied buffer must be large enough for all decimal digits
+// in value plus minus sign if negative
+// - left-justified
+// - NUL terminated
+// - return value is pointer to NUL terminator
+//
+// Copyright (c) 2016 Arturo Martin-de-Nicolas
+// arturomdn@gmail.com
+// https://github.com/amdn/itoa_ljust/
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+char* itoa_u32(uint32_t u, char* buffer);
+char* itoa_32( int32_t i, char* buffer);
+char* itoa_u64(uint64_t u, char* buffer);
+char* itoa_64( int64_t i, char* buffer);
+
+#endif // ITOA_LJUST_H
diff --git a/memcached.h b/memcached.h
index 567bcfa..a8d0014 100644
--- a/memcached.h
+++ b/memcached.h
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <assert.h>
+#include "itoa_ljust.h"
#include "protocol_binary.h"
#include "cache.h"
#include "logger.h"