├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── README.md ├── apps ├── swiftclient │ ├── account.h │ ├── container.h │ ├── object.h │ ├── swiftclient.cpp │ ├── swiftclient.h │ ├── swiftclient.inl │ └── util.hpp └── test │ └── swiftclient │ ├── CMakeLists.txt │ ├── main.cpp │ ├── test_account.cpp │ ├── test_container.cpp │ ├── test_object.cpp │ └── test_swiftclient.cpp ├── build.sh ├── swift ├── base │ ├── CMakeLists.txt │ ├── blockingqueue.h │ ├── bytebuffer.cpp │ ├── bytebuffer.h │ ├── byteorderhelper.h │ ├── crc32.cpp │ ├── crc32.h │ ├── date.cpp │ ├── date.h │ ├── exception.cpp │ ├── exception.h │ ├── experimental │ │ ├── logfile.cpp │ │ ├── logfile.h │ │ ├── logging.cpp │ │ ├── logging.h │ │ ├── logstream.cpp │ │ └── logstream.h │ ├── file.cpp │ ├── file.h │ ├── fileutil.cpp │ ├── fileutil.h │ ├── guid.cpp │ ├── guid.h │ ├── likely.h │ ├── linkedhashmap.cpp │ ├── linkedhashmap.h │ ├── logging.h │ ├── lru_cache.hpp │ ├── md5.cpp │ ├── md5.h │ ├── memorymapping.cpp │ ├── memorymapping.h │ ├── murmurhash3.cpp │ ├── murmurhash3.h │ ├── noncopyable.hpp │ ├── processinformation.cpp │ ├── processinformation.h │ ├── random-inl.h │ ├── random.cpp │ ├── random.h │ ├── rwspinlock.h │ ├── scopeguard.h │ ├── sha1.cpp │ ├── sha1.h │ ├── singleton.hpp │ ├── stacktrace.cpp │ ├── stacktrace.h │ ├── stringpiece.cpp │ ├── stringpiece.h │ ├── stringutil.cpp │ ├── stringutil.h │ ├── thisthread.cpp │ ├── thisthread.h │ ├── threadlocal.cpp │ ├── threadlocal.h │ ├── threadpool.cpp │ ├── threadpool.h │ ├── timestamp.cpp │ ├── timestamp.h │ ├── timezone.cpp │ └── timezone.h ├── disruptor │ ├── README.md │ └── disruptor.hpp └── net │ ├── CMakeLists.txt │ └── httpclient │ ├── easycurl.cpp │ ├── easycurl.h │ ├── easycurl.inl │ ├── easycurlpool.cpp │ ├── easycurlpool.h │ ├── easycurlpool.inl │ ├── httpclient.cpp │ ├── httpclient.h │ ├── httpclient.inl │ ├── httpcode.hpp │ ├── request.hpp │ └── response.hpp └── test ├── base ├── CMakeLists.txt ├── main.cpp ├── test_blockingqueue.cpp ├── test_bytebuffer.cpp ├── test_byteorderhelper.cpp ├── test_crc32.cpp ├── test_date.cpp ├── test_exception.cpp ├── test_file.cpp ├── test_fileutil.cpp ├── test_guid.cpp ├── test_linkedhashmap.cpp ├── test_logfile.cpp ├── test_logging.cpp ├── test_logstream.cpp ├── test_lru_cache.cpp ├── test_md5.cpp ├── test_memorymapping.cpp ├── test_processinformation.cpp ├── test_random.cpp ├── test_rwspinlock.cpp ├── test_scopeguard.cpp ├── test_sha1.cpp ├── test_stringpiece.cpp ├── test_stringutil.cpp ├── test_threadlocal.cpp ├── test_threadpool.cpp ├── test_timestamp.cpp └── test_timezone.cpp ├── disruptor ├── CMakeLists.txt └── test.cpp └── net ├── CMakeLists.txt ├── main.cpp └── test_httpclient.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | project (swift CXX) 5 | 6 | if(NOT CMAKE_BUILD_TYPE) 7 | set (CMAKE_BUILD_TYPE "Debug") 8 | endif() 9 | 10 | set (CMAKE_CXX_COMPILER "g++") 11 | set (CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -D__STDC_FORMAT_MACROS -fprofile-arcs -ftest-coverage -fPIC") 12 | set (CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -finline-limit=1000 -DNDEBUG -D__STDC_FORMAT_MACROS") 13 | 14 | set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 15 | set (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) 16 | 17 | string (TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE) 18 | 19 | include_directories (.) 20 | 21 | add_subdirectory (swift/base) 22 | add_subdirectory (swift/net) 23 | 24 | add_subdirectory (test/base) 25 | add_subdirectory (test/net) 26 | add_subdirectory (test/disruptor) 27 | 28 | add_subdirectory (apps/test/swiftclient) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Swift 2 | ===== 3 | Swift is a basic C++ library on linux platform which using c++11. 4 | 5 | Dependencies 6 | ============= 7 | - additional platform specific dependencies: 8 | 9 | Ubuntu 13.10 or late 64-bit 10 | - g++ 11 | - Cmake 12 | - libgtest-dev 13 | - libgoogle-glog-dev 14 | - libgflags-dev 15 | - unit test need libssl-dev 16 | 17 | Build 18 | ====== 19 | cd Swift && ./build.sh 20 | foundational libraries are in Swift/build/debug(release)/lib 21 | runnable programs of unit test at Swift/build/debug(release)/bin 22 | strongly recommend running the unit test 23 | 24 | Computer Latency Numbers 25 | ======================== 26 | L1 cache reference ......................... 0.5 ns 27 | Branch mispredict ............................ 5 ns 28 | L2 cache reference ........................... 7 ns 29 | Mutex lock/unlock ........................... 25 ns 30 | Main memory reference ...................... 100 ns 31 | Compress 1K bytes with Zippy ............. 3,000 ns = 3 µs 32 | Send 2K bytes over 1 Gbps network ....... 20,000 ns = 20 µs 33 | SSD random read ........................ 150,000 ns = 150 µs 34 | Read 1 MB sequentially from memory ..... 250,000 ns = 250 µs 35 | Round trip within same datacenter ...... 500,000 ns = 0.5 ms 36 | Read 1 MB sequentially from SSD* ..... 1,000,000 ns = 1 ms 37 | Disk seek ........................... 10,000,000 ns = 10 ms 38 | Read 1 MB sequentially from disk .... 20,000,000 ns = 20 ms 39 | Send packet CA->Netherlands->CA .... 150,000,000 ns = 150 ms 40 | 41 | 42 | -------------------------------------------------------------------------------- /apps/swiftclient/account.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | class Account 21 | { 22 | public: 23 | Account() = default; 24 | 25 | ~Account() = default; 26 | 27 | Account(const std::string& name) : name_(name) 28 | { 29 | 30 | } 31 | 32 | Account(std::string&& name) : name_(std::move(name)) 33 | { 34 | 35 | } 36 | 37 | Account(const Account&) = default; 38 | 39 | Account(Account&&) = default; 40 | 41 | Account& operator=(const Account&) = default; 42 | 43 | Account& operator=(Account&&) = default; 44 | 45 | inline bool operator==(const Account& rhs) const 46 | { 47 | return name_ == rhs.GetName(); 48 | } 49 | 50 | inline std::string&& GetName() 51 | { 52 | return std::move(name_); 53 | } 54 | 55 | inline const std::string& GetName() const 56 | { 57 | return name_; 58 | } 59 | 60 | inline void SetName(std::string&& name) 61 | { 62 | assert(!name.empty()); 63 | name_ = std::move(name); 64 | } 65 | 66 | inline void SetName(const std::string& name) 67 | { 68 | assert(!name.empty()); 69 | name_ = name; 70 | } 71 | 72 | inline const std::string& GetUri() const 73 | { 74 | return name_; 75 | } 76 | 77 | inline bool IsValid() const 78 | { 79 | return !name_.empty(); 80 | } 81 | 82 | private: 83 | std::string name_; 84 | }; 85 | -------------------------------------------------------------------------------- /apps/swiftclient/container.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | class Container 22 | { 23 | public: 24 | Container() = default; 25 | 26 | ~Container() = default; 27 | 28 | Container(const std::string& account, const std::string& name) 29 | : account_(account) 30 | , name_(name) 31 | { 32 | 33 | } 34 | 35 | Container(std::string&& account, std::string&& name) 36 | : account_(std::move(account)) 37 | , name_(std::move(name)) 38 | { 39 | 40 | } 41 | 42 | Container(Container&&) = default; 43 | 44 | Container(const Container&) = default; 45 | 46 | Container& operator=(Container&&) = default; 47 | 48 | Container& operator=(const Container& rhs) 49 | { 50 | account_ = rhs.GetAccount(); 51 | name_ = rhs.GetName(); 52 | return *this; 53 | } 54 | 55 | inline bool operator== (const Container& rhs) const 56 | { 57 | return (name_ == rhs.GetName() && account_ == rhs.GetAccount()); 58 | } 59 | 60 | inline const std::string& GetName() const 61 | { 62 | return name_; 63 | } 64 | 65 | inline std::string&& GetName() 66 | { 67 | return std::move(name_); 68 | } 69 | 70 | inline void SetName(const std::string& name) 71 | { 72 | assert(!name.empty()); 73 | name_ = name; 74 | } 75 | 76 | inline void SetName(std::string&& name) 77 | { 78 | assert(!name.empty()); 79 | name_ = std::move(name); 80 | } 81 | 82 | inline const std::string& GetAccount() const 83 | { 84 | return account_; 85 | } 86 | 87 | inline std::string&& GetAccount() 88 | { 89 | return std::move(account_); 90 | } 91 | 92 | inline void SetAccount(const std::string& account) 93 | { 94 | assert(!account.empty()); 95 | account_ = account; 96 | } 97 | 98 | inline void SetAccount(std::string&& account) 99 | { 100 | assert(!account.empty()); 101 | account_ = std::move(account); 102 | } 103 | 104 | inline std::string GetUri() const 105 | { 106 | if (!IsValid()) { 107 | return std::move(std::string()); 108 | } 109 | 110 | char buf[512] = {'\0'}; 111 | int size = snprintf(buf, sizeof(buf), "%s/%s", account_.c_str(), name_.c_str()); 112 | return std::move(std::string(buf, size)); 113 | } 114 | 115 | inline bool IsValid() const 116 | { 117 | return (!account_.empty() && !name_.empty()); 118 | } 119 | 120 | private: 121 | std::string account_; 122 | std::string name_; 123 | }; 124 | -------------------------------------------------------------------------------- /apps/swiftclient/object.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __APPS_SWIFT_CLIENT_OBJECT_H__ 16 | #define __APPS_SWIFT_CLIENT_OBJECT_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | class Object 23 | { 24 | public: 25 | Object() = default; 26 | 27 | Object(const std::string& account, const std::string& container, const std::string& name) 28 | : account_(account) 29 | , container_(container) 30 | , name_(name) 31 | { 32 | 33 | } 34 | 35 | 36 | Object(std::string&& account, std::string&& container, std::string&& name) 37 | : account_(std::move(account)) 38 | , container_(std::move(container)) 39 | , name_(std::move(name)) 40 | { 41 | 42 | } 43 | 44 | Object(Object&&) = default; 45 | Object(const Object&) = default; 46 | ~Object() = default; 47 | 48 | Object& operator=(Object&&) = default; 49 | Object& operator=(const Object& rhs) 50 | { 51 | account_ = rhs.GetAccount(); 52 | container_ = rhs.GetContainer(); 53 | name_ = rhs.GetName(); 54 | return *this; 55 | } 56 | 57 | inline bool operator== (const Object& rhs) const 58 | { 59 | if (name_ == rhs.GetName() 60 | && container_ == rhs.GetContainer() 61 | && account_ == rhs.GetAccount()) { 62 | return true; 63 | } 64 | 65 | return false; 66 | } 67 | 68 | inline const std::string& GetName() const 69 | { 70 | return name_; 71 | } 72 | 73 | inline std::string&& GetName() 74 | { 75 | return std::move(name_); 76 | } 77 | 78 | inline void SetName(const std::string& name) 79 | { 80 | assert(!name.empty()); 81 | name_ = name; 82 | } 83 | 84 | inline void SetName(std::string&& name) 85 | { 86 | assert(!name.empty()); 87 | name_ = std::move(name); 88 | } 89 | 90 | inline const std::string& GetContainer() const 91 | { 92 | return container_; 93 | } 94 | 95 | inline std::string&& GetContainer() 96 | { 97 | return std::move(container_); 98 | } 99 | 100 | inline void SetContainer(const std::string& container) 101 | { 102 | assert(!container.empty()); 103 | container_ = container; 104 | } 105 | 106 | inline void SetContainer(std::string&& container) 107 | { 108 | assert(!container.empty()); 109 | container_ = std::move(container); 110 | } 111 | 112 | inline const std::string& GetAccount() const 113 | { 114 | return account_; 115 | } 116 | 117 | inline std::string&& GetAccount() 118 | { 119 | return std::move(account_); 120 | } 121 | 122 | inline void SetAccount(const std::string& account) 123 | { 124 | assert(!account.empty()); 125 | account_ = account; 126 | } 127 | 128 | inline void SetAccount(std::string&& account) 129 | { 130 | assert(!account.empty()); 131 | account_ = std::move(account); 132 | } 133 | 134 | inline bool IsValid() const 135 | { 136 | return (!account_.empty() && !container_.empty() && !name_.empty()); 137 | } 138 | 139 | inline std::string GetUri() const 140 | { 141 | if (!IsValid()) { 142 | return std::move(std::string()); 143 | } 144 | 145 | char buf[1025] = {'\0'}; 146 | int size = snprintf(buf, sizeof(buf), "%s/%s/%s", account_.c_str(), 147 | container_.c_str(), name_.c_str()); 148 | return std::move(std::string(buf, size)); 149 | } 150 | 151 | 152 | private: 153 | std::string account_; 154 | std::string container_; 155 | std::string name_; 156 | }; // Object 157 | 158 | #endif // __APPS_SWIFT_CLIENT_OBJECT_H__ 159 | -------------------------------------------------------------------------------- /apps/swiftclient/swiftclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __APPS_SWIFT_CLIENT_SWIFT_CLIENT_H__ 16 | #define __APPS_SWIFT_CLIENT_SWIFT_CLIENT_H__ 17 | 18 | #include 19 | #include 20 | 21 | #include "swiftclient/object.h" 22 | #include "swiftclient/container.h" 23 | #include "swiftclient/account.h" 24 | 25 | class SwiftClient 26 | { 27 | public: 28 | typedef std::map header_map_type; 29 | typedef header_map_type info_map_type; 30 | typedef header_map_type query_map_type; 31 | 32 | public: 33 | SwiftClient() = default; 34 | SwiftClient(const std::string& host, const int port) 35 | : port_(port) 36 | , host_(host) 37 | { 38 | assert(!host_.empty()); 39 | assert(port_ > 0 || port_ < 65536); 40 | } 41 | 42 | SwiftClient(std::string&& host, int port) 43 | : port_(port) 44 | , host_(std::move(host)) 45 | { 46 | assert(!host_.empty()); 47 | assert(port_ > 0 || port_ < 65536); 48 | } 49 | 50 | SwiftClient(SwiftClient&&) = default; 51 | SwiftClient(const SwiftClient&) = default; 52 | SwiftClient& operator=(SwiftClient&&) = default; 53 | inline SwiftClient& operator=(const SwiftClient& rhs); 54 | inline bool operator== (const SwiftClient& rhs) const; 55 | inline const std::string& GetHost() const; 56 | inline void SetHost(const std::string& host); 57 | inline void SetHost(std::string&& host); 58 | inline const int GetPort() const; 59 | inline void SetPort(int port); 60 | 61 | 62 | inline info_map_type GetInfo(const Object* obj, const header_map_type* headers) const; 63 | inline info_map_type Download(const Object* obj, const header_map_type* headers, std::string& body) const; 64 | 65 | std::string Url(const std::string* account, 66 | const std::string* container = nullptr, 67 | const std::string* object = nullptr, 68 | const query_map_type* query = nullptr) const; 69 | 70 | std::string Url(const std::string& path, const query_map_type* query = nullptr) const; 71 | 72 | public: 73 | static info_map_type GetInfo(std::string&& url, const header_map_type* headers); 74 | inline static info_map_type GetInfo(const std::string& url, const header_map_type* headers); 75 | 76 | static info_map_type Download(std::string&& url, const header_map_type* headers, std::string& body); 77 | inline static info_map_type Download(const std::string& url, const header_map_type* headers, std::string& body); 78 | 79 | // Like pread 80 | static info_map_type Download(const std::string& url, 81 | const header_map_type* headers, 82 | char* buf, size_t size, size_t offset = 0); 83 | 84 | static int Download(const std::string& url, const header_map_type& headers, const std::string& file); 85 | static int Upload(const std::string& url, const header_map_type& headers, const std::string& file); 86 | 87 | inline static const std::string& GetSwiftApiVersion(); 88 | inline static void AddToken(header_map_type& headers, const std::string& token); 89 | inline static size_t GetLastModifyTime(const info_map_type& info); 90 | inline static size_t GetContentLength(const info_map_type& info); 91 | 92 | private: 93 | int port_; 94 | std::string host_; 95 | 96 | static const std::string kApiVersion_; 97 | }; 98 | 99 | #include "swiftclient/swiftclient.inl" 100 | 101 | #endif // __APPS_SWIFT_CLIENT_SWIFT_CLIENT_H__ -------------------------------------------------------------------------------- /apps/swiftclient/swiftclient.inl: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __APPS_SWIFT_CLIENT_SWIFT_CLIENT_INL__ 16 | #define __APPS_SWIFT_CLIENT_SWIFT_CLIENT_INL__ 17 | 18 | #include 19 | 20 | // public 21 | SwiftClient& SwiftClient::operator=(const SwiftClient& rhs) 22 | { 23 | port_ = rhs.GetPort(); 24 | host_ = rhs.GetHost(); 25 | return *this; 26 | } 27 | 28 | // public 29 | bool SwiftClient::operator== (const SwiftClient& rhs) const 30 | { 31 | return host_ == rhs.GetHost() && port_ == rhs.GetPort(); 32 | } 33 | 34 | // public 35 | const std::string& SwiftClient::GetHost() const 36 | { 37 | return host_; 38 | } 39 | 40 | // public 41 | void SwiftClient::SetHost(const std::string& host) 42 | { 43 | assert(!host.empty()); 44 | host_ = host; 45 | } 46 | 47 | // public 48 | void SwiftClient::SetHost(std::string&& host) 49 | { 50 | assert(!host.empty()); 51 | host_ = std::move(host); 52 | } 53 | 54 | // public 55 | const int SwiftClient::GetPort() const 56 | { 57 | return port_; 58 | } 59 | 60 | // public 61 | void SwiftClient::SetPort(int port) 62 | { 63 | assert(port_ > 0 || port_ < 65536); 64 | port_ = port; 65 | } 66 | 67 | // static public 68 | SwiftClient::info_map_type SwiftClient::GetInfo(const std::string& url, 69 | const header_map_type* headers) 70 | { 71 | return std::move(GetInfo(std::move(std::string(url)), headers)); 72 | } 73 | 74 | // static public 75 | SwiftClient::info_map_type SwiftClient::Download(const std::string& url, 76 | const header_map_type* headers, 77 | std::string& body) 78 | { 79 | return std::move(Download(std::move(std::string(url)), headers, body)); 80 | } 81 | 82 | // static public 83 | const std::string& SwiftClient::GetSwiftApiVersion() 84 | { 85 | return kApiVersion_; 86 | } 87 | 88 | // static public 89 | void SwiftClient::AddToken(header_map_type& headers, const std::string& token) 90 | { 91 | if (!token.empty()) { 92 | headers["X-Auth-Token"] = token; 93 | } 94 | } 95 | 96 | // static public 97 | size_t SwiftClient::GetLastModifyTime(const info_map_type& info) 98 | { 99 | if (!info.empty()) { 100 | auto it = info.find("X-Timestamp"); 101 | if (it != info.end()) { 102 | swift::StringUtil::FromString(it->second.c_str()); 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | 109 | // static public 110 | size_t SwiftClient::GetContentLength(const info_map_type& info) 111 | { 112 | if (!info.empty()) { 113 | auto it = info.find("Content-Length"); 114 | if (it != info.end()) { 115 | return swift::StringUtil::FromString(it->second.c_str()); 116 | } 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | // public 123 | SwiftClient::info_map_type SwiftClient::GetInfo(const Object *obj, 124 | const header_map_type* headers) const 125 | { 126 | if (nullptr == obj || !obj->IsValid()) { 127 | return std::move(info_map_type()); 128 | } 129 | 130 | return SwiftClient::GetInfo(std::move(Url(obj->GetUri(), nullptr)), headers); 131 | } 132 | 133 | // public 134 | SwiftClient::info_map_type SwiftClient::Download(const Object* obj, 135 | const header_map_type* headers, 136 | std::string& body) const 137 | { 138 | if (nullptr == obj || !obj->IsValid()) { 139 | return std::move(info_map_type()); 140 | } 141 | 142 | return SwiftClient::Download(std::move(Url(obj->GetUri(), nullptr)), headers, body); 143 | } 144 | 145 | 146 | #endif // __APPS_SWIFT_CLIENT_SWIFT_CLIENT_INL__ -------------------------------------------------------------------------------- /apps/swiftclient/util.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | -------------------------------------------------------------------------------- /apps/test/swiftclient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME swiftclient_test) 5 | 6 | include_directories(../.. Inc) 7 | include_directories(../../.. swift_Inc) 8 | aux_source_directory (. SRCS) 9 | aux_source_directory (../../swiftclient swiftclient_SRCS) 10 | add_executable (${TARGET_NAME} ${SRCS} ${Inc} ${swiftclient_SRCS} ${swift_Inc}) 11 | add_definitions ("-std=c++0x -Wno-deprecated -D_GLIBCXX_USE_NANOSLEEP") 12 | target_link_libraries (${TARGET_NAME} swift_net pthread gflags gtest) -------------------------------------------------------------------------------- /apps/test/swiftclient/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | int main (int argc, char* argv[]) 19 | { 20 | testing::InitGoogleTest (&argc, argv); 21 | swift::StackTrace::InitStackTraceHandler (); 22 | 23 | return RUN_ALL_TESTS (); 24 | } -------------------------------------------------------------------------------- /apps/test/swiftclient/test_account.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | class test_Account : public testing::Test 19 | { 20 | public: 21 | test_Account() {} 22 | ~test_Account() {} 23 | 24 | virtual void SetUp (void) 25 | { 26 | } 27 | 28 | virtual void TearDown (void) 29 | { 30 | 31 | } 32 | }; 33 | 34 | TEST(test_Account, Account) 35 | { 36 | std::string name("account"); 37 | Account account(name); 38 | ASSERT_EQ(name, account.GetName()); 39 | 40 | Account account1(account); 41 | ASSERT_EQ(account1.GetName(), account.GetName()); 42 | ASSERT_EQ(account, account1); 43 | 44 | Account account2(std::move(account1)); 45 | ASSERT_EQ(account2.GetName(), account.GetName()); 46 | ASSERT_EQ(account, account2); 47 | ASSERT_TRUE(account1.GetName().empty()); 48 | 49 | Account account3(std::move(account2)); 50 | ASSERT_EQ(account3.GetName(), account.GetName()); 51 | ASSERT_EQ(account1, account2); 52 | ASSERT_TRUE(account2.GetName().empty()); 53 | 54 | account1 = std::move(account3); 55 | ASSERT_EQ(account1.GetName(), account.GetName()); 56 | ASSERT_EQ(account3, account2); 57 | ASSERT_TRUE(!account1.GetName().empty()); 58 | 59 | account2.SetName(std::move(account1.GetName())); 60 | ASSERT_EQ(account2.GetName(), account.GetName()); 61 | ASSERT_EQ(account3, account1); 62 | ASSERT_TRUE(!account2.GetName().empty()); 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /apps/test/swiftclient/test_container.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | class test_Container : public testing::Test 19 | { 20 | public: 21 | test_Container() {} 22 | ~test_Container() {} 23 | 24 | virtual void SetUp (void) 25 | { 26 | } 27 | 28 | virtual void TearDown (void) 29 | { 30 | 31 | } 32 | }; 33 | 34 | TEST_F(test_Container, Container) 35 | { 36 | Container c(std::move(std::string("account")), 37 | std::move(std::string("container"))); 38 | ASSERT_EQ(c.GetAccount(), "account"); 39 | ASSERT_EQ(c.GetName(), "container"); 40 | 41 | Container c2(c); 42 | ASSERT_EQ(c2.GetAccount(), c.GetAccount()); 43 | ASSERT_EQ(c.GetName(), c2.GetName()); 44 | ASSERT_EQ(c, c2); 45 | std::string account = std::move(c2.GetAccount()); 46 | ASSERT_EQ(account, c.GetAccount()); 47 | ASSERT_TRUE(c2.GetAccount().empty()); 48 | 49 | c2.SetAccount(account); 50 | ASSERT_EQ(account, c2.GetAccount()); 51 | Container c3(std::move(c2)); 52 | ASSERT_EQ(c3.GetAccount(), c.GetAccount()); 53 | } -------------------------------------------------------------------------------- /apps/test/swiftclient/test_object.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | class test_Object : public testing::Test 20 | { 21 | public: 22 | test_Object() {} 23 | ~test_Object() {} 24 | 25 | virtual void SetUp (void) 26 | { 27 | } 28 | 29 | virtual void TearDown (void) 30 | { 31 | 32 | } 33 | }; 34 | 35 | TEST_F(test_Object, Object) 36 | { 37 | std::string account("account"); 38 | std::string container("container"); 39 | std::string object("object"); 40 | Object obj(account, container, object); 41 | ASSERT_EQ(obj.GetUri(), "account/container/object"); 42 | } -------------------------------------------------------------------------------- /apps/test/swiftclient/test_swiftclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | class test_SwiftClient : public testing::Test 20 | { 21 | public: 22 | test_SwiftClient() {} 23 | ~test_SwiftClient() {} 24 | 25 | virtual void SetUp (void) 26 | { 27 | } 28 | 29 | virtual void TearDown (void) 30 | { 31 | 32 | } 33 | }; 34 | 35 | TEST_F(test_SwiftClient, Uri) 36 | { 37 | std::string host("127.0.0.1"); 38 | int port = 8080; 39 | std::string account("account"); 40 | std::string container("container"); 41 | std::string object("object"); 42 | 43 | SwiftClient client; 44 | client.SetHost(host); 45 | client.SetPort(port); 46 | std::string uri = std::move(client.Url(&account)); 47 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account"); 48 | 49 | uri = std::move(client.Url(&account, &container)); 50 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container"); 51 | 52 | uri = std::move(client.Url(&account, &container, &object)); 53 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container/object"); 54 | 55 | uri = std::move(client.Url(nullptr, &container, &object)); 56 | ASSERT_TRUE(uri.empty()); 57 | 58 | uri = std::move(client.Url(&account, nullptr, &object)); 59 | ASSERT_TRUE(uri.empty()); 60 | 61 | std::string empty; 62 | uri = std::move(client.Url(&account, &empty, &empty)); 63 | ASSERT_TRUE(uri.empty()); 64 | 65 | SwiftClient::query_map_type query; 66 | query["format"] = "json"; 67 | uri = std::move(client.Url(&account, &container, &object, &query)); 68 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container/object?format=json"); 69 | 70 | uri = std::move(client.Url(&account, &empty, &object, &query)); 71 | ASSERT_TRUE(uri.empty()); 72 | 73 | Object obj(account, container, object); 74 | std::string path = std::move(obj.GetUri()); 75 | uri = std::move(client.Url(path, &query)); 76 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container/object?format=json"); 77 | 78 | uri = std::move(client.Url(empty, &query)); 79 | ASSERT_TRUE(uri.empty()); 80 | 81 | uri = std::move(client.Url(path)); 82 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container/object"); 83 | 84 | query["limit"] = "1000"; 85 | uri = std::move(client.Url(obj.GetUri(), &query)); 86 | ASSERT_EQ(uri, "http://127.0.0.1:8080/v1/account/container/object?format=json&limit=1000"); 87 | } -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | set -x 4 | 5 | SOURCE_DIR=`pwd` 6 | BUILD_DIR=${BUILD_DIR:-build} 7 | BUILD_TYPE=${BUILD_TYPE:-debug} 8 | INSTALL_DIR=${INSTALL_DIR:-../${BUILD_TYPE}-install} 9 | 10 | mkdir -p $BUILD_DIR/$BUILD_TYPE \ 11 | && cd $BUILD_DIR/$BUILD_TYPE \ 12 | && cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 13 | -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ 14 | $SOURCE_DIR \ 15 | && make -j4 $* 16 | -------------------------------------------------------------------------------- /swift/base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME swift_base) 5 | 6 | aux_source_directory (. base_SRCS) 7 | aux_source_directory (experimental base_exp_SRCS) 8 | add_library (${TARGET_NAME} ${base_SRCS} ${base_exp_SRCS}) 9 | target_link_libraries (${TARGET_NAME} pthread glog gflags) 10 | set_target_properties (${TARGET_NAME} PROPERTIES COMPILE_FLAGS "-std=c++0x -Wno-deprecated") 11 | 12 | install(TARGETS ${TARGET_NAME} DESTINATION lib) -------------------------------------------------------------------------------- /swift/base/blockingqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | #ifndef __SWIFT_BASE_BLOCKING_QUEUE_H__ 15 | #define __SWIFT_BASE_BLOCKING_QUEUE_H__ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "swift/base/noncopyable.hpp" 23 | 24 | namespace swift { 25 | 26 | template 27 | class BlockingQueue : swift::noncopyable 28 | { 29 | typedef std::lock_guard LockGuard; 30 | public: 31 | BlockingQueue () : mutex_ (), cond_ (), queue_ () 32 | { 33 | 34 | } 35 | 36 | ~BlockingQueue () 37 | { 38 | 39 | } 40 | 41 | void Put (const T& task) 42 | { 43 | LockGuard lock (mutex_); 44 | queue_.push_back (task); 45 | cond_.notify_one (); 46 | } 47 | 48 | void Put (T&& task) 49 | { 50 | LockGuard lock (mutex_); 51 | queue_.push_back (std::move (task)); 52 | cond_.notify_one (); 53 | } 54 | 55 | T Take () 56 | { 57 | std::unique_lock lock (mutex_); 58 | cond_.wait (lock, [this]{return !queue_.empty ();}); 59 | assert (!queue_.empty ()); 60 | T front (std::move (queue_.front ())); 61 | queue_.pop_front (); 62 | 63 | return front; 64 | } 65 | 66 | size_t Size () const 67 | { 68 | LockGuard lock (mutex_); 69 | return queue_.size (); 70 | } 71 | 72 | bool IsEmpty () const 73 | { 74 | LockGuard lock (mutex_); 75 | return queue_.empty (); 76 | } 77 | 78 | void Clear () 79 | { 80 | LockGuard lock (mutex_); 81 | queue_.clear (); 82 | } 83 | 84 | private: 85 | mutable std::mutex mutex_; 86 | std::condition_variable cond_; 87 | std::deque queue_; 88 | }; 89 | 90 | } // namespace swift 91 | 92 | #endif // __SWIFT_BASE_BLOCKING_QUEUE_H__ 93 | -------------------------------------------------------------------------------- /swift/base/bytebuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_BYTE_BUFFER_H__ 16 | #define __SWIFT_BASE_BYTE_BUFFER_H__ 17 | 18 | #include 19 | 20 | #include "swift/base/noncopyable.hpp" 21 | #include "swift/base/byteorderhelper.h" 22 | 23 | namespace swift { 24 | 25 | class ByteBuffer : swift::noncopyable 26 | { 27 | typedef ByteOrderHelper::ByteOrder ByteOrder; 28 | public: 29 | class ReadPosition 30 | { 31 | friend class ByteBuffer; 32 | ReadPosition (size_t start, int version) 33 | : start_ (start) 34 | , version_ (version) 35 | { 36 | } 37 | 38 | size_t start_; 39 | int version_; 40 | }; 41 | public: 42 | // Note: the default byte's order is ByteOrder::BYTE_ORDER_HOST 43 | ByteBuffer (); 44 | explicit ByteBuffer (const char *buffer); 45 | explicit ByteBuffer (ByteOrder byte_order); 46 | ByteBuffer (const char *buffer, size_t length); 47 | ByteBuffer (const char *buffer, 48 | size_t length, 49 | ByteOrder byte_order); 50 | 51 | ~ByteBuffer (); 52 | 53 | //movable 54 | ByteBuffer (ByteBuffer&&) = delete; 55 | ByteBuffer& operator= (ByteBuffer&&) = delete; 56 | 57 | size_t Length () const 58 | { 59 | return end_ - start_; 60 | } 61 | 62 | size_t Capacity () const 63 | { 64 | return size_ - start_; 65 | } 66 | 67 | const char* Data () const 68 | { 69 | return buffer_ + start_; 70 | } 71 | 72 | ByteOrder Order () const 73 | { 74 | return byte_order_; 75 | } 76 | 77 | ReadPosition GetReadPosition () const 78 | { 79 | return ReadPosition (start_, version_); 80 | } 81 | 82 | // if the version in new position isn't equal to version_, return false. 83 | bool SetReadPosition (const ReadPosition& position); 84 | 85 | std::string ToString () const 86 | { 87 | return std::string (buffer_ + start_, end_ - start_); 88 | } 89 | 90 | // Read a next value from the buffer. Return false if 91 | // there isn't enough data left for the specified type. 92 | bool ReadUInt8 (uint8_t *val) 93 | { 94 | if (nullptr == val) { return false;} 95 | return ReadBytes (reinterpret_cast(val), 1); 96 | } 97 | 98 | bool ReadUInt16 (uint16_t *val); 99 | bool ReadUInt32 (uint32_t *val); 100 | bool ReadUInt64 (uint64_t *val); 101 | bool ReadBytes (char *val, size_t len); 102 | 103 | // Appends next len bytes to val, if there is less than len return false. 104 | bool ReadString (std::string *val, size_t len); 105 | 106 | // Write value to the buffer. auto resizes the buffer when it is necessary. 107 | void WriteUInt8 (uint8_t val) 108 | { 109 | WriteBytes (reinterpret_cast(&val), 1); 110 | } 111 | 112 | void WriteUInt16 (uint16_t val); 113 | void WriteUInt32 (uint32_t val); 114 | void WriteUInt64 (uint64_t val); 115 | 116 | void WriteString (const std::string& val) 117 | { 118 | WriteBytes (val.c_str (), val.size ()); 119 | } 120 | 121 | void WriteBytes (const char* val, size_t len); 122 | 123 | // Resize the buffer to the specified size. 124 | // This invalidates any remembered seek positions. 125 | void Resize (size_t size); 126 | 127 | // Reserves the given number of bytes and return a char* that can be 128 | // written into. Useful for functions that require a char* buffer and 129 | // not a ByteBuffer. 130 | char* ReserveWriteBuffer (size_t len); 131 | 132 | // Moves current position size bytes forward. Return false if there is 133 | // less than size bytes left in the buffer. Consume doesn't permanently 134 | // remove data. so remembered read positions are still valid after this call. 135 | bool Consume (size_t size); 136 | 137 | // Clears the contents of the buffer. After this, Length() will be 0. 138 | void Clear (); 139 | 140 | void Swap (ByteBuffer& other); 141 | 142 | private: 143 | void Initialize (const char *buffer); 144 | 145 | private: 146 | char* buffer_; 147 | size_t size_; 148 | size_t start_; 149 | size_t end_; 150 | int version_; 151 | ByteOrder byte_order_; 152 | 153 | private: 154 | static const int kDefaultSize = 4096; 155 | }; 156 | 157 | } // namespace swift 158 | 159 | #endif // __SWIFT_BASE_BYTE_BUFFER_H__ 160 | -------------------------------------------------------------------------------- /swift/base/crc32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | #include "swift/base/crc32.h" 15 | 16 | namespace swift { 17 | namespace { 18 | 19 | static uint32_t kCrc32Table[256] = { 20 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 21 | 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 22 | 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 23 | 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 24 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 25 | 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 26 | 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 27 | 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 28 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 29 | 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 30 | 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 31 | 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 32 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 33 | 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 34 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 35 | 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 36 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 37 | 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 38 | 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 39 | 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 40 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 41 | 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 42 | 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 43 | 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 44 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 45 | 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 46 | 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 47 | 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 48 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 49 | 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 50 | 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 51 | 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 52 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 53 | 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 54 | 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 55 | 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 56 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 57 | 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 58 | 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 59 | 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 60 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 61 | 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 62 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 63 | }; 64 | } // namespace 65 | 66 | // static public 67 | uint32_t Crc32::UpdateCrc32 (uint32_t initial, const void *data, size_t len) 68 | { 69 | uint32_t c = initial ^ 0xFFFFFFFFU; 70 | const uint8_t *p = static_cast(data); 71 | for (size_t i = 0; i < len; ++i) { 72 | c = kCrc32Table[(c ^ p[i]) & 0xFF] ^ (c >> 8); 73 | } 74 | 75 | return c ^ 0xFFFFFFFFU; 76 | } 77 | 78 | } // namespace swift 79 | -------------------------------------------------------------------------------- /swift/base/crc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_CRC32_H__ 16 | #define __SWIFT_BASE_CRC32_H__ 17 | 18 | #include 19 | #include 20 | 21 | namespace swift { 22 | 23 | class Crc32 24 | { 25 | public: 26 | // Return the Crc32 of concat(A, data[0,len-1]) where initial is the 27 | // Crc32 of some string A. UpdateCrc32 () is often used to maintain the 28 | // Crc32 of a stream of data. for the first call, initial should be 0. 29 | static uint32_t UpdateCrc32 (uint32_t initial, const void *data, size_t len); 30 | 31 | // Return the crc32c of data[0,len-1] 32 | static inline uint32_t ComputeCrc32 (const void *data, size_t len) 33 | { 34 | return UpdateCrc32 (0, data, len); 35 | } 36 | }; 37 | 38 | } // namespace swift 39 | #endif // __SWIFT_BASE_CRC32_H__ 40 | -------------------------------------------------------------------------------- /swift/base/date.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include // snprintf 16 | #include 17 | #include 18 | 19 | #include "swift/base/date.h" 20 | 21 | namespace swift { 22 | namespace detail { 23 | 24 | char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1]; 25 | 26 | // algorithm and explanation see: 27 | // http://www.faqs.org/faqs/calendars/faq/part2/ 28 | // http://blog.csdn.net/Solstice 29 | 30 | int CalculateJulianDayNumber (int year, int month, int day) 31 | { 32 | (void) require_32_bit_integer_at_least; // no warning please 33 | int a = (14 - month) / 12; 34 | int y = year + 4800 - a; 35 | int m = month + 12 * a - 3; 36 | 37 | return day + (153 * m + 2) / 5 + y * 365 + (y / 4 - y / 100 + y / 400) - 32045; 38 | } 39 | 40 | struct Date::YearMonthDay CalculateYearMonthDay (int julian_day_number) 41 | { 42 | int a = julian_day_number + 32044; 43 | int b = (4 * a + 3) / 146097; 44 | int c = a - ((b * 146097) / 4); 45 | int d = (4 * c + 3) / 1461; 46 | int e = c - ((1461 * d) / 4); 47 | int m = (5 * e + 2) / 153; 48 | Date::YearMonthDay ymd; 49 | ymd.day = e - ((153 * m + 2) / 5) + 1; 50 | ymd.month = m + 3 - 12 * (m / 10); 51 | ymd.year = b * 100 + d - 4800 + (m / 10); 52 | return ymd; 53 | } 54 | 55 | } // namespace detail 56 | 57 | // public 58 | const int Date::kJulianDayOf1970_01_01 = detail::CalculateJulianDayNumber (1970, 1, 1); 59 | 60 | // public 61 | Date::Date (int y, int m, int d) : julian_day_number_ (detail::CalculateJulianDayNumber (y, m, d)) 62 | { 63 | assert (m > 0 && m <= 12); 64 | assert (d > 0 && d <= 31); 65 | } 66 | 67 | // public 68 | Date::Date (const struct tm& t) 69 | : julian_day_number_ (detail::CalculateJulianDayNumber ( 70 | t.tm_year + 1900, 71 | t.tm_mon + 1, 72 | t.tm_mday)) 73 | { 74 | } 75 | 76 | // public 77 | struct Date::YearMonthDay Date::GetYearMonthDay () const 78 | { 79 | return detail::CalculateYearMonthDay (julian_day_number_); 80 | } 81 | 82 | // public 83 | std::string Date::ToString () const 84 | { 85 | char buf[16] = {'\0'}; 86 | struct YearMonthDay ymd (GetYearMonthDay ()); 87 | int size = snprintf (buf, sizeof buf, "%4d-%02d-%02d", ymd.year, ymd.month, ymd.day); 88 | return std::string (buf, size); 89 | } 90 | 91 | } // namespace swift 92 | -------------------------------------------------------------------------------- /swift/base/date.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_DATE_H__ 16 | #define __SWIFT_BASE_DATE_H__ 17 | 18 | #include 19 | 20 | struct tm; 21 | 22 | namespace swift { 23 | 24 | class Date 25 | { 26 | public: 27 | struct YearMonthDay 28 | { 29 | int year; // [1900..2500] 30 | int month; // [1..12] 31 | int day; // [1..31] 32 | }; 33 | 34 | public: 35 | // Constructor an invalid Date. 36 | Date () : julian_day_number_ (0) {} 37 | 38 | // 39 | // Constructor a YYYY-MM-DD Date. 40 | // 41 | // 1 <= month <= 12 42 | Date (int year, int month, int day); 43 | 44 | // 45 | // Constructor a Date from Julian Day Number. 46 | // 47 | explicit Date (int julian_day_num) : julian_day_number_ (julian_day_num) {} 48 | 49 | // 50 | // Constructor a Date from struct tm 51 | // 52 | explicit Date (const struct tm&); 53 | 54 | inline void Swap (Date& that) 55 | { 56 | std::swap (julian_day_number_, that.julian_day_number_); 57 | } 58 | 59 | inline bool Valid () const 60 | { 61 | return julian_day_number_ > 0; 62 | } 63 | 64 | // Converts to YYYY-MM-DD format. 65 | std::string ToString () const; 66 | 67 | inline int Year () const 68 | { 69 | return GetYearMonthDay ().year; 70 | } 71 | 72 | inline int Month () const 73 | { 74 | return GetYearMonthDay ().month; 75 | } 76 | 77 | inline int Day () const 78 | { 79 | return GetYearMonthDay ().day; 80 | } 81 | 82 | // [0, 1, 2, 3, 4, 5, 6] => [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] 83 | inline int WeekDay () const 84 | { 85 | return (julian_day_number_ + 1) % kDaysPerWeek; 86 | } 87 | 88 | inline int GetJulianDayNumber () const 89 | { 90 | return julian_day_number_; 91 | } 92 | 93 | struct YearMonthDay GetYearMonthDay () const; 94 | 95 | private: 96 | int julian_day_number_; 97 | 98 | private: 99 | static const int kDaysPerWeek = 7; 100 | 101 | public: 102 | static const int kJulianDayOf1970_01_01; 103 | }; 104 | 105 | inline bool operator< (const Date& lhs, const Date& rhs) 106 | { 107 | return lhs.GetJulianDayNumber () < rhs.GetJulianDayNumber (); 108 | } 109 | 110 | inline bool operator== (const Date& lhs, const Date& rhs) 111 | { 112 | return lhs.GetJulianDayNumber () == rhs.GetJulianDayNumber (); 113 | } 114 | 115 | inline bool operator!= (const Date& lhs, const Date& rhs) 116 | { 117 | return !(lhs.GetJulianDayNumber () == rhs.GetJulianDayNumber ()); 118 | } 119 | 120 | } // end of namespace swift 121 | 122 | #endif // __SWIFT_BASE_DATE_H__ 123 | -------------------------------------------------------------------------------- /swift/base/exception.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include // backtrace and backtrace_symbols func 16 | #include // __cxa_demangle 17 | #include 18 | #include 19 | 20 | #include "swift/base/exception.h" 21 | 22 | namespace swift { 23 | namespace detail { 24 | 25 | // The prefix used for mangled symbols, per the Itanium C++ ABI: 26 | // http://www.codesourcery.com/cxx-abi/abi.html#mangling 27 | const char kMangledSymbolPrefix[] = "_Z"; 28 | 29 | // Characters that can be used for symbols, generated by Ruby: 30 | // (('a'..'z').to_a+('A'..'Z').to_a+('0'..'9').to_a + ['_']).join 31 | const char kSymbolCharacters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 32 | 33 | // Demangles C++ symbols in the given text. Example: 34 | // "out/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817778c]" 35 | // => 36 | // "out/Debug/base_unittests(StackTrace::StackTrace()+0x20) [0x817778c]" 37 | void DemangleSymbol (std::string* symbol) 38 | { 39 | std::string::size_type search_from = 0; 40 | while (search_from < symbol->size ()) { 41 | // Look for the start of a mangled symbol from search_from 42 | std::string::size_type mangled_start = symbol->find (kMangledSymbolPrefix, search_from); 43 | if (mangled_start == std::string::npos) { 44 | break; // Mangled symbol not found 45 | } 46 | 47 | // Look for the end of the mangled symbol 48 | std::string::size_type mangled_end = symbol->find_first_not_of (kSymbolCharacters, mangled_start); 49 | if (mangled_end == std::string::npos) { 50 | mangled_end = symbol->size (); 51 | } 52 | std::string mangled_symbol = std::move (symbol->substr (mangled_start, mangled_end - mangled_start)); 53 | 54 | // Try to demangle the mangled symbol candidate 55 | int status = -4; // some arbitrary value to eliminate the compiler warning 56 | std::unique_ptr demangled_symbol { 57 | abi::__cxa_demangle (mangled_symbol.c_str (), nullptr, 0, &status), 58 | std::free 59 | }; 60 | 61 | // 0 Demangling is success 62 | if (0 == status) { 63 | // Remove the mangled symbol 64 | symbol->erase (mangled_start, mangled_end - mangled_start); 65 | // Insert the demangled symbol 66 | symbol->insert (mangled_start, demangled_symbol.get ()); 67 | // Next time, we will start right after the demangled symbol 68 | search_from = mangled_start + strlen (demangled_symbol.get ()); 69 | } 70 | else { 71 | // Failed to demangle. Retry after the "_Z" we just found 72 | search_from = mangled_start + 2; 73 | } 74 | } 75 | } 76 | } // namespace detail 77 | 78 | // public 79 | Exception::Exception (const char* msg) : msg_ (nullptr == msg ? "" : msg) 80 | { 81 | ProcessStackTrace (); 82 | } 83 | 84 | // public 85 | Exception::Exception (const std::string& msg) : msg_ (msg) 86 | { 87 | ProcessStackTrace (); 88 | } 89 | 90 | // public 91 | Exception::Exception (std::string&& msg) : msg_ (std::move (msg)) 92 | { 93 | ProcessStackTrace (); 94 | } 95 | 96 | // public 97 | Exception::~Exception () throw () 98 | { 99 | 100 | } 101 | 102 | // public 103 | const char* Exception::GetStackTrace () const throw () 104 | { 105 | return stack_.c_str (); 106 | } 107 | 108 | // public 109 | const char* Exception::what () const throw () 110 | { 111 | return msg_.c_str (); 112 | } 113 | 114 | // private 115 | void Exception::ProcessStackTrace () 116 | { 117 | void* buf[100]; 118 | int size = ::backtrace (buf, 100); 119 | std::unique_ptr stacks { 120 | ::backtrace_symbols (buf, size), 121 | std::free 122 | }; 123 | 124 | if (nullptr != stacks.get ()) { 125 | for (int i = 0; i < size; ++i) { 126 | std::string symbol (stacks.get ()[i]); 127 | detail::DemangleSymbol (&symbol); 128 | stack_.append (symbol); 129 | stack_.push_back ('\n'); 130 | } 131 | } 132 | } 133 | 134 | } // namespace swift 135 | -------------------------------------------------------------------------------- /swift/base/exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_EXCEPTION_H__ 16 | #define __SWIFT_BASE_EXCEPTION_H__ 17 | 18 | #include 19 | #include 20 | 21 | namespace swift { 22 | 23 | class Exception : public std::exception 24 | { 25 | public: 26 | explicit Exception (const char* msg); 27 | explicit Exception (const std::string& msg); 28 | explicit Exception (std::string&& msg); 29 | 30 | virtual ~Exception () throw (); 31 | 32 | const char* GetStackTrace () const throw (); 33 | 34 | // Returns a C-style character string describing the general cause of the current error. 35 | virtual const char* what () const throw (); 36 | 37 | inline const std::string& Messge () const throw () 38 | { 39 | return msg_; 40 | } 41 | 42 | private: 43 | void ProcessStackTrace (); 44 | 45 | private: 46 | std::string msg_; 47 | std::string stack_; 48 | }; 49 | } // namespace swift 50 | 51 | #endif // __SWIFT_BASE_EXCEPTION_H__ 52 | -------------------------------------------------------------------------------- /swift/base/experimental/logfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_LOG_FILE_H__ 16 | #define __SWIFT_BASE_LOG_FILE_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "swift/base/noncopyable.hpp" 24 | 25 | namespace swift { 26 | 27 | class LogFile : swift::noncopyable 28 | { 29 | public: 30 | LogFile (const std::string& file_name, 31 | size_t roll_size, 32 | bool thread_safe = true, 33 | int flush_interval = 3, 34 | int check_every_count = 1024); 35 | ~LogFile (); 36 | 37 | void Append (const char* log_line, int length); 38 | void Flush (); 39 | bool RollFile (); 40 | 41 | private: 42 | void AppendUnlocked (const char* log_line, int length); 43 | static std::string GetLogFileName (const std::string& base_name, time_t* now); 44 | 45 | private: 46 | const static int kRollPerSeconds = 60 * 60 * 24; // one day 47 | 48 | private: 49 | std::unique_ptr mutex_; 50 | const std::string name_; 51 | const size_t roll_size_; // reached this size then write another file 52 | const int flush_interval_; // flush interval 53 | const int check_every_count_; // reached this number then flush data to disk 54 | int count_; // write count 55 | 56 | time_t start_of_period_; 57 | time_t last_roll_; 58 | time_t last_flush_; 59 | 60 | class AppendFile; 61 | std::unique_ptr file_; 62 | }; 63 | } // namespace swift 64 | #endif // __SWIFT_BASE_LOG_FILE_H__ -------------------------------------------------------------------------------- /swift/base/file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include "swift/base/file.h" 16 | #include "swift/base/likely.h" 17 | 18 | #include 19 | 20 | namespace swift { 21 | 22 | // public 23 | File::File (int fd, bool owns_fd /*= false*/) 24 | : fd_ (fd) 25 | , is_owns_ (owns_fd) 26 | { 27 | assert (fd > 0); 28 | } 29 | 30 | // public 31 | File::File (File&& other) 32 | : fd_ (other.fd_) 33 | , is_owns_ (other.is_owns_) 34 | { 35 | other.Release (); 36 | } 37 | 38 | // public 39 | File& File::operator= (File&& other) 40 | { 41 | Close (); 42 | Swap (other); 43 | return *this; 44 | } 45 | 46 | // public 47 | bool File::Open (const char *file_name, 48 | int flags /*= O_RDWR | O_LARGEFILE | O_CREAT*/, 49 | mode_t mode /*= 0666*/) 50 | { 51 | if (fd_ > 0) { 52 | Close(); 53 | } 54 | 55 | fd_ = fileutil::Open (file_name, flags, mode); 56 | is_owns_ = true; 57 | return fd_ > 0; 58 | } 59 | 60 | // public 61 | void File::Swap (File& other) 62 | { 63 | std::swap (fd_, other.fd_); 64 | std::swap (is_owns_, other.is_owns_); 65 | } 66 | 67 | // public 68 | int File::Release () 69 | { 70 | int released = fd_; 71 | fd_ = -1; 72 | is_owns_ = false; 73 | return released; 74 | } 75 | 76 | // public 77 | bool File::Close () 78 | { 79 | int ret = is_owns_ ? fileutil::Close (fd_) : 0; 80 | Release (); 81 | return (0 == ret); 82 | } 83 | 84 | // public 85 | File File::Dup () const 86 | { 87 | File ret_file; 88 | if (-1 != fd_) { 89 | int fd = fileutil::Dup (fd_); 90 | if (LIKELY (-1 != fd)) { 91 | File f (fd, true); 92 | ret_file.Swap (f); 93 | } 94 | } 95 | 96 | return ret_file; 97 | } 98 | 99 | // static public 100 | File File::Temporary () 101 | { 102 | FILE *tmp_file = ::tmpfile (); 103 | SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT{ 104 | if (nullptr != tmp_file) { 105 | ::fclose (tmp_file); 106 | } 107 | }; 108 | 109 | File ret_file; 110 | if (nullptr != tmp_file) { 111 | int fd = fileutil::Dup (::fileno (tmp_file)); 112 | if (LIKELY (-1 != fd)) { 113 | File f (fd, true); 114 | ret_file.Swap (f); 115 | } 116 | } 117 | 118 | return ret_file; 119 | } 120 | 121 | } // namespace swift 122 | -------------------------------------------------------------------------------- /swift/base/fileutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include "swift/base/fileutil.h" 16 | 17 | #include 18 | #include 19 | 20 | namespace swift { 21 | namespace fileutil { 22 | 23 | int Open (const char *file_name, 24 | int flags /*= O_RDWR | O_LARGEFILE | O_CREAT*/, 25 | mode_t mode /*= 0666*/) 26 | { 27 | return detail::WrapFuncT (open, file_name, flags, mode); 28 | } 29 | 30 | int Close (int fd) 31 | { 32 | int ret = close (fd); 33 | // Ignore EINTR. On Linux, close() may only return EINTR after the file 34 | // descriptor has been closed, so you must not retry close() on EINTR -- 35 | // in the best case, you'll get EBADF, and in the worst case, you'll end up 36 | // closing a different file (one opened from another thread). 37 | // 38 | // Interestingly enough, the Single Unix Specification says that the state 39 | // of the file descriptor is unspecified if close returns EINTR. In that 40 | // case, the safe thing to do is also not to retry close() -- leaking a file 41 | // descriptor is probably better than closing the wrong file. 42 | return (-1 == ret && EINTR == errno) ? 0 : ret; 43 | } 44 | 45 | int Dup (int fd) 46 | { 47 | return detail::WrapFuncT (dup, fd); 48 | } 49 | 50 | int Dup2 (int old_fd, int new_fd) 51 | { 52 | return detail::WrapFuncT (dup2, old_fd, new_fd); 53 | } 54 | 55 | int Fsync (int fd) 56 | { 57 | return detail::WrapFuncT (fsync, fd); 58 | } 59 | 60 | int Fdatasync (int fd) 61 | { 62 | return detail::WrapFuncT (fdatasync, fd); 63 | } 64 | 65 | int Ftrucate (int fd, off_t length) 66 | { 67 | return detail::WrapFuncT (ftruncate, fd, length); 68 | } 69 | 70 | int Truncate (const char *path, off_t length) 71 | { 72 | return detail::WrapFuncT (truncate, path, length); 73 | } 74 | 75 | int Flock (int fd, int operation) 76 | { 77 | return detail::WrapFuncT (flock, fd, operation); 78 | } 79 | 80 | int Shutdown (int fd, int how) 81 | { 82 | return detail::WrapFuncT (shutdown, fd, how); 83 | } 84 | 85 | ssize_t Read (int fd, void *buf, size_t length) 86 | { 87 | return detail::WrapFuncT (read, fd, buf, length); 88 | } 89 | 90 | ssize_t PRead (int fd, void *buf, size_t length, off_t offset) 91 | { 92 | return detail::WrapFuncT (pread, fd, buf, length, offset); 93 | } 94 | 95 | ssize_t Readv (int fd, const iovec *iov, int length) 96 | { 97 | return detail::WrapFuncT (readv, fd, iov, length); 98 | } 99 | 100 | ssize_t Write (int fd, const void *buf, size_t length) 101 | { 102 | return detail::WrapFuncT (write, fd, buf, length); 103 | } 104 | 105 | ssize_t PWrite (int fd, void *buf, size_t length, off_t offset) 106 | { 107 | return detail::WrapFuncT (pwrite, fd, buf, length, offset); 108 | } 109 | 110 | ssize_t Writev (int fd, const iovec *iov, int length) 111 | { 112 | return detail::WrapFuncT (writev, fd, iov, length); 113 | } 114 | 115 | ssize_t ReadFull (int fd, void *buf, size_t length) 116 | { 117 | return detail::WrapFileOpFuncT (read, fd, buf, length); 118 | } 119 | 120 | ssize_t PReadFull (int fd, void *buf, size_t length, off_t offset) 121 | { 122 | return detail::WrapFileOpFuncT (pread, fd, buf, length, offset); 123 | } 124 | 125 | ssize_t ReadvFull (int fd, iovec *iov, int length) 126 | { 127 | return detail::WrapFileOpVFuncT (readv, fd, iov, length); 128 | } 129 | 130 | ssize_t PReadvFull (int fd, iovec *iov, int length, off_t offset) 131 | { 132 | return detail::WrapFileOpVFuncT (preadv, fd, iov, length, offset); 133 | } 134 | 135 | ssize_t WriteFull (int fd, const void *buf, size_t length) 136 | { 137 | return detail::WrapFileOpFuncT (write, fd, const_cast(buf), length); 138 | } 139 | 140 | ssize_t PWriteFull (int fd, const void *buf, size_t length, off_t offset) 141 | { 142 | return detail::WrapFileOpFuncT (pwrite, fd, const_cast(buf), length, offset); 143 | } 144 | 145 | ssize_t WritevFull (int fd, iovec *iov, int length) 146 | { 147 | return detail::WrapFileOpVFuncT (writev, fd, iov, length); 148 | } 149 | 150 | ssize_t PWritevFull (int fd, iovec *iov, int length, off_t offset) 151 | { 152 | return detail::WrapFileOpVFuncT (pwritev, fd, iov, length, offset); 153 | } 154 | 155 | bool DeleteFile (const char* file_name) 156 | { 157 | if (nullptr == file_name) { 158 | return false; 159 | } 160 | 161 | return 0 == ::unlink (file_name); 162 | } 163 | 164 | bool GetFileSize (const char* file_name, size_t* size) 165 | { 166 | if (nullptr == file_name) { 167 | return false; 168 | } 169 | 170 | struct stat file_stats; 171 | if (::lstat (file_name, &file_stats) != 0) { 172 | return false; 173 | } 174 | 175 | *size = file_stats.st_size; 176 | return true; 177 | } 178 | 179 | } // fileutil 180 | } // namespace swift 181 | -------------------------------------------------------------------------------- /swift/base/guid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 ApusApp 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "swift/base/guid.h" 18 | 19 | #include // snprintf 20 | #include // strtoull 21 | 22 | #include "swift/base/stringpiece.h" 23 | #include "swift/base/random.h" 24 | 25 | namespace swift { 26 | 27 | const char* Guid::kHexChars = "0123456789ABCDEF"; 28 | 29 | // static public 30 | bool Guid::RandomDataToGuidString(const uint64_t bytes[2], std::string& guid) 31 | { 32 | char buf[64]; 33 | size_t n = snprintf(buf, sizeof(buf), "%08X-%04X-%04X-%04X-%012llX", 34 | static_cast(bytes[0] >> 32), 35 | static_cast((bytes[0] >> 16) & 0x0000ffff), 36 | static_cast(bytes[0] & 0x0000ffff), 37 | static_cast(bytes[1] >> 48), 38 | bytes[1] & 0x0000ffffffffffffULL); 39 | if (36 == n) { 40 | guid = std::move(std::string(buf, n)); 41 | return true; 42 | } 43 | 44 | return false; 45 | } 46 | 47 | // static public 48 | bool Guid::Generate(std::string& guid) 49 | { 50 | uint64_t bytes[2] = { Random::RandUInt64(), Random::RandUInt64() }; 51 | return RandomDataToGuidString(bytes, guid); 52 | } 53 | 54 | // static public 55 | bool Guid::IsValid(const std::string& guid) 56 | { 57 | size_t len = guid.size(); 58 | if (36u != len) { 59 | return false; 60 | } 61 | 62 | StringPiece hex_chars(kHexChars, 16); 63 | for (size_t i = 0; i < len; ++i) { 64 | char c = guid[i]; 65 | if (i == 8 || i == 13 || i == 18 || i == 23) { 66 | if ('-' != c) { 67 | return false; 68 | } 69 | } else { 70 | if (StringPiece::npos == hex_chars.find(c)) { 71 | return false; 72 | } 73 | } 74 | } 75 | 76 | return true; 77 | } 78 | 79 | // public 80 | Guid::Guid() 81 | { 82 | for (uint32_t i = 0; i < sizeof(bytes_) / sizeof(uint64_t); ++i) { 83 | bytes_[i] = Random::RandUInt64(); 84 | } 85 | } 86 | 87 | // public 88 | Guid::Guid(const std::string& guid) 89 | { 90 | if (36u == guid.size() && IsValid(guid)) { 91 | size_t n = 0; 92 | size_t j = 0; 93 | char buf[17] = { '\0' }; 94 | for (size_t i = 0; i < guid.size(); ++i) { 95 | if (i == 8 || i == 13 || i == 18 || i == 23) { 96 | continue; 97 | } 98 | 99 | buf[j++] = guid[i]; 100 | if (17 == i || 35 == i) { 101 | buf[16] = '\0'; 102 | bytes_[n++] = std::strtoull(buf, nullptr, 16); 103 | j = 0; 104 | } 105 | } 106 | } else { 107 | for (uint32_t i = 0; i < sizeof(bytes_) / sizeof(uint64_t); ++i) { 108 | bytes_[i] = 0u; 109 | } 110 | } 111 | } 112 | 113 | // public 114 | Guid::Guid(const Guid& guid) 115 | { 116 | if (this != &guid) { 117 | for (uint32_t i = 0; i < sizeof(bytes_) / sizeof(uint64_t); ++i) { 118 | bytes_[i] = guid.bytes_[i]; 119 | } 120 | } 121 | } 122 | 123 | // public 124 | Guid& Guid::operator= (const Guid& rhs) 125 | { 126 | if (this != &rhs) { 127 | for (uint32_t i = 0; i < sizeof(bytes_) / sizeof(uint64_t); ++i) { 128 | bytes_[i] = rhs.bytes_[i]; 129 | } 130 | } 131 | 132 | return *this; 133 | } 134 | 135 | } // namespace swift 136 | -------------------------------------------------------------------------------- /swift/base/guid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 ApusApp 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __SWIFT_BASE_GUID_H__ 18 | #define __SWIFT_BASE_GUID_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace swift { 25 | 26 | class Guid 27 | { 28 | public: 29 | Guid(); 30 | Guid(const std::string& guid); 31 | ~Guid() {}; 32 | 33 | Guid(const Guid& guid); 34 | Guid& operator=(const Guid& rhs); 35 | 36 | inline bool IsValid() const 37 | { 38 | return (0 != bytes_[0]) || (0 != bytes_[1]); 39 | } 40 | 41 | inline std::string ToString() const 42 | { 43 | assert(true == IsValid()); 44 | std::string guid; 45 | RandomDataToGuidString(bytes_, guid); 46 | return guid; 47 | } 48 | 49 | bool operator== (const Guid& rhs) const 50 | { 51 | return (bytes_[0] == rhs.bytes_[0]) && (bytes_[1] == rhs.bytes_[1]); 52 | } 53 | 54 | public: 55 | // Generate a 128 bit random GUID of the form: "%08X-%04X-%04X-%04X-%012llX". 56 | static bool Generate(std::string& guid); 57 | 58 | // Returns true if the input string conforms to the GUID format. 59 | static bool IsValid(const std::string& guid); 60 | 61 | static bool RandomDataToGuidString(const uint64_t bytes[2], std::string& guid); 62 | 63 | private: 64 | uint64_t bytes_[2]; 65 | 66 | private: 67 | static const char* kHexChars; 68 | }; 69 | } // namespace swift 70 | 71 | #endif // __SWIFT_BASE_GUID_H__ 72 | -------------------------------------------------------------------------------- /swift/base/likely.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | // These definition are faster than "if" branch 16 | // return true of false 17 | 18 | #ifndef __SWIFT_BASE_LIKELY_H__ 19 | #define __SWIFT_BASE_LIKELY_H__ 20 | 21 | #undef LIKELY 22 | #undef UNLIKELY 23 | 24 | #if defined(__GNC__) && __GNC__ >= 4 25 | #define LIKELY(x) (__builtin_expect((x), 1)) 26 | #define UNLIKELY(x) (__builtin_expect((x), 0)) 27 | #else 28 | #define LIKELY(x) (x) 29 | #define UNLIKELY(x) (x) 30 | #endif 31 | 32 | #endif // __SWIFT_BASE_LIKELY_H__ 33 | -------------------------------------------------------------------------------- /swift/base/linkedhashmap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include "swift/base/linkedhashmap.h" 16 | #include 17 | 18 | namespace swift { 19 | namespace detail { 20 | void* MapAlloc (size_t size) 21 | { 22 | assert (size > 0 && size <= std::numeric_limits::max () / 2); 23 | void* ptr = ::mmap (0, sizeof(size) + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 24 | if (MAP_FAILED == ptr) { 25 | throw std::bad_alloc (); 26 | } 27 | 28 | *(size_t*)ptr = size; 29 | return (char*)ptr + sizeof(size); 30 | } 31 | 32 | void MapFree (void* ptr) 33 | { 34 | if (ptr) { 35 | size_t size = *((size_t*)ptr - 1); 36 | ::munmap ((char*)ptr - sizeof(size), sizeof(size) + size); 37 | } 38 | } 39 | } // namespace swift 40 | } // namespace swift 41 | -------------------------------------------------------------------------------- /swift/base/logging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_LOGGING_H__ 16 | #define __SWIFT_BASE_LOGGING_H__ 17 | 18 | #include 19 | 20 | namespace swift { 21 | 22 | } // namespace swift 23 | 24 | #endif // __SWIFT_BASE_LOGGING_H__ 25 | -------------------------------------------------------------------------------- /swift/base/lru_cache.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_LRU_CACHE_HPP__ 16 | #define __SWIFT_BASE_LRU_CACHE_HPP__ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace swift { 23 | 24 | template 25 | class LruCache { 26 | private: 27 | typedef typename std::pair KeyValuePairType; 28 | typedef typename std::list::iterator ListIteratorType; 29 | 30 | public: 31 | LruCache(size_t capacity); 32 | void Set(const KeyType& key, const ValueType& value); 33 | bool Get(const KeyType& key, ValueType& value); 34 | 35 | private: 36 | std::mutex mutex_; 37 | size_t capacity_; 38 | std::list cache_items_list_; 39 | std::unordered_map cache_items_map_; 40 | }; 41 | 42 | template 43 | swift::LruCache::LruCache(size_t capacity) 44 | : capacity_(capacity) { 45 | } 46 | 47 | template 48 | void swift::LruCache::Set(const KeyType& key, const ValueType& value) { 49 | std::unique_lock lock(mutex_); 50 | 51 | auto it = cache_items_map_.find(key); 52 | if (it != cache_items_map_.end()) { 53 | cache_items_list_.erase(it->second); 54 | cache_items_map_.erase(it); 55 | } 56 | 57 | cache_items_list_.push_front(KeyValuePairType(key, value)); 58 | cache_items_map_[key] = cache_items_list_.begin(); 59 | 60 | if (cache_items_map_.size() > capacity_) { 61 | cache_items_map_.erase(cache_items_list_.back().first); 62 | cache_items_list_.pop_back(); 63 | } 64 | } 65 | 66 | template 67 | bool swift::LruCache::Get(const KeyType& key, ValueType& value) { 68 | std::unique_lock lock(mutex_); 69 | 70 | auto it = cache_items_map_.find(key); 71 | if (it == cache_items_map_.end()) { 72 | return false; 73 | } else { 74 | cache_items_list_.splice(cache_items_list_.begin(), cache_items_list_, it->second); 75 | value = it->second->second; 76 | return true; 77 | } 78 | } 79 | 80 | } // namespace swift 81 | 82 | #endif // __SWIFT_BASE_LRU_CACHE_HPP__ 83 | -------------------------------------------------------------------------------- /swift/base/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_MD5_H__ 16 | #define __SWIFT_BASE_MD5_H__ 17 | 18 | #include 19 | #include "swift/base/noncopyable.hpp" 20 | 21 | namespace swift { 22 | namespace detail { 23 | // The output of an MD5 operation. 24 | struct MD5Digest 25 | { 26 | MD5Digest () 27 | { 28 | Init (); 29 | } 30 | 31 | inline void Init () 32 | { 33 | memset (digest, 0, sizeof(digest)); 34 | } 35 | 36 | unsigned char digest[16]; 37 | }; 38 | 39 | // Used for storing intermediate data during an MD5 computation. Callers 40 | // should not access the data. 41 | typedef char MD5Context[88]; 42 | 43 | } // namespace detail 44 | 45 | // Example: 46 | // MD5 md5; 47 | // md5.Update ("abc", 3); 48 | // md5.Update (StringPiece ("defg")); 49 | // md5.Final (); 50 | // std::string result = md5.ToString (); 51 | // or 52 | // std::string result; 53 | // MD5::Md5Sum ("abcdefg", 7, result); 54 | // or 55 | // std::string result; 56 | // MD5::Md5Sum (StringPiece ("abcdefg"), result); 57 | class StringPiece; 58 | class MD5 : swift::noncopyable 59 | { 60 | public: 61 | MD5 (); 62 | ~MD5 (); 63 | 64 | void Update (const void* data, size_t length); 65 | void Update (const StringPiece& str); 66 | void Final (); 67 | void Reset (); 68 | std::string ToString () const; 69 | 70 | inline bool Valid () const 71 | { 72 | return complete_; 73 | } 74 | 75 | bool operator== (const MD5& rhs) const; 76 | 77 | inline bool operator!= (const MD5& rhs) const 78 | { 79 | return (*this == rhs) ? false : true; 80 | } 81 | 82 | // movable 83 | MD5 (MD5&&) = default; 84 | MD5& operator= (MD5&&) = default; 85 | 86 | public: 87 | static void Md5Sum (const StringPiece& str, std::string& out); 88 | static void Md5Sum (const void* data, size_t length, std::string& out); 89 | 90 | private: 91 | bool complete_; 92 | detail::MD5Digest digest_; 93 | detail::MD5Context context_; 94 | }; // MD5 95 | 96 | } // namespace swift 97 | 98 | #endif // __SWIFT_BASE_MD5_H__ 99 | -------------------------------------------------------------------------------- /swift/base/murmurhash3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | // MurmurHash3 was written by Austin Appleby, and is placed in the public 16 | // domain. The author hereby disclaims copyright to this source code. 17 | 18 | #ifndef __SWIFT_BASE_MURMUR_HASH3_H__ 19 | #define __SWIFT_BASE_MURMUR_HASH3_H__ 20 | 21 | #include 22 | 23 | namespace swift { 24 | 25 | void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out); 26 | 27 | void MurmurHash3_x86_128 (const void *key, int len, uint32_t seed, void *out); 28 | 29 | void MurmurHash3_x64_128 (const void *key, int len, uint32_t seed, void *out); 30 | } 31 | 32 | #endif // __SWIFT_BASE_MURMUR_HASH3_H__ 33 | -------------------------------------------------------------------------------- /swift/base/noncopyable.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_NONCOPYABLE_HPP__ 16 | #define __SWIFT_BASE_NONCOPYABLE_HPP__ 17 | 18 | namespace swift { 19 | 20 | // Private copy constructor and copy assignment ensure classes derived from 21 | // class noncopyable cannot be copied. 22 | 23 | namespace noncopyable_ // protection from unintended ADL 24 | { 25 | class noncopyable 26 | { 27 | protected: 28 | noncopyable () {} 29 | ~noncopyable () {} 30 | 31 | private: // emphasize the following members are private 32 | noncopyable (const noncopyable&); 33 | const noncopyable& operator= (const noncopyable&); 34 | }; 35 | } 36 | 37 | typedef noncopyable_::noncopyable noncopyable; 38 | 39 | } // namespace swift 40 | 41 | #endif // __SWIFT_BASE_NONCOPYABLE_HPP__ 42 | -------------------------------------------------------------------------------- /swift/base/random.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include "swift/base/random.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "swift/base/logging.h" 25 | #include "swift/base/file.h" 26 | #include "swift/base/likely.h" 27 | #include "swift/base/singleton.hpp" 28 | 29 | namespace swift { 30 | namespace { 31 | 32 | // Use Singleton ot keep it open for the durarion of the program 33 | class RandomDevice : public Singleton 34 | { 35 | public: 36 | RandomDevice() : dev_() 37 | { 38 | PCHECK(true == dev_.Open("/dev/urandom")); 39 | } 40 | 41 | inline void Read(void* data, size_t size) 42 | { 43 | PCHECK(size == dev_.Read(static_cast(data), size)); 44 | } 45 | 46 | private: 47 | File dev_; 48 | }; 49 | 50 | class BufferedRandomDevice 51 | { 52 | public: 53 | explicit BufferedRandomDevice(size_t buffer_size = kDefaultBufferSize) 54 | : buffer_size_(buffer_size) 55 | , buffer_(new unsigned char[buffer_size]) 56 | , ptr_(buffer_.get() + buffer_size) 57 | { 58 | 59 | }; 60 | 61 | ~BufferedRandomDevice() {}; 62 | 63 | void Get(void* data, size_t size) 64 | { 65 | if (LIKELY(size <= Remaining())) { 66 | ::memcpy(data, ptr_, size); 67 | ptr_ += size; 68 | } else { 69 | GetSlow(static_cast(data), size); 70 | } 71 | } 72 | 73 | private: 74 | void GetSlow(unsigned char* data, size_t size) 75 | { 76 | DCHECK_GT(size, Remaining()); 77 | if (size >= buffer_size_) { 78 | // Just read directly 79 | RandomDevice::Instance().Read(data, size); 80 | return; 81 | } 82 | 83 | size_t copied = Remaining(); 84 | ::memcpy(data, ptr_, copied); 85 | data += copied; 86 | size -= copied; 87 | 88 | // refill 89 | RandomDevice::Instance().Read(buffer_.get(), buffer_size_); 90 | ptr_ = buffer_.get(); 91 | 92 | ::memcpy(data, ptr_, size); 93 | ptr_ += size; 94 | } 95 | 96 | inline size_t Remaining() const 97 | { 98 | return buffer_.get() + buffer_size_ - ptr_; 99 | } 100 | 101 | public: 102 | static constexpr size_t kDefaultBufferSize = 128; 103 | 104 | private: 105 | const size_t buffer_size_; 106 | std::unique_ptr buffer_; 107 | unsigned char* ptr_; 108 | }; // BufferedRandomDevice 109 | 110 | ThreadLocal buffered_random_device; 111 | 112 | } // anonymous namespace 113 | 114 | namespace detail { 115 | 116 | class ThreadLocalPRNG::LocalInstancePRNG 117 | { 118 | public: 119 | LocalInstancePRNG() : rng_(std::move(Random::Create())) {} 120 | ~LocalInstancePRNG() {} 121 | 122 | public: 123 | Random::DefaultGenerator rng_; 124 | }; 125 | 126 | ThreadLocal ThreadLocalPRNG::kLocalInstance; 127 | 128 | ThreadLocalPRNG::ThreadLocalPRNG() : local_(kLocalInstance.Get()) 129 | { 130 | if (nullptr == local_) { 131 | local_ = InitLocal(); 132 | } 133 | } 134 | 135 | // static private 136 | ThreadLocalPRNG::LocalInstancePRNG* ThreadLocalPRNG::InitLocal() 137 | { 138 | LocalInstancePRNG* prng = new LocalInstancePRNG; 139 | kLocalInstance.Reset(prng); 140 | return prng; 141 | } 142 | 143 | // static private 144 | uint32_t ThreadLocalPRNG::GetImpl(LocalInstancePRNG* local) 145 | { 146 | assert(nullptr != local); 147 | return local->rng_(); 148 | } 149 | 150 | } // namespace detail 151 | 152 | // static public 153 | void Random::SecureRandom(void* data, size_t size) 154 | { 155 | buffered_random_device->Get(data, size); 156 | } 157 | 158 | } // namespace swift 159 | -------------------------------------------------------------------------------- /swift/base/scopeguard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_SCOPE_GUARD_H__ 16 | #define __SWIFT_BASE_SCOPE_GUARD_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace swift { 23 | 24 | /** 25 | * ScopeGuard is a general implementation of the "Initialization is 26 | * Resource Acquisition" idiom. Basically, it guarantees that a function 27 | * is executed upon leaving the current scope unless otherwise told. 28 | * 29 | * The MakeScopeGuard () function is used to create a new ScopeGuard object. 30 | * It can be instantiated with a lambda function, a std::function, 31 | * a functor, or a void(*)() function pointer. 32 | * 33 | * 34 | * Usage example: Add a friend to memory if it is also added to the db. 35 | * 36 | * void User::AddFriend (User& newFriend) { 37 | * // add the friend to memory 38 | * friends_.push_back (&newFriend); 39 | * 40 | * // If the db insertion that follows fails, we should 41 | * // remove it from memory. 42 | * // (You could also declare this as "auto guard = MakeScopeGuard (...)") 43 | * swift::ScopeGuard guard = swift::MakeScopeGuard([&] { friends_.pop_back(); }); 44 | * 45 | * // this will throw an exception upon error, which 46 | * // makes the ScopeGuard execute UserCont::pop_back() 47 | * // once the Guard's destructor is called. 48 | * db_->AddFriend(GetName (), newFriend.GetName ()); 49 | * 50 | * // an exception was not thrown, so don't execute 51 | * // the Guard. 52 | * guard.Dismiss (); 53 | * } 54 | * // For more, to see unit test 55 | * 56 | * Stolen from: 57 | * Andrei's and Petru Marginean's CUJ article: 58 | * http://drdobbs.com/184403758 59 | * and the loki library: 60 | * http://loki-lib.sourceforge.net/index.php?n=Idioms.ScopeGuardPointer 61 | * and triendl.kj article: 62 | * http://www.codeproject.com/KB/cpp/scope_guard.aspx 63 | */ 64 | 65 | namespace detail { 66 | 67 | class ScopeGuardBase 68 | { 69 | public: 70 | inline void Dismiss () noexcept 71 | { 72 | dismissed_ = true; 73 | } 74 | 75 | protected: 76 | ScopeGuardBase () : dismissed_ (false) 77 | { 78 | } 79 | 80 | ScopeGuardBase (ScopeGuardBase&& other) 81 | : dismissed_ (other.dismissed_) 82 | { 83 | other.dismissed_ = true; 84 | } 85 | 86 | protected: 87 | bool dismissed_; 88 | }; 89 | 90 | template 91 | class ScopeGuardImpl : public ScopeGuardBase 92 | { 93 | public: 94 | explicit ScopeGuardImpl (const FuncT& func) 95 | : function_ (func) 96 | { 97 | } 98 | 99 | explicit ScopeGuardImpl (FuncT&& func) 100 | : function_ (std::move (func)) 101 | { 102 | } 103 | 104 | ScopeGuardImpl (ScopeGuardImpl&& other) 105 | : ScopeGuardBase (std::move (other)) 106 | , function_ (std::move (other.function_)) 107 | { 108 | other.dismissed_ = true; 109 | } 110 | 111 | ~ScopeGuardImpl () 112 | { 113 | if (!dismissed_) { 114 | function_ (); 115 | } 116 | } 117 | 118 | private: 119 | void* operator new(size_t) = delete; 120 | 121 | private: 122 | FuncT function_; 123 | }; 124 | 125 | // Internal use for the macro SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT below 126 | enum class ScopeGuardOnExit {}; 127 | 128 | template 129 | ScopeGuardImpl::type> 130 | operator+ (detail::ScopeGuardOnExit, FuncT&& func) { 131 | return ScopeGuardImpl::type> ( 132 | std::forward (func)); 133 | } 134 | 135 | } // namespace detail 136 | 137 | template 138 | detail::ScopeGuardImpl::type> 139 | MakeScopeGuard (FuncT&& func) { 140 | return detail::ScopeGuardImpl::type> ( 141 | std::forward (func)); 142 | } 143 | 144 | 145 | typedef detail::ScopeGuardBase&& ScopeGuard; 146 | 147 | } // namespace swift 148 | 149 | #ifndef SWIFT_ANONYMOUS_VARIABLES 150 | #define SWIFT_ANONYMOUS_VARIABLES_IMPL(s1, s2) s1##s2 151 | #define SWIFT_ANONYMOUS_VARIABLES(str) SWIFT_ANONYMOUS_VARIABLES_IMPL(str, __LINE__) 152 | #endif 153 | #ifndef SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT 154 | #define SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT \ 155 | auto SWIFT_ANONYMOUS_VARIABLES(SCOPE_GUARD_EXIT_STATE) \ 156 | = ::swift::detail::ScopeGuardOnExit () + [&]() noexcept 157 | 158 | #endif 159 | 160 | #endif // __SWIFT_BASE_SCOPE_GUARD_H__ -------------------------------------------------------------------------------- /swift/base/sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_SHA1_H__ 16 | #define __SWIFT_BASE_SHA1_H__ 17 | 18 | #include 19 | #include 20 | 21 | #include "swift/base/noncopyable.hpp" 22 | 23 | namespace swift { 24 | namespace detail { 25 | 26 | struct Sha1Context 27 | { 28 | uint32_t state[5]; 29 | uint32_t count[2]; 30 | unsigned char buffer[64]; 31 | }; 32 | 33 | struct Sha1Digest 34 | { 35 | Sha1Digest() 36 | { 37 | Init(); 38 | } 39 | 40 | inline void Init() 41 | { 42 | memset(digest, 0, sizeof(digest)); 43 | } 44 | 45 | unsigned char digest[20]; 46 | }; 47 | 48 | /** 49 | * @param [in] data 50 | * @param [in] length 51 | * @param [out] sha1 52 | */ 53 | void ComputeSha1(const void* data, uint32_t length, std::string* sha1); 54 | void Sha1Init(Sha1Context* context); 55 | void Sha1Update(Sha1Context* context, 56 | const unsigned char* data, 57 | uint32_t length); 58 | void Sha1Final(Sha1Context* context, Sha1Digest* digest); 59 | } // namespace detail 60 | 61 | // Example: 62 | // Sha1 sha1; 63 | // sha1.Update ("abc", 3); 64 | // sha1.Update (StringPiece ("defg")); 65 | // sha1.Final (); 66 | // std::string result = sha1.ToString (); 67 | // or 68 | // std::string result; 69 | // Sha1::Sha1Sum ("abcdefg", 7, &result); 70 | // or 71 | // std::string result; 72 | // Sha1::Sha1Sum (StringPiece ("abcdefg"), &result); 73 | class StringPiece; 74 | class Sha1 : swift::noncopyable 75 | { 76 | public: 77 | Sha1(); 78 | ~Sha1(); 79 | 80 | inline void Update(const void* data, size_t length) 81 | { 82 | if (data && length) { 83 | detail::Sha1Update(&context_, 84 | reinterpret_cast(data), 85 | static_cast(length)); 86 | complete_ = true; 87 | } 88 | } 89 | 90 | void Update(const StringPiece& str); 91 | 92 | inline void Final() 93 | { 94 | if (complete_) { 95 | detail::Sha1Final(&context_, &digest_); 96 | } 97 | } 98 | 99 | inline void Reset() 100 | { 101 | digest_.Init(); 102 | memset(&context_, 0, sizeof(context_)); 103 | detail::Sha1Init(&context_); 104 | complete_ = false; 105 | } 106 | 107 | std::string ToString() const; 108 | 109 | inline bool Valid() const 110 | { 111 | return complete_; 112 | } 113 | 114 | inline bool operator== (const Sha1& rhs) const 115 | { 116 | if (!complete_ && !rhs.complete_) { 117 | return true; 118 | } 119 | 120 | return (0 == memcmp(digest_.digest, 121 | rhs.digest_.digest, 122 | sizeof(digest_.digest))); 123 | } 124 | 125 | inline bool operator!= (const Sha1& rhs) const 126 | { 127 | return (*this == rhs) ? false : true; 128 | } 129 | 130 | // movable 131 | Sha1 (Sha1&&) = default; 132 | Sha1& operator=(Sha1&&) = default; 133 | 134 | public: 135 | static void Sha1Sum(const StringPiece& str, std::string* out); 136 | 137 | /** 138 | * @param [in] data 139 | * @param [in] length 140 | * @param [out] sha1 141 | */ 142 | static inline void Sha1Sum(const void* data, 143 | size_t length, 144 | std::string* sha1) 145 | { 146 | if (data && length) { 147 | detail::ComputeSha1(data, static_cast(length), sha1); 148 | } 149 | } 150 | 151 | private: 152 | bool complete_; 153 | detail::Sha1Digest digest_; 154 | detail::Sha1Context context_; 155 | }; 156 | 157 | } // namespace swift 158 | 159 | #endif // __SWIFT_BASE_SHA1_H__ 160 | -------------------------------------------------------------------------------- /swift/base/singleton.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_SINGLETON_HPP__ 16 | #define __SWIFT_BASE_SINGLETON_HPP__ 17 | 18 | #include 19 | #include "swift/base/noncopyable.hpp" 20 | 21 | // used example 22 | // T& instance = Singleton::Instance (); 23 | 24 | namespace swift { 25 | 26 | template 27 | class Singleton : swift::noncopyable 28 | { 29 | public: 30 | inline static T& Instance () 31 | { 32 | T* instance = GetInstance(); 33 | 34 | return *instance; 35 | } 36 | 37 | inline static T* GetInstance() 38 | { 39 | std::call_once (ponce_, &Singleton::Init); 40 | 41 | return value_; 42 | } 43 | 44 | protected: 45 | Singleton () {}; 46 | ~Singleton () {}; 47 | 48 | private: 49 | inline static void Init () 50 | { 51 | if (0 == value_) { 52 | value_ = new T (); 53 | ::atexit (Destroy); 54 | } 55 | } 56 | 57 | inline static void Destroy () 58 | { 59 | // this typedef is to avoid T is not a complete type 60 | typedef char T_must_be_complete_type[sizeof (T) == 0 ? -1 : 1]; 61 | T_must_be_complete_type dummy; (void) dummy; 62 | if (nullptr != value_) { 63 | delete value_; 64 | value_ = nullptr; 65 | } 66 | } 67 | 68 | private: 69 | static std::once_flag ponce_; 70 | static T* volatile value_; 71 | }; 72 | 73 | template 74 | std::once_flag Singleton::ponce_; 75 | 76 | template 77 | T* volatile Singleton::value_ = nullptr; 78 | 79 | } // end of name space swift 80 | 81 | #endif // __SWIFT_BASE_SINGLETON_HPP__ 82 | -------------------------------------------------------------------------------- /swift/base/stacktrace.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "swift/base/stacktrace.h" 26 | 27 | namespace swift { 28 | 29 | namespace { 30 | 31 | void PrintStackTraceByLine (const char *program_name, 32 | const char *symbol, 33 | void *frame) 34 | { 35 | if (symbol) { 36 | fprintf (stderr, "%s ", symbol); 37 | } 38 | 39 | const int line_max = 256; 40 | char cmd[line_max] = { '\0' }; 41 | snprintf (cmd, sizeof(cmd), 42 | "addr2line %p -e %s -f -C 2>&1", 43 | frame, program_name); 44 | FILE *f = popen (cmd, "r"); 45 | if (nullptr != f) { 46 | char line[line_max] = { '\0' }; 47 | while (fgets (line, sizeof(line), f)) { 48 | line[strlen (line) - 1] = '\0'; 49 | fprintf (stderr, "%s\t", line); 50 | } 51 | pclose (f); 52 | } 53 | else { 54 | fprintf (stderr, " %p", frame); 55 | } 56 | 57 | fprintf (stderr, "\n"); 58 | } 59 | } // namespace 60 | 61 | // static public 62 | bool StackTrace::GetExecutableName (std::string* name) 63 | { 64 | assert (nullptr != name); 65 | char buf[1024] = { '\0' }; 66 | char link[64] = { '\0' }; 67 | 68 | snprintf (link, sizeof(link), "/proc/%d/exe", getpid ()); 69 | ssize_t n = readlink (link, buf, sizeof(buf)); 70 | if (-1 == n) { 71 | return false; 72 | } 73 | else { 74 | buf[n] = '\0'; 75 | name->clear (); 76 | name->append (buf); 77 | } 78 | 79 | return true; 80 | } 81 | 82 | // static public 83 | void StackTrace::PrintStack (int first_frames_to_skip /*= 0*/) 84 | { 85 | void* buf[100]; 86 | int size = ::backtrace (buf, 100); 87 | std::unique_ptr stacks{ 88 | ::backtrace_symbols (buf, size), 89 | std::free 90 | }; 91 | 92 | if (nullptr != stacks.get ()) { 93 | std::string program_name; 94 | bool running = GetExecutableName (&program_name); 95 | for (int i = first_frames_to_skip; i < size && running; ++i) { 96 | fprintf (stderr, "#%-2d ", i - first_frames_to_skip); 97 | PrintStackTraceByLine (program_name.c_str (), stacks.get ()[i], buf[i]); 98 | } 99 | } 100 | } 101 | 102 | // static private 103 | void StackTrace::StackTraceHandler (int signal_num) 104 | { 105 | // reset to default handler 106 | signal (signal_num, SIG_DFL); 107 | 108 | fprintf (stderr, "Received signal %d (%s)\n", signal_num, strsignal (signal_num)); 109 | PrintStack (3); 110 | 111 | // re-signal to default handler 112 | raise (signal_num); 113 | } 114 | 115 | // static public 116 | void StackTrace::InitStackTraceHandler () 117 | { 118 | signal (SIGILL, StackTraceHandler); 119 | signal (SIGSEGV, StackTraceHandler); 120 | signal (SIGBUS, StackTraceHandler); 121 | signal (SIGABRT, StackTraceHandler); 122 | } 123 | 124 | } // namespace swift 125 | -------------------------------------------------------------------------------- /swift/base/stacktrace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_STACK_TRACE_H__ 16 | #define __SWIFT_BASE_STACK_TRACE_H__ 17 | 18 | #include 19 | 20 | namespace swift { 21 | 22 | class StackTrace 23 | { 24 | public: 25 | // get current program name 26 | static bool GetExecutableName (std::string* name); 27 | 28 | // init a signal handler to print callstack on the following signal: 29 | // SIGILL SIGSEGV SIGBUS SIGABRT 30 | static void InitStackTraceHandler (); 31 | 32 | static void PrintStack (int first_frames_to_skip = 0); 33 | 34 | private: 35 | static void StackTraceHandler (int signal_num); 36 | }; 37 | } 38 | #endif // __SWIFT_BASE_STACK_TRACE_H__ -------------------------------------------------------------------------------- /swift/base/thisthread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "swift/base/thisthread.h" 25 | 26 | namespace swift { 27 | namespace detail { 28 | 29 | inline pid_t GetTid () 30 | { 31 | return static_cast(::syscall (SYS_gettid)); 32 | } 33 | 34 | void AfterFork () 35 | { 36 | swift::thisthread::t_cached_tid = 0; 37 | swift::thisthread::t_thread_name = "__swift_main_thread__"; 38 | swift::thisthread::GetTid (); 39 | } 40 | 41 | class ThreadNameInitializer 42 | { 43 | public: 44 | ThreadNameInitializer () 45 | { 46 | swift::thisthread::t_thread_name = "__swift_main_thread__"; 47 | swift::thisthread::GetTid (); 48 | pthread_atfork (nullptr, nullptr, &detail::AfterFork); 49 | } 50 | 51 | ~ThreadNameInitializer () 52 | { 53 | 54 | } 55 | }; 56 | 57 | } // namespace detail 58 | 59 | detail::ThreadNameInitializer init; 60 | 61 | namespace thisthread { 62 | __thread int t_cached_tid = 0; 63 | __thread char t_tid_string[32]; 64 | __thread const char* t_thread_name = "__swift_thread__"; 65 | 66 | void CacheTid () 67 | { 68 | if (0 == t_cached_tid) { 69 | t_cached_tid = detail::GetTid (); 70 | int length = snprintf (t_tid_string, sizeof(t_tid_string), "%5d ", t_cached_tid); 71 | assert (6 == length); (void) length; 72 | } 73 | } 74 | 75 | bool IsMainThread () 76 | { 77 | return GetTid () == ::getpid (); 78 | } 79 | 80 | } // namespace thisthread 81 | 82 | } // namespace swift 83 | -------------------------------------------------------------------------------- /swift/base/thisthread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_THIS_THREAD_H__ 16 | #define __SWIFT_BASE_THIS_THREAD_H__ 17 | 18 | #include 19 | 20 | #include "swift/base/likely.h" 21 | 22 | namespace swift { 23 | namespace thisthread { 24 | // internal 25 | extern __thread int t_cached_tid; 26 | extern __thread char t_tid_string[32]; 27 | extern __thread const char* t_thread_name; 28 | 29 | void CacheTid (); 30 | bool IsMainThread (); 31 | inline int GetTid () 32 | { 33 | if (UNLIKELY (0 == t_cached_tid)) { 34 | CacheTid (); 35 | } 36 | 37 | return t_cached_tid; 38 | } 39 | 40 | inline const char* TidToString () 41 | { 42 | if (UNLIKELY (0 == t_cached_tid)) { 43 | CacheTid (); 44 | } 45 | 46 | return t_tid_string; 47 | } 48 | 49 | inline const char* GetName () 50 | { 51 | return t_thread_name; 52 | } 53 | 54 | } // namespace thisthread 55 | } // namespace swift 56 | #endif // __SWIFT_BASE_THIS_THREAD_H__ 57 | -------------------------------------------------------------------------------- /swift/base/threadlocal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_THREAD_LOCAL_H__ 16 | #define __SWIFT_BASE_THREAD_LOCAL_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "swift/base/noncopyable.hpp" 27 | 28 | namespace swift { 29 | 30 | // ThreadLocalPtr is stolen from the rocksdb and change some implementation 31 | typedef void (*UnrefHandler) (void* ptr); 32 | class ThreadLocalPtr 33 | { 34 | public: 35 | explicit ThreadLocalPtr (UnrefHandler handler = nullptr); 36 | ~ThreadLocalPtr (); 37 | 38 | void* Get () const; 39 | void Reset (void* ptr); 40 | void* Swap (void* ptr); 41 | bool CompareAndSwap (void* ptr, void*& expected); 42 | void Scrape (std::vector* ptrs, const void* replacement); 43 | 44 | protected: 45 | struct Entry 46 | { 47 | Entry () : ptr (nullptr) {} 48 | Entry (const Entry& other) : ptr (other.ptr.load (std::memory_order_relaxed)) {} 49 | std::atomic ptr; 50 | }; 51 | 52 | struct ThreadData 53 | { 54 | ThreadData () : next (nullptr), prev (nullptr) {} 55 | std::vector entries; 56 | ThreadData* next; 57 | ThreadData* prev; 58 | }; 59 | 60 | class StaticMeta 61 | { 62 | public: 63 | StaticMeta (); 64 | 65 | uint32_t GetId (); 66 | uint32_t PeekId () const; 67 | void* Get (uint32_t id); 68 | void Reset (uint32_t id, void* ptr); 69 | void* Swap (uint32_t id, void* ptr); 70 | void ReclaimId (uint32_t id); 71 | void Scrape (uint32_t id, std::vector* ptrs, const void* replacement); 72 | bool CompareAndSwap (uint32_t id, void* ptr, void*& expected); 73 | void SetHandler (uint32_t id, UnrefHandler handler); 74 | 75 | private: 76 | UnrefHandler GetHandler (uint32_t id) const; 77 | void AddThreadData (ThreadData* data); 78 | void RemoveThreadData (ThreadData* data); 79 | 80 | private: 81 | static void OnThreadExit (void* ptr); 82 | static ThreadData* GetThreadLocal (); 83 | 84 | private: 85 | ThreadData head_; 86 | pthread_key_t key_; 87 | uint32_t next_instance_id_; 88 | std::vector free_instance_ids_; 89 | std::unordered_map handler_map_; 90 | 91 | static std::mutex kLock_; 92 | static __thread ThreadData *kTls_; 93 | }; // StaticMeta 94 | 95 | static StaticMeta* Instance (); 96 | 97 | const uint32_t id_; 98 | }; 99 | 100 | template 101 | class ThreadLocal : swift::noncopyable 102 | { 103 | public: 104 | ThreadLocal () : tlp_ (OnThreadExit) { } 105 | ~ThreadLocal () {} 106 | 107 | T* Get () const 108 | { 109 | T* ptr = static_cast(tlp_.Get ()); 110 | if (nullptr != ptr) { 111 | return ptr; 112 | } 113 | 114 | return MakeTls (); 115 | } 116 | 117 | T* operator-> () const { 118 | return Get (); 119 | } 120 | 121 | T& operator* () const { 122 | return *Get (); 123 | } 124 | 125 | void Reset (T* t = nullptr) 126 | { 127 | tlp_.Reset (t); 128 | } 129 | 130 | // movable 131 | ThreadLocal (ThreadLocal&&) = default; 132 | ThreadLocal& operator= (ThreadLocal&&) = default; 133 | 134 | private: 135 | static void OnThreadExit (void* obj) 136 | { 137 | T* ptr = static_cast(obj); 138 | typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1]; 139 | T_must_be_complete_type dummy; (void) dummy; 140 | if (nullptr != ptr) { 141 | delete ptr; 142 | } 143 | } 144 | 145 | // Tls: Thread Local Storage 146 | T* MakeTls () const 147 | { 148 | T* ptr = new T (); 149 | tlp_.Reset (ptr); 150 | return ptr; 151 | } 152 | 153 | private: 154 | mutable ThreadLocalPtr tlp_; 155 | }; 156 | } // namespace swift 157 | #endif // __SWIFT_BASE_THREAD_LOCAL_H__ 158 | -------------------------------------------------------------------------------- /swift/base/threadpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_THREAD_POOL_H__ 16 | #define __SWIFT_BASE_THREAD_POOL_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "swift/base/noncopyable.hpp" 25 | 26 | namespace swift { 27 | 28 | class ThreadPool : swift::noncopyable 29 | { 30 | class Worker; 31 | public: 32 | typedef std::function Task; 33 | 34 | public: 35 | explicit ThreadPool (int threads_number = 4); 36 | 37 | // blocks until all tasks are complete (TasksRemaining () == 0) 38 | // You should not call schedule while in the destructor 39 | ~ThreadPool (); 40 | 41 | // must call this function at first use 42 | void Start (); 43 | 44 | // blocks until all tasks are complete (TasksRemaining () == 0) 45 | // does not prevent new tasks from being scheduled so could wait forever. 46 | // Also, new tasks could be scheduled after this returns. 47 | void Join (); 48 | 49 | // task will be copied a few times so make sure it's relatively cheap 50 | void Schedule (const Task& task); 51 | 52 | void Schedule (Task&& task); 53 | 54 | // Helpers that wrap schedule and std::bind. 55 | // Functor and args will be copied a few times so make sure it's relatively cheap 56 | template 57 | void Schedule (F f, A a) 58 | { 59 | Schedule (std::move (std::bind (f, a))); 60 | } 61 | 62 | template 63 | void Schedule (F f, A a, B b) 64 | { 65 | Schedule (std::move (std::bind (f, a, b))); 66 | } 67 | 68 | template 69 | void Schedule (F f, A a, B b, C c) 70 | { 71 | Schedule (std::move (std::bind (f, a, b, c))); 72 | } 73 | 74 | template 75 | void Schedule (F f, A a, B b, C c, D d) 76 | { 77 | Schedule (std::move (std::bind (f, a, b, c, d))); 78 | } 79 | 80 | template 81 | void Schedule (F f, A a, B b, C c, D d, E e) 82 | { 83 | Schedule (std::move (std::bind (f, a, b, c, d, e))); 84 | } 85 | 86 | int TasksRemaining () const 87 | { 88 | return tasks_remaining_; 89 | } 90 | 91 | private: 92 | std::mutex mutex_; 93 | std::condition_variable condition_; 94 | 95 | std::list free_workers_; //used as LIFO stack (always front) 96 | std::list tasks_; //used as FIFO queue (push_back, pop_front) 97 | std::atomic tasks_remaining_; // in queue + currently processing 98 | int threads_number_; // only used for sanity checking. could be removed in the future. 99 | 100 | // should only be called by a worker from the worker's thread 101 | void TaskDone (Worker* worker); 102 | 103 | friend class Worker; 104 | }; 105 | 106 | } // namespace swift 107 | #endif //__SWIFT_BASE_THREAD_POOL_H__ -------------------------------------------------------------------------------- /swift/base/timestamp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include // for static_assert 16 | #include 17 | #include 18 | 19 | #include "swift/base/timestamp.h" 20 | 21 | namespace swift { 22 | 23 | static_assert (sizeof(Timestamp) == sizeof(int64_t), "sizeof(Timestamp) must equal to sizeof(int64_t)"); 24 | 25 | Timestamp::Timestamp () : micro_seconds_since_epoch_ (0) 26 | { 27 | } 28 | 29 | Timestamp::Timestamp (const Timestamp& rhs) 30 | { 31 | if (this != &rhs) { 32 | micro_seconds_since_epoch_ = rhs.micro_seconds_since_epoch_; 33 | } 34 | } 35 | 36 | Timestamp::Timestamp (const int64_t micro_seconds_since_epoch) 37 | : micro_seconds_since_epoch_ (micro_seconds_since_epoch) 38 | { 39 | 40 | } 41 | 42 | Timestamp::~Timestamp () 43 | { 44 | 45 | } 46 | 47 | Timestamp& Timestamp::operator= (const Timestamp& rhs) 48 | { 49 | if (this != &rhs) { 50 | micro_seconds_since_epoch_ = rhs.micro_seconds_since_epoch_; 51 | } 52 | 53 | return *this; 54 | } 55 | 56 | // static public 57 | Timestamp Timestamp::Now () 58 | { 59 | struct timeval tv; 60 | gettimeofday (&tv, NULL); 61 | return Timestamp (tv.tv_sec * kMicroSecondsPerSecond + tv.tv_usec); 62 | } 63 | 64 | // static public 65 | Timestamp Timestamp::Invalid () 66 | { 67 | return Timestamp (); 68 | } 69 | 70 | // public 71 | std::string Timestamp::ToSecDotMicroString () const 72 | { 73 | char buf[32] = {0}; 74 | int64_t seconds = static_cast(micro_seconds_since_epoch_ / kMicroSecondsPerSecond); 75 | int64_t microseconds = micro_seconds_since_epoch_ % kMicroSecondsPerSecond; 76 | // PRId64 GCC compile with -D__STDC_FORMAT_MACROS and include 77 | int size = snprintf (buf, sizeof(buf) - 1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); 78 | return std::string (buf, size); 79 | } 80 | 81 | // public 82 | std::string Timestamp::ToString () const 83 | { 84 | char buf[32] = {0}; 85 | int size = snprintf (buf, sizeof(buf) - 1, "%" PRId64"", micro_seconds_since_epoch_); 86 | return std::string (buf, size); 87 | } 88 | 89 | // public 90 | std::string Timestamp::ToFormattedString (bool show_microseconds /*= true*/) const 91 | { 92 | char buf[32] = {0}; 93 | time_t seconds = static_cast(micro_seconds_since_epoch_ / kMicroSecondsPerSecond); 94 | int microseconds = static_cast(micro_seconds_since_epoch_ % kMicroSecondsPerSecond); 95 | struct tm tm_time; 96 | gmtime_r(&seconds, &tm_time); 97 | 98 | if (show_microseconds) { 99 | snprintf (buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d.%06d", 100 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 101 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, 102 | microseconds); 103 | } 104 | else { 105 | snprintf (buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d", 106 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 107 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); 108 | } 109 | return std::string (buf); 110 | } 111 | 112 | } // namespace swift 113 | -------------------------------------------------------------------------------- /swift/base/timestamp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_TIMESTAMP_H__ 16 | #define __SWIFT_BASE_TIMESTAMP_H__ 17 | 18 | #include 19 | #include 20 | 21 | namespace swift { 22 | 23 | class Timestamp 24 | { 25 | public: 26 | Timestamp (); 27 | ~Timestamp (); 28 | explicit Timestamp (const int64_t micro_seconds_since_epoch); 29 | 30 | Timestamp (const Timestamp& rhs); 31 | Timestamp& operator= (const Timestamp& rhs); 32 | 33 | void Swap (Timestamp& that) 34 | { 35 | std::swap (micro_seconds_since_epoch_, that.micro_seconds_since_epoch_); 36 | } 37 | 38 | std::string ToSecDotMicroString () const; 39 | std::string ToString () const; 40 | 41 | std::string ToFormattedString (bool show_microseconds = true) const; 42 | 43 | bool Valid () const { return micro_seconds_since_epoch_ > 0; } 44 | 45 | // for internal usage. 46 | int64_t MicroSecondsSinceEpoch () const 47 | { 48 | return micro_seconds_since_epoch_; 49 | } 50 | 51 | time_t SecondsSinceEpoch () const 52 | { 53 | return static_cast (micro_seconds_since_epoch_ / kMicroSecondsPerSecond); 54 | } 55 | 56 | static Timestamp Now (); 57 | 58 | static Timestamp Invalid (); 59 | 60 | static const int kMicroSecondsPerSecond = 1000 * 1000; 61 | 62 | private: 63 | int64_t micro_seconds_since_epoch_; 64 | }; 65 | 66 | inline bool operator< (const Timestamp& lhs, const Timestamp& rhs) 67 | { 68 | return lhs.MicroSecondsSinceEpoch () < rhs.MicroSecondsSinceEpoch (); 69 | } 70 | 71 | inline bool operator== (const Timestamp& lhs, const Timestamp& rhs) 72 | { 73 | return lhs.MicroSecondsSinceEpoch () == rhs.MicroSecondsSinceEpoch (); 74 | } 75 | 76 | inline bool operator!= (const Timestamp& lhs, const Timestamp& rhs) 77 | { 78 | return !(lhs == rhs); 79 | } 80 | 81 | inline bool operator> (const Timestamp& lhs, const Timestamp& rhs) 82 | { 83 | return !(lhs < rhs) && (lhs != rhs); 84 | } 85 | 86 | /** 87 | * Gets time difference of two timestamps, result in seconds. 88 | * 89 | * @param high, low 90 | * @return (high-low) in seconds 91 | * @c double has 52-bit precision, enough for one-microsecond 92 | * resolution for next 100 years. 93 | */ 94 | inline double TimeDifference (const Timestamp& high, const Timestamp& low) 95 | { 96 | int64_t diff = high.MicroSecondsSinceEpoch () - low.MicroSecondsSinceEpoch (); 97 | return static_cast(diff) / Timestamp::kMicroSecondsPerSecond; 98 | } 99 | 100 | /** 101 | * Add @c seconds to given timestamp. 102 | * 103 | * @return timestamp+seconds as Timestamp 104 | */ 105 | inline Timestamp AddTime (const Timestamp& timestamp, double seconds) 106 | { 107 | int64_t delta = static_cast(seconds * Timestamp::kMicroSecondsPerSecond); 108 | return Timestamp (timestamp.MicroSecondsSinceEpoch () + delta); 109 | } 110 | 111 | } // end of namespace swift 112 | 113 | #endif // __SWIFT_BASE_TIMESTAMP_H__ 114 | -------------------------------------------------------------------------------- /swift/base/timezone.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_BASE_TIME_ZONE_H__ 16 | #define __SWIFT_BASE_TIME_ZONE_H__ 17 | 18 | #include 19 | #include 20 | 21 | namespace swift { 22 | 23 | class TimeZone 24 | { 25 | public: 26 | explicit TimeZone (const char* zone_file); 27 | TimeZone (int east_of_utc, const char* tzname); // a fixed timezone 28 | TimeZone () {} // an invalid timezone 29 | ~TimeZone() {} 30 | 31 | bool Valid () const 32 | { 33 | // 'explicit operator bool() const' in C++11 34 | return static_cast(data_); 35 | } 36 | 37 | struct tm ToLocalTime (time_t seconds_since_epoch) const; 38 | 39 | time_t FromLocalTime (const struct tm& t) const; 40 | 41 | // gmtime(3) 42 | static struct tm ToUtcTime (time_t seconds_since_epoch, bool yday = false); 43 | 44 | // timegm(3) 45 | static time_t FromUtcTime (const struct tm& t); 46 | 47 | // year in [1900..2500], month in [1..12], day in [1..31] 48 | static time_t FromUtcTime (int year, int month, int day, 49 | int hour, int minute, int seconds); 50 | 51 | struct Data; 52 | 53 | private: 54 | std::shared_ptr data_; 55 | }; // end of TimeZone 56 | 57 | } // end of namespace swift 58 | 59 | #endif // __SWIFT_BASE_TIME_ZONE_H__ -------------------------------------------------------------------------------- /swift/disruptor/README.md: -------------------------------------------------------------------------------- 1 | Disruptor 2 | ========= 3 | 4 | C++ simple implementations of the LMAX disruptor. 5 | 6 | 7 | API 8 | ========= 9 | 10 | * *RingBuffer* is a circular buffer with Power of 2 Size 11 | * *WriteCursor* tracks a position in the buffer and can follow 12 | other read cursors to ensure things don't wrap. 13 | * *SharedWriteCursor* is a write cursor that may be used from multiple threads 14 | other read cursors to ensure things don't wrap. 15 | * *ReadCursor* tracks the read position and can follow / block 16 | on other cursors (read or write). 17 | 18 | 19 | The concept of the cursors are separated from the data storage. Every cursor 20 | should read from one or more sources and write to its own output buffer. 21 | 22 | Features 23 | ========== 24 | * Progressive-backoff blocking. When one cursor needs to wait on another it starts 25 | out with a busy wait, followed by a yield, and ultimately falls back to sleeping 26 | wait if the queue is stalled. 27 | 28 | * Batch writing / Reading with 'iterator like' interface. Producers and consumers 29 | always work with a 'range' of valid positions. The ring buffer provides the 30 | ability to detect 'wraping' and therefore it should be possible to use this as 31 | a data queue for a socket that can read/write many slots all at once. Slots 32 | could be single bytes and the result would be a very effecient stream-processing 33 | library. 34 | 35 | 36 | -------------------------------------------------------------------------------- /swift/net/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME swift_net) 5 | 6 | aux_source_directory (../base base_SRCS) 7 | aux_source_directory (../base/experimental base_exp_SRCS) 8 | aux_source_directory (. net_SRCS) 9 | aux_source_directory (httpclient net_httpclient_SRCS) 10 | add_library (${TARGET_NAME} ${base_SRCS} ${base_exp_SRCS} ${net_SRCS} ${net_httpclient_SRCS}) 11 | target_link_libraries (${TARGET_NAME} pthread glog gflags curl) 12 | set_target_properties (${TARGET_NAME} PROPERTIES COMPILE_FLAGS "-std=c++0x -Wno-deprecated") 13 | 14 | install(TARGETS ${TARGET_NAME} DESTINATION lib) -------------------------------------------------------------------------------- /swift/net/httpclient/easycurl.inl: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_EASY_CURL_INL__ 16 | #define __SWIFT_NET_HTTP_CLIENT_EASY_CURL_INL__ 17 | 18 | #include 19 | 20 | #include "swift/net/httpclient/request.hpp" 21 | #include "swift/net/httpclient/response.hpp" 22 | 23 | namespace swift { 24 | 25 | // public 26 | void EasyCurl::Reset() 27 | { 28 | if (curl_) { 29 | Destroy(); 30 | curl_easy_reset(curl_); 31 | Init(); 32 | } 33 | } 34 | 35 | // public 36 | void EasyCurl::SetPort(const long port) 37 | { 38 | assert(0 != curl_); 39 | curl_easy_setopt(curl_, CURLOPT_PORT, port); 40 | } 41 | 42 | // public 43 | void EasyCurl::SetUrl(const char* url) 44 | { 45 | assert(0 != url); 46 | assert(0 != curl_); 47 | curl_easy_setopt(curl_, CURLOPT_URL, url); 48 | } 49 | 50 | // public 51 | void EasyCurl::SetReadTimeout(size_t timeout) 52 | { 53 | assert(0 != curl_); 54 | if (timeout > 0) { 55 | curl_easy_setopt(curl_, CURLOPT_TIMEOUT, timeout); 56 | } 57 | } 58 | 59 | // public 60 | void EasyCurl::SetConnectTimeout(size_t timeout) 61 | { 62 | assert(0 != curl_); 63 | if (timeout > 0) { 64 | curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, timeout); 65 | } 66 | } 67 | 68 | // static private 69 | size_t EasyCurl::BodyHandler(void *data, size_t size, size_t nmemb, void *user_data) 70 | { 71 | if (user_data && data && size * nmemb > 0) { 72 | return (reinterpret_cast(user_data))->Write(Middleware::OPERATE_TYPE_BODY, 73 | reinterpret_cast(data), 74 | size * nmemb); 75 | } 76 | 77 | return size * nmemb; 78 | } 79 | 80 | // static private 81 | size_t EasyCurl::HeaderHandler(void *data, size_t size, size_t nmemb, void *user_data) 82 | { 83 | if (user_data && data && size * nmemb > 0) { 84 | return (reinterpret_cast(user_data))->Write(Middleware::OPERATE_TYPE_HEADER, 85 | reinterpret_cast(data), 86 | size * nmemb); 87 | } 88 | 89 | return size * nmemb; 90 | } 91 | 92 | 93 | // static private 94 | size_t EasyCurl::EmptyHandler(void *data, size_t size, size_t nmemb, void *user_data) 95 | { 96 | return size * nmemb; 97 | } 98 | 99 | // public 100 | void EasyCurl::Middleware::SetResponseStatusCode(int code) 101 | { 102 | if (response_) { 103 | response_->SetStatusCode(code); 104 | } 105 | } 106 | 107 | // static public 108 | void EasyCurl::GlobalInit() 109 | { 110 | curl_global_init(CURL_GLOBAL_DEFAULT); 111 | } 112 | 113 | // static public 114 | void EasyCurl::GlobalCleanUp() 115 | { 116 | curl_global_cleanup(); 117 | } 118 | 119 | } // namespace swift 120 | 121 | #endif // __SWIFT_NET_HTTP_CLIENT_EASY_CURL_INL__ 122 | -------------------------------------------------------------------------------- /swift/net/httpclient/easycurlpool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include "swift/net/httpclient/easycurlpool.h" 16 | 17 | namespace swift { 18 | 19 | const std::unique_ptr EasyCurlPool::kPool(new EasyCurlPool); 20 | 21 | // public 22 | EasyCurlPool::EasyCurlHandlerSPtrType EasyCurlPool::Get() 23 | { 24 | { 25 | ReadLockGuard lock(lock_); 26 | size_t size = handlers_.size(); 27 | for (size_t i = 0; i < size; ++i) { 28 | size_t n = std::atomic_fetch_add(&rider_, static_cast(1)); 29 | if (n >= size) { 30 | std::atomic_store(&rider_, static_cast(0)); 31 | n = 0; 32 | } 33 | 34 | EasyCurlHandlerSPtrType &conn = handlers_[n]; 35 | if (conn->UsedCompareExchange(false, true)) { 36 | return conn; 37 | } 38 | } 39 | } 40 | 41 | EasyCurlHandlerSPtrType handler(new EasyCurlHandler); 42 | { 43 | WriteLockGuard lock(lock_); 44 | if (handlers_.size() < kMax) { 45 | handlers_.push_back(handler); 46 | handler->SetUsed(true); 47 | } 48 | } 49 | 50 | return handler; 51 | } 52 | 53 | EasyCurlPool::~EasyCurlPool() 54 | { 55 | EasyCurl::GlobalCleanUp(); 56 | } 57 | 58 | EasyCurlPool::EasyCurlPool() : lock_(), rider_(0), handlers_() 59 | { 60 | EasyCurl::GlobalInit(); 61 | } 62 | 63 | } // namespace swift 64 | -------------------------------------------------------------------------------- /swift/net/httpclient/easycurlpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_H__ 16 | #define __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "swift/base/rwspinlock.h" 24 | #include "swift/base/noncopyable.hpp" 25 | #include "swift/net/httpclient/easycurl.h" 26 | 27 | namespace swift { 28 | 29 | class EasyCurlPool : swift::noncopyable 30 | { 31 | private: 32 | class EasyCurlHandler : swift::noncopyable 33 | { 34 | public: 35 | EasyCurlHandler () : curl_(), used_(false) 36 | { 37 | } 38 | 39 | inline ~EasyCurlHandler(); 40 | inline EasyCurl& GetCurl(); 41 | inline bool GetUsed() const; 42 | inline bool UsedCompareExchange(bool compare_value, bool used); 43 | inline void SetUsed(bool used); 44 | inline void Reset(); 45 | 46 | private: 47 | EasyCurl curl_; 48 | std::atomic used_; 49 | }; 50 | 51 | typedef RWTicketSpinLock64 LockType; 52 | typedef typename RWTicketSpinLock64::ReadHolder ReadLockGuard; 53 | typedef typename RWTicketSpinLock64::WriteHolder WriteLockGuard; 54 | 55 | public: 56 | typedef std::shared_ptr EasyCurlHandlerSPtrType; 57 | 58 | class EasyCurlHolder 59 | { 60 | public: 61 | EasyCurlHolder(const EasyCurlHandlerSPtrType& handler) : handler_(handler) 62 | { 63 | 64 | } 65 | 66 | inline ~EasyCurlHolder(); 67 | inline EasyCurl& GetEasyCurl() const; 68 | private: 69 | const EasyCurlHandlerSPtrType handler_; 70 | }; 71 | 72 | public: 73 | static inline EasyCurlPool& Instance(); 74 | inline void Clear(); 75 | EasyCurlHandlerSPtrType Get(); 76 | ~EasyCurlPool(); 77 | 78 | private: 79 | EasyCurlPool(); 80 | 81 | private: 82 | LockType lock_; 83 | std::atomic rider_; 84 | std::vector handlers_; 85 | static const int kMax = 100; 86 | static const std::unique_ptr kPool; 87 | }; // ConnectionPool 88 | 89 | } // namespace swift 90 | 91 | #include "swift/net/httpclient/easycurlpool.inl" 92 | 93 | #endif // __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_H__ 94 | -------------------------------------------------------------------------------- /swift/net/httpclient/easycurlpool.inl: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_INL__ 16 | #define __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_INL__ 17 | 18 | namespace swift { 19 | 20 | // static public 21 | EasyCurlPool& EasyCurlPool::Instance() 22 | { 23 | return *kPool; 24 | } 25 | 26 | // public 27 | void EasyCurlPool::Clear() 28 | { 29 | WriteLockGuard lock(lock_); 30 | handlers_.clear(); 31 | rider_.store(0, std::memory_order_release); 32 | } 33 | 34 | // public 35 | EasyCurlPool::EasyCurlHolder::~EasyCurlHolder() 36 | { 37 | handler_->Reset(); 38 | handler_->SetUsed(false); 39 | } 40 | 41 | // public 42 | EasyCurl& EasyCurlPool::EasyCurlHolder::GetEasyCurl() const 43 | { 44 | return handler_->GetCurl(); 45 | } 46 | 47 | // public 48 | void EasyCurlPool::EasyCurlHandler::Reset() 49 | { 50 | curl_.Reset(); 51 | } 52 | 53 | // public 54 | void EasyCurlPool::EasyCurlHandler::SetUsed(bool used) 55 | { 56 | used_.store(used, std::memory_order_release); 57 | } 58 | 59 | // public 60 | bool EasyCurlPool::EasyCurlHandler::GetUsed() const 61 | { 62 | return used_.load(std::memory_order_acquire); 63 | } 64 | 65 | // public 66 | bool EasyCurlPool::EasyCurlHandler::UsedCompareExchange(bool compare_value, bool used) 67 | { 68 | return std::atomic_compare_exchange_strong(&used_, &compare_value, used); 69 | } 70 | 71 | // public 72 | EasyCurl& EasyCurlPool::EasyCurlHandler::GetCurl() 73 | { 74 | return curl_; 75 | } 76 | 77 | EasyCurlPool::EasyCurlHandler::~EasyCurlHandler() 78 | { 79 | 80 | } 81 | } // namespace swift 82 | 83 | #endif // __SWIFT_NET_HTTP_CLIENT_EASY_CURL_POOL_INL__ 84 | -------------------------------------------------------------------------------- /swift/net/httpclient/httpclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_H__ 16 | #define __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "swift/base/noncopyable.hpp" 24 | #include "swift/net/httpclient/easycurl.h" 25 | #include "swift/net/httpclient/httpcode.hpp" 26 | #include "swift/net/httpclient/request.hpp" 27 | #include "swift/net/httpclient/response.hpp" 28 | 29 | 30 | namespace swift { 31 | 32 | class File; 33 | struct ReceiveHandler; 34 | 35 | class HttpClient : swift::noncopyable 36 | { 37 | public: 38 | HttpClient(); 39 | ~HttpClient(); 40 | 41 | inline int Get(const Request* req, Response* resp) const; 42 | inline int Head(const Request* req, Response* resp) const; 43 | inline int Copy(const Request* req, Response* resp) const; 44 | inline int Delete(const Request* req, Response* resp) const; 45 | inline int Put(const Request* req, Response* resp) const; 46 | inline int Post(const Request* req, Response* resp) const; 47 | int Get(const Request* req, Response* resp, 48 | const File* file, size_t size=std::numeric_limits::max(), size_t offset=0) const; 49 | int Put(const Request* req, Response* resp, 50 | const File* file, size_t size=std::numeric_limits::max(), size_t offset=0) const; 51 | 52 | int Get(const Request* req, Response* resp, char* buf, size_t size) const; 53 | 54 | inline std::shared_ptr Get(const Request* req) const; 55 | inline std::shared_ptr Head(const Request* req) const; 56 | inline std::shared_ptr Copy(const Request* req) const; 57 | inline std::shared_ptr Delete(const Request* req) const; 58 | inline std::shared_ptr Put(const Request* req) const; 59 | inline std::shared_ptr Post(const Request* req) const; 60 | std::shared_ptr Get(const Request* req, const File* file) const; 61 | std::shared_ptr Put(const Request* req, const File* file) const; 62 | 63 | private: 64 | int Do(const HttpMethod& method, const Request* req, Response* resp) const; 65 | 66 | private: 67 | static const ReceiveHandler kHeaderHandler; 68 | static const ReceiveHandler kBodyAndHeaderHandler; 69 | static void HeaderHandler(Response* resp, const char* data, const size_t size); 70 | static void BodyHandler(Response* resp, const char* data, const size_t size); 71 | }; 72 | 73 | } 74 | 75 | #include "swift/net/httpclient/httpclient.inl" 76 | 77 | #endif // __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_H__ -------------------------------------------------------------------------------- /swift/net/httpclient/httpclient.inl: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_INL__ 16 | #define __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_INL__ 17 | 18 | namespace swift { 19 | 20 | // public 21 | int HttpClient::Head(const Request* req, Response* resp) const 22 | { 23 | return Do(HTTP_METHOD_HEAD, req, resp); 24 | } 25 | 26 | // public 27 | int HttpClient::Get(const Request* req, Response* resp) const 28 | { 29 | return Do(HTTP_METHOD_GET, req, resp); 30 | } 31 | 32 | // public 33 | int HttpClient::Copy(const Request* req, Response* resp) const 34 | { 35 | return Do(HTTP_METHOD_COPY, req, resp); 36 | } 37 | 38 | // public 39 | int HttpClient::Delete(const Request* req, Response* resp) const 40 | { 41 | return Do(HTTP_METHOD_DELETE, req, resp); 42 | } 43 | 44 | // public 45 | int HttpClient::Put(const Request* req, Response* resp) const 46 | { 47 | return Do(HTTP_METHOD_PUT, req, resp); 48 | } 49 | 50 | // public 51 | int HttpClient::Post(const Request* req, Response* resp) const 52 | { 53 | return Do(HTTP_METHOD_POST, req, resp); 54 | } 55 | 56 | // public 57 | std::shared_ptr HttpClient::Get(const Request* req) const 58 | { 59 | std::shared_ptr resp = std::make_shared(); 60 | Get(req, resp.get()); 61 | return resp; 62 | } 63 | 64 | // public 65 | std::shared_ptr HttpClient::Head(const Request* req) const 66 | { 67 | std::shared_ptr resp = std::make_shared(); 68 | Head(req, resp.get()); 69 | return resp; 70 | } 71 | 72 | // public 73 | std::shared_ptr HttpClient::Copy(const Request* req) const 74 | { 75 | std::shared_ptr resp = std::make_shared(); 76 | Copy(req, resp.get()); 77 | return resp; 78 | } 79 | 80 | // public 81 | std::shared_ptr HttpClient::Delete(const Request* req) const 82 | { 83 | std::shared_ptr resp = std::make_shared(); 84 | Delete(req, resp.get()); 85 | return resp; 86 | } 87 | 88 | // public 89 | std::shared_ptr HttpClient::Put(const Request* req) const 90 | { 91 | std::shared_ptr resp = std::make_shared(); 92 | Put(req, resp.get()); 93 | return resp; 94 | } 95 | 96 | // public 97 | std::shared_ptr HttpClient::Post(const Request* req) const 98 | { 99 | std::shared_ptr resp = std::make_shared(); 100 | Post(req, resp.get()); 101 | return resp; 102 | } 103 | } 104 | 105 | #endif // __SWIFT_NET_HTTP_CLIENT_HTTP_CLIENT_INL__ 106 | -------------------------------------------------------------------------------- /swift/net/httpclient/httpcode.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_HTTP_CODE_HPP__ 16 | #define __SWIFT_NET_HTTP_CLIENT_HTTP_CODE_HPP__ 17 | 18 | namespace swift { 19 | 20 | // List of HTTP status codes 21 | enum HttpCode 22 | { 23 | //############################################################################### 24 | //## 1xx Informational 25 | //############################################################################### 26 | HTTP_CONTINUE = 100, 27 | HTTP_SWITCHING_PROTOCOLS = 101, 28 | HTTP_PROCESSING = 102, 29 | HTTP_CHECKPOINT = 103, 30 | 31 | //############################################################################### 32 | //## 2xx Success 33 | //############################################################################### 34 | HTTP_OK = 200, 35 | HTTP_CREATED = 201, 36 | HTTP_ACCEPTED = 202, 37 | HTTP_NON_AUTHORITATIVE_INFORMATION = 203, 38 | HTTP_NO_CONTENT = 204, 39 | HTTP_RESET_CONTENT = 205, 40 | HTTP_PARTIAL_CONTENT = 206, 41 | HTTP_MULTI_STATUS = 207, 42 | HTTP_IM_USED = 226, 43 | 44 | //############################################################################### 45 | //## 3xx Redirection 46 | //############################################################################### 47 | HTTP_MULTIPLE_CHOICES = 300, 48 | HTTP_MOVED_PERMANENTLY = 301, 49 | HTTP_FOUND = 302, 50 | HTTP_SEE_OTHER = 303, 51 | HTTP_NOT_MODIFIED = 304, 52 | HTTP_USE_PROXY = 305, 53 | HTTP_SWITCH_PROXY = 306, 54 | HTTP_TEMPORARY_REDIRECT = 307, 55 | HTTP_RESUME_INCOMPLETE = 308, 56 | 57 | //############################################################################### 58 | //## 4xx Client Error 59 | //############################################################################### 60 | HTTP_BAD_REQUEST = 400, 61 | HTTP_UNAUTHORIZED = 401, 62 | HTTP_PAYMENT_REQUIRED = 402, 63 | HTTP_FORBIDDEN = 403, 64 | HTTP_NOT_FOUND = 404, 65 | HTTP_METHOD_NOT_ALLOWED = 405, 66 | HTTP_NOT_ACCEPTABLE = 406, 67 | HTTP_PROXY_AUTHENTICATION_REQUIRED = 407, 68 | HTTP_REQUEST_TIMEOUT = 408, 69 | HTTP_CONFLICT = 409, 70 | HTTP_GONE = 410, 71 | HTTP_LENGTH_REQUIRED = 411, 72 | HTTP_PRECONDITION_FAILED = 412, 73 | HTTP_REQUEST_ENTITY_TOO_LARGE = 413, 74 | HTTP_REQUEST_URI_TOO_LONG = 414, 75 | HTTP_UNSUPPORTED_MEDIA_TYPE = 415, 76 | HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416, 77 | HTTP_EXPECTATION_FAILED = 417, 78 | HTTP_IM_A_TEAPOT = 418, 79 | HTTP_UNPROCESSABLE_ENTITY = 422, 80 | HTTP_LOCKED = 423, 81 | HTTP_FAILED_DEPENDENCY = 424, 82 | HTTP_UNORDERED_COLLECTION = 425, 83 | HTTP_UPGRADE_REQUIED = 426, 84 | HTTP_PRECONDITION_REQUIRED = 428, 85 | HTTP_TOO_MANY_REQUESTS = 429, 86 | HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, 87 | HTTP_NO_RESPONSE = 444, 88 | HTTP_RETRY_WITH = 449, 89 | HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450, 90 | HTTP_CLIENT_CLOSED_REQUEST = 499, 91 | 92 | //############################################################################### 93 | //## 5xx Server Error 94 | //############################################################################### 95 | HTTP_INTERNAL_SERVER_ERROR = 500, 96 | HTTP_NOT_IMPLEMENTED = 501, 97 | HTTP_BAD_GATEWAY = 502, 98 | HTTP_SERVICE_UNAVAILABLE = 503, 99 | HTTP_GATEWAY_TIMEOUT = 504, 100 | HTTP_VERSION_NOT_SUPPORTED = 505, 101 | HTTP_VARIANT_ALSO_NEGOTIATES = 506, 102 | HTTP_INSUFFICIENT_STORAGE = 507, 103 | HTTP_BANDWIDTH_LIMIT_EXCEEDED = 509, 104 | HTTP_NOT_EXTENDED = 510, 105 | HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511, 106 | HTTP_NETWORK_READ_TIMEOUT_ERROR = 598, // not used in RFC 107 | HTTP_NETWORK_CONNECT_TIMEOUT_ERROR = 599, // not used in RFC 108 | }; 109 | 110 | } // namespace swift 111 | 112 | #endif //__SWIFT_NET_HTTP_CLIENT_HTTP_CODE_HPP__ 113 | -------------------------------------------------------------------------------- /swift/net/httpclient/request.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | 16 | #ifndef __SWIFT_NET_HTTP_CLIENT_REQUEST_HPP__ 17 | #define __SWIFT_NET_HTTP_CLIENT_REQUEST_HPP__ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "swift/base/noncopyable.hpp" 24 | 25 | namespace swift { 26 | 27 | class Request : swift::noncopyable { 28 | 29 | public: 30 | Request() : size_(0), read_timeout_(30), connect_timeout_(3) 31 | , data_(nullptr), url_(), headers_() 32 | { 33 | headers_.insert(std::move( 34 | std::make_pair(std::move(std::string("User-Agent")), 35 | std::move(std::string("SwiftCli/1.0"))))); 36 | } 37 | 38 | ~Request() 39 | { 40 | if (nullptr != data_) { 41 | data_ = nullptr; 42 | } 43 | 44 | size_ = 0; 45 | } 46 | 47 | inline void SetReadTimeout(int timeout /* seconds */) 48 | { 49 | assert(timeout >= 0); 50 | read_timeout_ = timeout; 51 | } 52 | 53 | inline int GetReadTimeout() const 54 | { 55 | return read_timeout_; 56 | } 57 | 58 | inline void SetConnectTimeout(int timeout /* seconds */) 59 | { 60 | assert(timeout >= 0); 61 | connect_timeout_ = timeout; 62 | } 63 | 64 | inline int GetConnectTimeout() const 65 | { 66 | return connect_timeout_; 67 | } 68 | 69 | inline size_t GetSize() const 70 | { 71 | return size_; 72 | } 73 | 74 | inline const char* GetData() const 75 | { 76 | return data_; 77 | } 78 | 79 | inline void SetData(const char* data, size_t size) 80 | { 81 | assert(nullptr != data); 82 | assert(size > 0); 83 | data_ = data; 84 | size_ = size; 85 | } 86 | 87 | inline void SetUrl(const std::string& url) 88 | { 89 | assert(!url.empty()); 90 | url_ = url; 91 | } 92 | 93 | inline void SetUrl(std::string&& url) 94 | { 95 | assert(!url.empty()); 96 | url_ = std::move(url); 97 | } 98 | 99 | const char* GetUrl() const 100 | { 101 | return url_.data(); 102 | } 103 | 104 | inline const std::map& GetHeaders() const 105 | { 106 | return headers_; 107 | } 108 | 109 | inline void AddHeader(const std::string& name, const std::string& value) 110 | { 111 | assert(!name.empty() || !value.empty()); 112 | std::map::iterator it = headers_.find(name); 113 | if (it != headers_.end()) { 114 | it->second = value; 115 | } 116 | else { 117 | headers_.insert(std::move(std::make_pair(name, value))); 118 | } 119 | } 120 | 121 | inline void AddHeader(std::string&& name, std::string&& value) 122 | { 123 | assert(!name.empty() || !value.empty()); 124 | std::map::iterator it = headers_.find(name); 125 | if (it != headers_.end()) { 126 | it->second = std::move(value); 127 | } 128 | else { 129 | headers_.insert(std::move(std::make_pair(std::move(name), std::move(value)))); 130 | } 131 | } 132 | 133 | void AddHeader(const std::map& headers) 134 | { 135 | for (auto &it : headers) { 136 | AddHeader(it.first, it.second); 137 | } 138 | } 139 | 140 | private: 141 | size_t size_; 142 | int read_timeout_; 143 | int connect_timeout_; 144 | const char* data_; 145 | std::string url_; 146 | std::map headers_; 147 | }; 148 | } // namespace swift 149 | #endif //__SWIFT_NET_HTTP_CLIENT_REQUEST_HPP__ 150 | -------------------------------------------------------------------------------- /swift/net/httpclient/response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #ifndef __SWIFT_NET_HTTP_CLIENT_RESPONSE_HPP__ 16 | #define __SWIFT_NET_HTTP_CLIENT_RESPONSE_HPP__ 17 | 18 | #include 19 | #include 20 | 21 | #include "swift/base/noncopyable.hpp" 22 | #include "swift/base/stringutil.h" 23 | 24 | namespace swift { 25 | 26 | class Response : swift::noncopyable { 27 | public: 28 | Response() : status_code_(0), body_(), headers_() 29 | { 30 | } 31 | 32 | ~Response() 33 | { 34 | Reset(); 35 | } 36 | 37 | Response(Response&&) = default; 38 | Response(const Response&) = default; 39 | Response& operator=(const Response&) = default; 40 | Response& operator=(Response&&) = default; 41 | 42 | inline int GetStatusCode() const 43 | { 44 | return status_code_; 45 | } 46 | 47 | inline void SetStatusCode(int status_code) 48 | { 49 | status_code_ = status_code; 50 | } 51 | 52 | inline const std::map& GetHeaders() const 53 | { 54 | return headers_; 55 | } 56 | 57 | inline std::map&& GetHeaders() 58 | { 59 | return std::move(headers_); 60 | } 61 | 62 | inline void AddHeader(const std::string& name, const std::string& value) 63 | { 64 | std::map::iterator it = headers_.find(name); 65 | if (it != headers_.end()) { 66 | it->second = value; 67 | } 68 | else { 69 | headers_.insert(std::move(std::make_pair(name, value))); 70 | } 71 | } 72 | 73 | inline void AddHeader(std::string&& name, std::string&& value) 74 | { 75 | assert(!name.empty() || !value.empty()); 76 | std::map::iterator it = headers_.find(name); 77 | if (it != headers_.end()) { 78 | it->second = std::move(value); 79 | } 80 | else { 81 | headers_.insert(std::move(std::make_pair(std::move(name), std::move(value)))); 82 | } 83 | } 84 | 85 | inline const std::string& GetBody() const 86 | { 87 | return body_; 88 | } 89 | 90 | inline std::string&& GetBody() 91 | { 92 | return std::move(body_); 93 | } 94 | 95 | inline void SetBody(const char* data, const size_t size) 96 | { 97 | body_.append(data, size); 98 | } 99 | 100 | inline void Reset() 101 | { 102 | status_code_ = 0; 103 | headers_.clear(); 104 | body_.clear(); 105 | } 106 | 107 | inline size_t ContentLength() const 108 | { 109 | if (!headers_.empty()) { 110 | auto it = headers_.find("Content-Length"); 111 | if (it != headers_.end()) { 112 | return swift::StringUtil::FromString(it->second.c_str()); 113 | } 114 | } 115 | 116 | return 0; 117 | } 118 | 119 | private: 120 | int status_code_; 121 | std::string body_; 122 | std::map headers_; 123 | 124 | }; // Response 125 | } // namespace swift 126 | 127 | #endif //__SWIFT_NET_HTTP_CLIENT_RESPONSE_HPP__ 128 | -------------------------------------------------------------------------------- /test/base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME swift_base_test) 5 | 6 | aux_source_directory (. SRCS) 7 | add_executable (${TARGET_NAME} ${SRCS}) 8 | add_definitions ("-std=c++0x -Wno-deprecated -D_GLIBCXX_USE_NANOSLEEP") 9 | target_link_libraries (${TARGET_NAME} swift_base gtest pthread crypto glog gflags) -------------------------------------------------------------------------------- /test/base/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main (int argc, char* argv[]) 5 | { 6 | testing::InitGoogleTest (&argc, argv); 7 | swift::StackTrace::InitStackTraceHandler (); 8 | 9 | return RUN_ALL_TESTS (); 10 | } -------------------------------------------------------------------------------- /test/base/test_blockingqueue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class test_BlockingQueue : public testing::Test 11 | { 12 | public: 13 | test_BlockingQueue () {} 14 | ~test_BlockingQueue () {} 15 | 16 | virtual void SetUp (void) 17 | { 18 | 19 | } 20 | 21 | virtual void TearDown (void) 22 | { 23 | 24 | } 25 | }; 26 | 27 | TEST_F (test_BlockingQueue, Integer) 28 | { 29 | swift::BlockingQueue q; 30 | auto t1 = std::async (std::launch::async, [&q] () { 31 | for (int i = 0; i < 10; ++i) { 32 | q.Put (i); 33 | } 34 | }); 35 | 36 | auto t2 = std::async (std::launch::async, [&q] () { 37 | while (q.Size ()) { 38 | ASSERT_TRUE (q.Take () < 10); 39 | } 40 | }); 41 | 42 | auto t3 = std::async (std::launch::async, [&q] () { 43 | while (q.Size ()) { 44 | ASSERT_TRUE (q.Take () < 10); 45 | } 46 | }); 47 | 48 | t1.wait (); 49 | t2.wait (); 50 | t3.wait (); 51 | } 52 | 53 | class Data 54 | { 55 | public: 56 | Data (const char* data) : length_ (0) 57 | { 58 | if (nullptr != data) { 59 | length_ = strlen (data); 60 | data_.reset (length_ > 0 ? new char[length_ + 1] : nullptr); 61 | if (data_) { 62 | std::copy (data, data + length_, data_.get ()); 63 | data_.get ()[length_] = '\0'; 64 | } 65 | } 66 | } 67 | 68 | ~Data () 69 | { 70 | data_.reset (); 71 | length_ = 0; 72 | } 73 | 74 | Data (const Data& rhs) 75 | { 76 | if (this != &rhs) { 77 | length_ = rhs.length_; 78 | data_.reset (length_ > 0 ? new char[length_ + 1] : nullptr); 79 | if (data_) { 80 | const char* source = rhs.data_.get (); 81 | std::copy (source, source + length_, data_.get ()); 82 | data_.get ()[length_] = '\0'; 83 | } 84 | } 85 | } 86 | 87 | Data (Data&& rhs) 88 | { 89 | if (this != &rhs) { 90 | length_ = rhs.length_; 91 | if (length_) { 92 | data_ = std::move (rhs.data_); 93 | rhs.data_ = nullptr; 94 | rhs.length_ = 0; 95 | } 96 | } 97 | } 98 | 99 | Data& operator= (const Data& rhs) 100 | { 101 | if (this != &rhs) { 102 | if (length_ != rhs.length_) { 103 | length_ = rhs.length_; 104 | data_.reset (length_ > 0 ? new char[length_ + 1] : nullptr); 105 | } 106 | 107 | if (data_) { 108 | const char* source = rhs.data_.get (); 109 | std::copy (source, source + length_, data_.get ()); 110 | data_.get ()[length_] = '\0'; 111 | } 112 | } 113 | 114 | return *this; 115 | } 116 | 117 | Data& operator= (Data&& rhs) 118 | { 119 | if (this != &rhs) { 120 | length_ = rhs.length_; 121 | data_ = std::move (rhs.data_); 122 | rhs.data_ = nullptr; 123 | rhs.length_ = 0; 124 | } 125 | 126 | return *this; 127 | } 128 | 129 | bool operator== (const Data& rhs) const 130 | { 131 | if (length_ != rhs.length_) { 132 | return false; 133 | } 134 | 135 | return 0 == memcmp (data_.get (), rhs.data_.get (), length_); 136 | } 137 | 138 | const char* GetData () const 139 | { 140 | return data_.get (); 141 | } 142 | 143 | size_t GetSize () const 144 | { 145 | return length_; 146 | } 147 | 148 | private: 149 | int length_; 150 | std::unique_ptr data_; 151 | }; 152 | 153 | TEST_F (test_BlockingQueue, Structure) 154 | { 155 | Data a ("xxxxx"); 156 | Data d ("abcde"); 157 | d = a; 158 | 159 | Data c = a; 160 | c = d; 161 | 162 | swift::BlockingQueue q; 163 | q.Put (d); 164 | ASSERT_EQ (q.Size (), 1); 165 | ASSERT_EQ (q.IsEmpty (), false); 166 | q.Clear (); 167 | ASSERT_EQ (q.IsEmpty (), true); 168 | q.Put (d); 169 | q.Put (std::move (a)); 170 | Data r = q.Take (); 171 | ASSERT_EQ (q.Size (), 1); 172 | 173 | ASSERT_TRUE (d == r); 174 | ASSERT_TRUE (c == r); 175 | ASSERT_TRUE (memcmp (r.GetData (), "xxxxx", r.GetSize ()) == 0); 176 | 177 | r = q.Take (); 178 | ASSERT_EQ (a.GetData (), nullptr); 179 | ASSERT_EQ (a.GetSize (), 0); 180 | ASSERT_EQ (strlen (r.GetData ()), r.GetSize ()); 181 | } 182 | -------------------------------------------------------------------------------- /test/base/test_byteorderhelper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | class test_ByteOrderHelper : public testing::Test 6 | { 7 | public: 8 | test_ByteOrderHelper () {} 9 | ~test_ByteOrderHelper () {} 10 | 11 | virtual void SetUp (void) 12 | { 13 | 14 | } 15 | 16 | virtual void TearDown (void) 17 | { 18 | 19 | } 20 | }; 21 | 22 | TEST_F (test_ByteOrderHelper, Set) 23 | { 24 | uint8_t buf[8] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }; 25 | swift::ByteOrderHelper::Set8 (buf, 0, 0xfb); 26 | swift::ByteOrderHelper::Set8 (buf, 1, 0x12); 27 | EXPECT_EQ (0xfb, buf[0]); 28 | EXPECT_EQ (0x12, buf[1]); 29 | swift::ByteOrderHelper::SetBigEndian16 (buf, 0x1234); 30 | EXPECT_EQ (0x12, buf[0]); 31 | EXPECT_EQ (0x34, buf[1]); 32 | swift::ByteOrderHelper::SetLittleEndian16 (buf, 0x1234); 33 | EXPECT_EQ (0x34, buf[0]); 34 | EXPECT_EQ (0x12, buf[1]); 35 | swift::ByteOrderHelper::SetBigEndian32 (buf, 0x12345678); 36 | EXPECT_EQ (0x12, buf[0]); 37 | EXPECT_EQ (0x34, buf[1]); 38 | EXPECT_EQ (0x56, buf[2]); 39 | EXPECT_EQ (0x78, buf[3]); 40 | swift::ByteOrderHelper::SetLittleEndian32 (buf, 0x12345678); 41 | EXPECT_EQ (0x78, buf[0]); 42 | EXPECT_EQ (0x56, buf[1]); 43 | EXPECT_EQ (0x34, buf[2]); 44 | EXPECT_EQ (0x12, buf[3]); 45 | swift::ByteOrderHelper::SetBigEndian64 (buf, 0x0123456789abcdefULL); 46 | EXPECT_EQ (0x01, buf[0]); 47 | EXPECT_EQ (0x23, buf[1]); 48 | EXPECT_EQ (0x45, buf[2]); 49 | EXPECT_EQ (0x67, buf[3]); 50 | EXPECT_EQ (0x89, buf[4]); 51 | EXPECT_EQ (0xab, buf[5]); 52 | EXPECT_EQ (0xcd, buf[6]); 53 | EXPECT_EQ (0xef, buf[7]); 54 | swift::ByteOrderHelper::SetLittleEndian64 (buf, 0x0123456789abcdefULL); 55 | EXPECT_EQ (0xef, buf[0]); 56 | EXPECT_EQ (0xcd, buf[1]); 57 | EXPECT_EQ (0xab, buf[2]); 58 | EXPECT_EQ (0x89, buf[3]); 59 | EXPECT_EQ (0x67, buf[4]); 60 | EXPECT_EQ (0x45, buf[5]); 61 | EXPECT_EQ (0x23, buf[6]); 62 | EXPECT_EQ (0x01, buf[7]); 63 | } 64 | 65 | TEST_F (test_ByteOrderHelper, Get) { 66 | uint8_t buf[8]; 67 | buf[0] = 0x01u; 68 | buf[1] = 0x23u; 69 | buf[2] = 0x45u; 70 | buf[3] = 0x67u; 71 | buf[4] = 0x89u; 72 | buf[5] = 0xabu; 73 | buf[6] = 0xcdu; 74 | buf[7] = 0xefu; 75 | EXPECT_EQ (0x01u, swift::ByteOrderHelper::Get8 (buf, 0)); 76 | EXPECT_EQ (0x23u, swift::ByteOrderHelper::Get8 (buf, 1)); 77 | EXPECT_EQ (0x0123u, swift::ByteOrderHelper::GetBigEndian16 (buf)); 78 | EXPECT_EQ (0x2301u, swift::ByteOrderHelper::GetLittleEndian16 (buf)); 79 | EXPECT_EQ (0x01234567u, swift::ByteOrderHelper::GetBigEndian32 (buf)); 80 | EXPECT_EQ (0x67452301u, swift::ByteOrderHelper::GetLittleEndian32 (buf)); 81 | EXPECT_EQ (0x0123456789abcdefULL, swift::ByteOrderHelper::GetBigEndian64 (buf)); 82 | EXPECT_EQ (0xefcdab8967452301ULL, swift::ByteOrderHelper::GetLittleEndian64 (buf)); 83 | } 84 | 85 | TEST_F (test_ByteOrderHelper, NetworkAndHost) { 86 | uint16_t v16 = 1; 87 | uint32_t v32 = 1; 88 | uint64_t v64 = 1; 89 | 90 | EXPECT_EQ (v16, swift::ByteOrderHelper::NetworkToHost16 (swift::ByteOrderHelper::HostToNetwork16 (v16))); 91 | EXPECT_EQ (v32, swift::ByteOrderHelper::NetworkToHost32 (swift::ByteOrderHelper::HostToNetwork32 (v32))); 92 | EXPECT_EQ (v64, swift::ByteOrderHelper::NetworkToHost64 (swift::ByteOrderHelper::HostToNetwork64 (v64))); 93 | 94 | if (swift::ByteOrderHelper::IsBigEndianHost ()) { 95 | // The host is the network (big) endian. 96 | EXPECT_EQ (v16, swift::ByteOrderHelper::HostToNetwork16 (v16)); 97 | EXPECT_EQ (v32, swift::ByteOrderHelper::HostToNetwork32 (v32)); 98 | EXPECT_EQ (v64, swift::ByteOrderHelper::HostToNetwork64 (v64)); 99 | 100 | // GetBigEndian converts big endian to little endian here. 101 | EXPECT_EQ (v16 >> 8, swift::ByteOrderHelper::GetBigEndian16 (&v16)); 102 | EXPECT_EQ (v32 >> 24, swift::ByteOrderHelper::GetBigEndian32 (&v32)); 103 | EXPECT_EQ (v64 >> 56, swift::ByteOrderHelper::GetBigEndian64 (&v64)); 104 | } 105 | else { 106 | // The host is little endian. 107 | EXPECT_NE (v16, swift::ByteOrderHelper::HostToNetwork16 (v16)); 108 | EXPECT_NE (v32, swift::ByteOrderHelper::HostToNetwork32 (v32)); 109 | EXPECT_NE (v64, swift::ByteOrderHelper::HostToNetwork64 (v64)); 110 | 111 | // GetBigEndian converts little endian to big endian here. 112 | EXPECT_EQ (swift::ByteOrderHelper::GetBigEndian16 (&v16), swift::ByteOrderHelper::HostToNetwork16 (v16)); 113 | EXPECT_EQ (swift::ByteOrderHelper::GetBigEndian32 (&v32), swift::ByteOrderHelper::HostToNetwork32 (v32)); 114 | EXPECT_EQ (swift::ByteOrderHelper::GetBigEndian64 (&v64), swift::ByteOrderHelper::HostToNetwork64 (v64)); 115 | 116 | // GetBigEndian converts little endian to big endian here. 117 | EXPECT_EQ (v16 << 8, swift::ByteOrderHelper::GetBigEndian16 (&v16)); 118 | EXPECT_EQ (v32 << 24, swift::ByteOrderHelper::GetBigEndian32 (&v32)); 119 | EXPECT_EQ (v64 << 56, swift::ByteOrderHelper::GetBigEndian64 (&v64)); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /test/base/test_crc32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | class test_Crc32 : public testing::Test 8 | { 9 | public: 10 | test_Crc32 () {} 11 | ~test_Crc32 () {} 12 | }; 13 | 14 | TEST_F (test_Crc32, All) 15 | { 16 | uint32_t n = swift::Crc32::ComputeCrc32 ("", 0); 17 | EXPECT_EQ (0, n); 18 | 19 | swift::StringPiece input ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); 20 | uint32_t c = 0; 21 | for (size_t i = 0; i < input.size (); ++i) { 22 | char cc = input[i]; 23 | c = swift::Crc32::UpdateCrc32 (c, &cc, 1); 24 | } 25 | EXPECT_EQ (0x171A3F5FU, c); 26 | 27 | std::string s ("123"); 28 | n = swift::Crc32::ComputeCrc32 (s.data (), s.length ()); 29 | EXPECT_EQ (0x884863D2, n); 30 | 31 | EXPECT_EQ(swift::Crc32::ComputeCrc32 ("ccc", 3), 32 | swift::Crc32::UpdateCrc32 (swift::Crc32::ComputeCrc32 ("c", 1), "cc", 2)); 33 | } -------------------------------------------------------------------------------- /test/base/test_date.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class test_Date : public testing::Test 8 | { 9 | public: 10 | test_Date () {} 11 | ~test_Date () {} 12 | 13 | virtual void SetUp (void) 14 | { 15 | 16 | } 17 | 18 | virtual void TearDown (void) 19 | { 20 | 21 | } 22 | }; 23 | 24 | TEST_F (test_Date, All) 25 | { 26 | swift::Date date; 27 | ASSERT_FALSE (date.Valid ()); 28 | 29 | swift::Date::YearMonthDay ymd; 30 | ymd.year = 2014; 31 | ymd.month = 4; 32 | ymd.day = 25; 33 | 34 | swift::Date dt (ymd.year, ymd.month, ymd.day); 35 | date.Swap (dt); 36 | ASSERT_TRUE (date.Valid ()); 37 | ASSERT_FALSE (dt.Valid ()); 38 | 39 | ASSERT_TRUE (2014 == date.Year ()); 40 | ASSERT_TRUE (4 == date.Month ()); 41 | ASSERT_TRUE (25 == date.Day ()); 42 | // Friday == 5 43 | ASSERT_TRUE (5 == date.WeekDay ()); 44 | ASSERT_TRUE (date.ToString () == "2014-04-25"); 45 | 46 | struct tm stm; 47 | time_t tt = time (nullptr); 48 | ::gmtime_r (&tt, &stm); 49 | dt = swift::Date (stm); 50 | dt = swift::Date (2014, 5, 26); 51 | ASSERT_TRUE (dt.Year () == date.Year ()); 52 | ASSERT_TRUE (dt.Month () > date.Month ()); 53 | ASSERT_TRUE (dt.Day () > date.Day ()); 54 | ASSERT_TRUE (dt != date); 55 | ASSERT_TRUE (swift::Date (2014, 4, 24) < date); 56 | swift::Date::YearMonthDay ymd_tmp = dt.GetYearMonthDay (); 57 | ASSERT_TRUE (ymd_tmp.year == ymd.year); 58 | ASSERT_TRUE (ymd_tmp.month != ymd.month); 59 | ASSERT_TRUE (ymd_tmp.day != ymd.day); 60 | 61 | swift::Date dtt (date.GetJulianDayNumber ()); 62 | ASSERT_TRUE (dtt == date); 63 | ASSERT_TRUE (dtt.Year () == date.Year ()); 64 | ASSERT_TRUE (dtt.Month () == date.Month ()); 65 | ASSERT_TRUE (dtt.Day () == date.Day ()); 66 | } -------------------------------------------------------------------------------- /test/base/test_exception.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class test_Exception : public testing::Test 8 | { 9 | public: 10 | test_Exception () {} 11 | ~test_Exception () {} 12 | 13 | virtual void SetUp (void) 14 | { 15 | 16 | } 17 | 18 | virtual void TearDown (void) 19 | { 20 | 21 | } 22 | }; 23 | 24 | #define STR_MSG "g_test_msg" 25 | static std::string g_test_msg = STR_MSG; 26 | 27 | class TestCase 28 | { 29 | public: 30 | void TestThrowNewException () 31 | { 32 | throw new swift::Exception (std::move (g_test_msg)); 33 | } 34 | }; 35 | 36 | void TestFunc (int n) 37 | { 38 | TestCase tc; 39 | try { 40 | tc.TestThrowNewException (); 41 | } 42 | catch (std::exception* e) { 43 | ASSERT_TRUE (STR_MSG == std::string (e->what ())); 44 | ASSERT_TRUE (g_test_msg.empty ()); 45 | ASSERT_TRUE (!std::string ((dynamic_cast(e))->GetStackTrace ()).empty ()); 46 | std::cout << (dynamic_cast(e))->GetStackTrace () << std::endl; 47 | 48 | swift::StackTrace::PrintStack (0); 49 | 50 | delete e; 51 | } 52 | } 53 | 54 | TEST_F (test_Exception, All) 55 | { 56 | { 57 | swift::Exception ex (""); 58 | ASSERT_TRUE (true == std::string (ex.what ()).empty ()); 59 | ASSERT_TRUE (true == ex.Messge ().empty ()); 60 | ASSERT_TRUE (false == std::string (ex.GetStackTrace ()).empty ()); 61 | 62 | swift::Exception e (nullptr); 63 | ASSERT_TRUE (true == std::string (e.what ()).empty ()); 64 | ASSERT_TRUE (true == e.Messge ().empty ()); 65 | ASSERT_TRUE (false == std::string (e.GetStackTrace ()).empty ()); 66 | } 67 | 68 | { 69 | swift::Exception ex ("abc"); 70 | ASSERT_TRUE ("abc" == std::string (ex.what ())); 71 | ASSERT_TRUE (false == std::string (ex.GetStackTrace ()).empty ()); 72 | swift::Exception tmp = ex; 73 | ASSERT_TRUE ("abc" == std::string (tmp.what ())); 74 | } 75 | 76 | { 77 | std::string msg = "abc"; 78 | swift::Exception ex (msg); 79 | ASSERT_TRUE (msg == std::string (ex.what ())); 80 | } 81 | 82 | TestFunc (5); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /test/base/test_guid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class test_Guid : public testing::Test 10 | { 11 | public: 12 | test_Guid(); 13 | ~test_Guid(); 14 | }; 15 | 16 | TEST(test_Guid, Zeroes) 17 | { 18 | uint64_t bytes[] = { 0, 0 }; 19 | std::string guid; 20 | EXPECT_TRUE(swift::Guid::RandomDataToGuidString(bytes, guid)); 21 | EXPECT_EQ(guid, "00000000-0000-0000-0000-000000000000"); 22 | } 23 | 24 | TEST(test_Guid, Correctly) 25 | { 26 | uint64_t bytes[] = { 0x0123456789ABCDEFULL, 0xFEDCBA9876543210ULL }; 27 | std::string guid; 28 | EXPECT_TRUE(swift::Guid::RandomDataToGuidString(bytes, guid)); 29 | EXPECT_EQ(guid, "01234567-89AB-CDEF-FEDC-BA9876543210"); 30 | 31 | for (int i = 0; i < 100; ++i) { 32 | std::move(swift::Guid::Generate(guid)); 33 | EXPECT_TRUE(swift::Guid::IsValid(guid)); 34 | } 35 | } 36 | 37 | TEST(test_Guid, Uniqueness) 38 | { 39 | std::string guid1; 40 | std::string guid2; 41 | for (int i = 0; i < 100; ++i) { 42 | swift::Guid::Generate(guid1); 43 | swift::Guid::Generate(guid2); 44 | EXPECT_NE(guid1, guid2); 45 | EXPECT_EQ(guid1.size(), 36); 46 | EXPECT_EQ(guid2.size(), 36); 47 | } 48 | 49 | std::mutex mu; 50 | std::set ss; 51 | std::vector ths; 52 | for (int i = 0; i < 4; ++i) { 53 | ths.push_back(std::move(std::thread([&mu, &ss]{ 54 | std::string guid; 55 | for (int i = 0; i < 10000; ++i) { 56 | EXPECT_TRUE(swift::Guid::Generate(guid)); 57 | EXPECT_TRUE(swift::Guid::IsValid(guid)); 58 | mu.lock(); 59 | auto ret = ss.insert(std::move(guid)); 60 | mu.unlock(); 61 | EXPECT_NE(ret.second, false); 62 | } 63 | }))); 64 | } 65 | 66 | for (auto&& i : ths) { 67 | i.join(); 68 | } 69 | } 70 | 71 | TEST(test_Guid, Others) 72 | { 73 | swift::Guid guid; 74 | EXPECT_TRUE(guid.IsValid()); 75 | std::string s = guid.ToString(); 76 | EXPECT_TRUE(false == s.empty()); 77 | EXPECT_EQ(s.size(), 36); 78 | 79 | swift::Guid str_guid (s); 80 | EXPECT_TRUE(str_guid.IsValid()); 81 | EXPECT_EQ(s, str_guid.ToString()); 82 | 83 | s = "01234567-89AB-CDEF-FEDC-BA"; 84 | swift::Guid g(s); 85 | EXPECT_FALSE(g.IsValid()); 86 | 87 | s = "01234567-89AB-CDEF-HEDC-BA9876543210"; 88 | swift::Guid gg(s); 89 | EXPECT_FALSE(gg.IsValid()); 90 | 91 | s = "00000000-0000-0000-HEDC-BA9876543210"; 92 | swift::Guid ggg(s); 93 | EXPECT_FALSE(ggg.IsValid()); 94 | 95 | swift::Guid gggg = guid; 96 | EXPECT_EQ(gggg, guid); 97 | } 98 | -------------------------------------------------------------------------------- /test/base/test_linkedhashmap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | class test_LinkedHashMap : public testing::Test 7 | { 8 | public: 9 | test_LinkedHashMap () {} 10 | ~test_LinkedHashMap () {} 11 | 12 | virtual void SetUp (void) 13 | { 14 | 15 | } 16 | 17 | virtual void TearDown (void) 18 | { 19 | 20 | } 21 | }; 22 | 23 | TEST_F (test_LinkedHashMap, All) 24 | { 25 | swift::LinkedHashMap lhm; 26 | 27 | ASSERT_TRUE (0 == lhm.Count ()); 28 | lhm.Set (100, 100, swift::LinkedHashMap::MM_FIRST); 29 | lhm.Set (101, 100, swift::LinkedHashMap::MM_FIRST); 30 | lhm.Set (102, 100, swift::LinkedHashMap::MM_FIRST); 31 | lhm.Set (103, 100, swift::LinkedHashMap::MM_FIRST); 32 | ASSERT_TRUE (100 == *lhm.Get (100, swift::LinkedHashMap::MM_LAST)); 33 | ASSERT_TRUE (100 == lhm.LastKey ()); 34 | ASSERT_TRUE (100 == lhm.LastValue ()); 35 | int count = 0; 36 | for (auto it = lhm.Begin (); it != lhm.End (); ++it) { 37 | ++count; 38 | } 39 | ASSERT_TRUE (4 == count); 40 | 41 | auto it = lhm.Find (102); 42 | ASSERT_TRUE (102 == it.Key ()); 43 | ASSERT_TRUE (100 == it.Value ()); 44 | 45 | ASSERT_TRUE (lhm.Remove (102)); 46 | ASSERT_FALSE (lhm.Remove (102)); 47 | ASSERT_TRUE (nullptr == lhm.Get (102, swift::LinkedHashMap::MM_LAST)); 48 | 49 | swift::LinkedHashMap bigMap (32768); 50 | bigMap.Set (100, 100, swift::LinkedHashMap::MM_FIRST); 51 | bigMap.Set (101, 100, swift::LinkedHashMap::MM_FIRST); 52 | bigMap.Set (102, 100, swift::LinkedHashMap::MM_FIRST); 53 | bigMap.Set (103, 100, swift::LinkedHashMap::MM_FIRST); 54 | 55 | bigMap.Get (100, swift::LinkedHashMap::MM_FIRST); 56 | ASSERT_TRUE (100 == bigMap.FirstKey ()); 57 | ASSERT_TRUE (100 == bigMap.FirstValue ()); 58 | ASSERT_TRUE (100 == *bigMap.Get (100, swift::LinkedHashMap::MM_LAST)); 59 | ASSERT_TRUE (100 == bigMap.LastKey ()); 60 | ASSERT_TRUE (100 == bigMap.LastValue ()); 61 | 62 | ASSERT_TRUE (100 == *bigMap.Get (100, swift::LinkedHashMap::MM_CURRENT)); 63 | ASSERT_TRUE (100 == bigMap.LastKey ()); 64 | ASSERT_TRUE (100 == bigMap.LastValue ()); 65 | } 66 | 67 | -------------------------------------------------------------------------------- /test/base/test_logfile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class test_LogFile : public testing::Test 11 | { 12 | public: 13 | test_LogFile () {} 14 | ~test_LogFile () {} 15 | 16 | virtual void SetUp (void) 17 | { 18 | 19 | } 20 | 21 | virtual void TearDown (void) 22 | { 23 | 24 | } 25 | }; 26 | 27 | void DebugFunc (const std::string& line) 28 | { 29 | for (int i = 0; i < 6000; ++i) { 30 | LOG_DEBUG << line << i; 31 | } 32 | } 33 | 34 | void TraceFunc (const std::string& line) 35 | { 36 | for (int i = 0; i < 10000; ++i) { 37 | LOG_TRACE << line << i; 38 | } 39 | } 40 | 41 | TEST_F (test_LogFile, All) 42 | { 43 | std::unique_ptr log_file; 44 | 45 | std::string log_path = "~/test_swift_log_file"; 46 | log_file.reset (new swift::LogFile (::basename (log_path.c_str ()), 200 * 1000)); 47 | swift::Logger::SetOutput (std::move ([&log_file] (const char* msg, int len) { 48 | log_file->Append (msg, len); 49 | })); 50 | 51 | swift::Logger::SetFlush (std::move ([&log_file] () { 52 | log_file->Flush (); 53 | })); 54 | 55 | swift::Logger::SetLogSeverity (swift::Logger::LS_TRACE); 56 | swift::TimeZone tz ("/usr/share/zoneinfo/Asia/Shanghai"); 57 | swift::Logger::SetTimeZone (tz); 58 | 59 | std::string line = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ "; 60 | 61 | std::cout << "Main process id = " << getpid () << std::endl; 62 | std::vector thread_pool; 63 | thread_pool.push_back (std::thread ([&line] () { 64 | std::cout << "LOG_INFO thread id = " << swift::thisthread::GetTid () << std::endl; 65 | for (int i = 0; i < 2000; ++i) { 66 | LOG_INFO << line << i; 67 | usleep (100); 68 | } 69 | })); 70 | 71 | thread_pool.push_back (std::thread ([&line] () { 72 | std::cout << "LOG_DEBUG thread id = " << swift::thisthread::GetTid () << std::endl; 73 | DebugFunc (line); 74 | })); 75 | 76 | thread_pool.push_back (std::thread ([&line] () { 77 | std::cout << "LOG_ERROR thread id = " << swift::thisthread::GetTid () << std::endl; 78 | for (int i = 0; i < 5000; ++i) { 79 | LOG_ERROR << line << i; 80 | usleep (100); 81 | } 82 | })); 83 | 84 | thread_pool.push_back (std::thread ([&line] () { 85 | std::cout << "LOG_TRACE thread id = " << swift::thisthread::GetTid () << std::endl; 86 | TraceFunc (line); 87 | })); 88 | 89 | thread_pool.push_back (std::thread ([&line] () { 90 | std::cout << "LOG_WARN thread id = " << swift::thisthread::GetTid () << std::endl; 91 | for (int i = 0; i < 4000; ++i) { 92 | LOG_WARN << line << i; 93 | usleep (100); 94 | } 95 | })); 96 | 97 | for (auto &it : thread_pool) { 98 | if (it.joinable ()) { 99 | it.join (); 100 | } 101 | } 102 | 103 | const char *cmd = "rm -rf test_swift_log_file*"; 104 | system (cmd); 105 | } -------------------------------------------------------------------------------- /test/base/test_logging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class test_Logging : public testing::Test 11 | { 12 | public: 13 | test_Logging () {} 14 | ~test_Logging () {} 15 | 16 | virtual void SetUp (void) 17 | { 18 | 19 | } 20 | 21 | virtual void TearDown (void) 22 | { 23 | 24 | } 25 | }; 26 | 27 | std::atomic g_total_write_size; 28 | FILE* g_file_descriptor = nullptr; 29 | std::unique_ptr g_log_file; 30 | 31 | void LogBench (const char* buf, bool is_write_long_string = false) 32 | { 33 | swift::Logger::SetOutput (std::move ([&] (const char* msg, int length) { 34 | g_total_write_size += length; 35 | if (g_file_descriptor) { 36 | fwrite (msg, 1, length, g_file_descriptor); 37 | } 38 | else if (g_log_file.get ()) { 39 | g_log_file->Append (msg, length); 40 | } 41 | })); 42 | 43 | swift::Timestamp start (swift::Timestamp::Now ()); 44 | g_total_write_size = 0; 45 | 46 | int n = 1000 * 2000; 47 | std::string empty = " "; 48 | std::string long_str (3000, 'Y'); 49 | long_str += " "; 50 | for (int i = 0; i < n; ++i) { 51 | LOG_INFO << "ABCDEFGHIJKLMNOPQRSTUVWXZ" 52 | << (is_write_long_string ? long_str : empty) 53 | << i; 54 | } 55 | 56 | swift::Timestamp end (swift::Timestamp::Now ()); 57 | double seconds = swift::TimeDifference (end, start); 58 | printf ("%12s: %f seconds, %" PRIu64" bytes, %10.2f msg/s, %.2f MiB/s\n", 59 | buf, seconds, g_total_write_size.load (), 60 | static_cast(n / seconds), 61 | static_cast(g_total_write_size / seconds / (1024 * 1024))); 62 | g_total_write_size = 0; 63 | } 64 | 65 | TEST_F (test_Logging, All) 66 | { 67 | LogBench ("nop", true); 68 | 69 | char buffer[1024 * 64] = {'\0'}; 70 | g_file_descriptor = fopen ("/dev/null", "w"); 71 | setbuffer (g_file_descriptor, buffer, sizeof(buffer)); 72 | LogBench ("/dev/null", true); 73 | fclose (g_file_descriptor); 74 | g_file_descriptor = nullptr; 75 | 76 | g_file_descriptor = fopen ("/tmp/log", "w"); 77 | setbuffer (g_file_descriptor, buffer, sizeof(buffer)); 78 | LogBench ("/tmp/log"); 79 | fclose (g_file_descriptor); 80 | g_file_descriptor = nullptr; 81 | 82 | g_log_file.reset (new swift::LogFile ("test_log_st", 500 * 1000 * 1000, false)); 83 | LogBench ("test_log_st"); 84 | 85 | g_log_file.reset (new swift::LogFile ("test_log_mt", 1000 * 1000 * 1000, true)); 86 | auto f1 = std::thread ([] () {LogBench ("test_log_mt_th1");}); 87 | auto f2 = std::thread ([] () {LogBench ("test_log_mt_th2");}); 88 | LogBench ("test_log_mt"); 89 | f1.join (); 90 | f2.join (); 91 | g_log_file.reset (); 92 | 93 | system ("rm -rf test_log_*"); 94 | 95 | g_file_descriptor = stdout; 96 | sleep (1); 97 | swift::TimeZone beijing (8 * 3600, "CST"); 98 | swift::Logger::SetTimeZone (beijing); 99 | LOG_TRACE << "trace CST"; 100 | LOG_DEBUG << "debug CST"; 101 | LOG_INFO << "Hello CST"; 102 | LOG_WARN << "World CST"; 103 | LOG_ERROR << "Error CST"; 104 | 105 | sleep (1); 106 | swift::TimeZone newyork ("/usr/share/zoneinfo/America/New_York"); 107 | swift::Logger::SetTimeZone (newyork); 108 | LOG_TRACE << "trace NYT"; 109 | LOG_DEBUG << "debug NYT"; 110 | LOG_INFO << "Hello NYT"; 111 | LOG_WARN << "World NYT"; 112 | LOG_ERROR << "Error NYT"; 113 | g_file_descriptor = nullptr; 114 | } -------------------------------------------------------------------------------- /test/base/test_lru_cache.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class test_LruCache : public testing::Test 8 | { 9 | public: 10 | test_LruCache() {} 11 | ~test_LruCache() {} 12 | }; 13 | 14 | TEST_F(test_LruCache, All) 15 | { 16 | // 17 | // base case: 18 | // 19 | swift::LruCache lru_cache(3); 20 | lru_cache.Set(1, 1); 21 | lru_cache.Set(2, 2); 22 | lru_cache.Set(3, 3); 23 | 24 | // order: 3, 2, 1 25 | 26 | size_t value = 0; 27 | lru_cache.Get(1, value); 28 | EXPECT_EQ(value, 1); 29 | 30 | // order 1, 3, 2 erase 2 31 | lru_cache.Set(4, 4); 32 | ASSERT_FALSE(lru_cache.Get(2, value)); 33 | 34 | // benchmark 35 | swift::LruCache lru_cache_bench(2000); 36 | 37 | size_t thread_num = 4; 38 | size_t run_times = 1000; 39 | 40 | timeval t1, t2; 41 | gettimeofday(&t1, NULL); 42 | 43 | std::vector thread_pool; 44 | for (size_t i = 0; i < thread_num; ++i) { 45 | thread_pool.push_back(std::thread([&]() { 46 | size_t value; 47 | for (size_t i = 0; i < run_times; ++i) { 48 | if (i % 2 == 0) { 49 | lru_cache_bench.Set(i, i); 50 | } else { 51 | lru_cache_bench.Get(i - 1, value); 52 | } 53 | } 54 | })); 55 | } 56 | 57 | for (auto& t : thread_pool) { 58 | t.join(); 59 | } 60 | 61 | gettimeofday(&t2, NULL); 62 | time_t time_cost = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec; 63 | double time_in_sec = double(time_cost) / 1000000; 64 | double total_num = double(thread_num * run_times); 65 | double qps = total_num / time_in_sec; 66 | std::cout << "lru_cache: thread_num[" << thread_num << "] qps:" << qps << std::endl; 67 | } -------------------------------------------------------------------------------- /test/base/test_md5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | class test_MD5 : public testing::Test 8 | { 9 | public: 10 | test_MD5 () {} 11 | ~test_MD5 () {} 12 | 13 | virtual void SetUp (void) 14 | { 15 | 16 | } 17 | 18 | virtual void TearDown (void) 19 | { 20 | 21 | } 22 | }; 23 | 24 | // static public 25 | std::string Md5 (const void* str, const size_t size) 26 | { 27 | assert (0 != str && size > 0); 28 | unsigned char md[16]; 29 | char tmp[3] = { '\0' }; 30 | char buf[33] = { '\0' }; 31 | 32 | MD5 (reinterpret_cast(str), size, md); 33 | for (int i = 0; i < 16; ++i) { 34 | snprintf (tmp, sizeof (tmp), "%02x", md[i]); 35 | strcat (buf, tmp); 36 | } 37 | 38 | return std::string (buf, sizeof (buf)-1); 39 | } 40 | 41 | TEST_F (test_MD5, All) 42 | { 43 | swift::MD5 md5; 44 | EXPECT_FALSE (md5.Valid ()); 45 | 46 | std::string val = "abcdefghijklmnopqrstuvwxyz0123456789"; 47 | md5.Update (val.data (), val.size ()); 48 | md5.Final (); 49 | std::string md5_result = std::move (md5.ToString ()); 50 | std::string result = std::move (Md5 (val.data (), val.size ())); 51 | std::string out; 52 | swift::MD5::Md5Sum (val.data (), val.size (), out); 53 | EXPECT_EQ (md5_result, out); 54 | EXPECT_EQ (md5_result, result); 55 | out.clear (); 56 | swift::MD5::Md5Sum (swift::StringPiece (val.data (), val.size ()), out); 57 | EXPECT_EQ (out, result); 58 | EXPECT_TRUE (md5.Valid ()); 59 | 60 | md5.Reset (); 61 | EXPECT_FALSE (md5.Valid ()); 62 | std::string str1 = "abcdefghijklmnopqrstuvwxyz"; 63 | std::string str2 = "0123456789"; 64 | md5.Update (nullptr, val.size ()); 65 | EXPECT_FALSE (md5.Valid ()); 66 | md5.Update (str1.data (), str1.size ()); 67 | md5.Update (str2.data (), str2.size ()); 68 | md5.Final (); 69 | EXPECT_EQ (md5.ToString (), result); 70 | 71 | swift::MD5 other; 72 | other.Update (val.c_str (), val.size ()); 73 | other.Final (); 74 | ASSERT_TRUE (other == md5); 75 | ASSERT_FALSE (other != md5); 76 | 77 | other.Reset (); 78 | EXPECT_FALSE (other.Valid ()); 79 | other.Update ("abc", 0); 80 | EXPECT_TRUE (other.ToString ().empty ()); 81 | other.Final (); 82 | EXPECT_TRUE (other.ToString ().empty ()); 83 | } 84 | -------------------------------------------------------------------------------- /test/base/test_memorymapping.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | class test_MemoryMapping : testing::Test 7 | { 8 | public: 9 | test_MemoryMapping() { } 10 | ~test_MemoryMapping() { } 11 | }; 12 | 13 | static const double kPI = 3.1415926; 14 | 15 | TEST(test_MemoryMapping, Basic) 16 | { 17 | swift::File f = swift::File::Temporary(); 18 | { 19 | swift::MemoryMapping m(f.GetFd(), 0, sizeof(double), swift::MemoryMapping::Writable()); 20 | double volatile* d = m.AsWritableBuffer().buf; 21 | *d = 37 * kPI; 22 | } 23 | 24 | { 25 | swift::MemoryMapping m(f.GetFd(), 0, 3); 26 | EXPECT_EQ(0, m.AsReadableBuffer().length); 27 | } 28 | 29 | { 30 | swift::MemoryMapping m(f.GetFd(), 0, sizeof(double)); 31 | const double volatile* d = m.AsReadableBuffer().buf; 32 | EXPECT_EQ(*d, 37 * kPI); 33 | } 34 | 35 | std::string s = "hello world"; 36 | EXPECT_EQ(s.size(), f.Write(s.data(), s.size())); 37 | { 38 | swift::MemoryMapping m(f.GetFd()); 39 | EXPECT_EQ(s, m.GetData().data()); 40 | } 41 | { 42 | swift::MemoryMapping m(f.GetFd(), 1, 2); 43 | EXPECT_EQ('e', m.GetData().data()[0]); 44 | EXPECT_EQ('l', m.GetData().data()[1]); 45 | EXPECT_EQ(2, m.GetData().size()); 46 | } 47 | { 48 | swift::MemoryMapping m(f.GetFd()); 49 | EXPECT_EQ(s, m.GetData().data()); 50 | } 51 | 52 | // Anonymous 53 | { 54 | swift::MemoryMapping::Options opt; 55 | opt.SetWritable(true); 56 | opt.SetShared(true); 57 | opt.SetGrow(false); 58 | opt.SetPrefault(false); 59 | opt.SetShared(false); 60 | opt.SetPageSize(::sysconf(_SC_PAGESIZE)); 61 | // Anonymous mmap will set the file to 0 62 | swift::MemoryMapping m(swift::MemoryMapping::AnonymousType::ANONYMOUS_TYPE, 63 | sizeof(int), 64 | opt); 65 | EXPECT_EQ(-1, m.GetFd()); 66 | EXPECT_EQ(sizeof(int), m.GetData().size()); 67 | swift::MemoryMapping::Buffer buffer = m.AsWritableBuffer(); 68 | EXPECT_NE(buffer.buf, nullptr); 69 | (*buffer.buf)++; 70 | EXPECT_EQ(1, *buffer.buf); 71 | } 72 | } 73 | 74 | TEST(test_MemoryMapping, Lock) 75 | { 76 | swift::File f = swift::File::Temporary(); 77 | swift::MemoryMapping m(swift::File(f.GetFd())); 78 | EXPECT_TRUE(m.mlock(swift::MemoryMapping::LockMode::LOCK_MODE_LOCK)); 79 | EXPECT_TRUE(m.IsLocked()); 80 | EXPECT_EQ(0, m.GetData().size()); 81 | // Can lock mutil times at the same process 82 | EXPECT_TRUE(m.mlock(swift::MemoryMapping::LockMode::LOCK_MODE_TRY_LOCK)); 83 | m.munlock(); 84 | EXPECT_TRUE(m.mlock(swift::MemoryMapping::LockMode::LOCK_MODE_TRY_LOCK)); 85 | m.munlock(true); 86 | } 87 | 88 | TEST(test_MemoryMapping, DoublyMapped) 89 | { 90 | swift::File f = swift::File::Temporary(); 91 | swift::MemoryMapping mw(f.GetFd(), 0, sizeof(double), swift::MemoryMapping::Writable()); 92 | swift::MemoryMapping mr(f.GetFd(), 0, sizeof(double)); 93 | 94 | double volatile* dw = mw.AsWritableBuffer().buf; 95 | const double volatile* dr = mr.AsReadableBuffer().buf; 96 | EXPECT_NE(dw, dr); 97 | *dw = 42 * kPI; 98 | EXPECT_EQ(*dr, 42 * kPI); 99 | *dw = 43 * kPI; 100 | EXPECT_EQ(*dr, 43 * kPI); 101 | } 102 | 103 | TEST(test_MemoryMapping, Copy) 104 | { 105 | swift::File f; 106 | EXPECT_TRUE(f.Open("test_MemoryMapping_01")); 107 | for (int i = 0; i < 100; ++i) { 108 | EXPECT_EQ(sizeof(i), f.PWrite(reinterpret_cast(&i), sizeof(i), sizeof(i) * i)); 109 | } 110 | f.Close(); 111 | 112 | swift::MemoryMapping::MMapFileCopy("test_MemoryMapping_01", "test_MemoryMapping_02"); 113 | swift::MemoryMapping m("test_MemoryMapping_02", 0, sizeof(int) * 100); 114 | swift::MemoryMapping::Buffer buffer = m.AsReadableBuffer(); 115 | EXPECT_EQ(buffer.length, 100); 116 | int* buf = buffer.buf; 117 | for (int i = 0; i < 100; ++i) { 118 | EXPECT_EQ(i, buf[i]); 119 | } 120 | 121 | system("rm -rf test_MemoryMapping_0*"); 122 | } -------------------------------------------------------------------------------- /test/base/test_processinformation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class test_ProcessInformation : public testing::Test 6 | { 7 | public: 8 | test_ProcessInformation () {} 9 | ~test_ProcessInformation () {} 10 | 11 | virtual void SetUp (void) 12 | { 13 | 14 | } 15 | 16 | virtual void TearDown (void) 17 | { 18 | 19 | } 20 | }; 21 | 22 | TEST_F (test_ProcessInformation, All) 23 | { 24 | swift::ProcessInformation::InitializeSystemInformation (); 25 | swift::ProcessInformation pf; 26 | std::cout << "pid:\t" << pf.GetPidAsUint32 () << std::endl; 27 | ASSERT_TRUE (pf.GetPidAsUint32 () > 0); 28 | ASSERT_TRUE (pf.GetAddressSize () > 0); 29 | std::cout << "VirtualMemorySize:\t" << pf.GetVirtualMemorySize () << std::endl; 30 | std::cout << "ResidentSize:\t" << pf.GetResidentSize () << std::endl; 31 | std::cout << "pid:\t" << pf.GetPidAsString () << std::endl; 32 | std::cout << "OsType:\t" << pf.GetOsType () << std::endl; 33 | std::cout << "OsName:\t" << pf.GetOsName () << std::endl; 34 | std::cout << "OsVersion:\t" << pf.GetOsVersion () << std::endl; 35 | std::cout << "AddressSize:\t" << pf.GetAddressSize () << std::endl; 36 | std::cout << "MemorySizeMB:\t" << pf.GetMemorySizeMB () << std::endl; 37 | std::cout << "NumberPages:\t" << pf.GetNumberPages () << std::endl; 38 | std::cout << "NumberOfCores:\t" << pf.GetNumberOfCores () << std::endl; 39 | std::cout << "MaxOpenFiles:\t" << pf.GetMaxOpenFiles () << std::endl; 40 | std::cout << "Architecture:\t" << pf.GetArchitecture () << std::endl; 41 | std::cout << "NumaEnabled:\t" << pf.HasNumaEnabled () << std::endl; 42 | std::cout << "LibcVersion:\t" << pf.GetLibcVersion () << std::endl; 43 | std::cout << "KernelVersion:\t" << pf.GetKernelVersion () << std::endl; 44 | std::cout << "CpuFrequncy:\t" << pf.GetCpuFrequncy () << std::endl; 45 | std::cout << "VersionSignature:\t" << pf.GetVersionSignature () << std::endl; 46 | std::cout << "ParentProcessId:\t" << pf.GetParentProcessId () << std::endl; 47 | std::cout << "PageSize:\t" << pf.GetPageSize () << std::endl; 48 | std::cout << "Program Name: " << pf.GetExecutableName () << std::endl; 49 | } -------------------------------------------------------------------------------- /test/base/test_scopeguard.cpp: -------------------------------------------------------------------------------- 1 | #include "swift/base/scopeguard.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using std::vector; 7 | 8 | class test_ScopeGuard : public testing::Test 9 | { 10 | public: 11 | test_ScopeGuard () {} 12 | ~test_ScopeGuard () {} 13 | 14 | virtual void SetUp (void) 15 | { 16 | 17 | } 18 | 19 | virtual void TearDown (void) 20 | { 21 | 22 | } 23 | }; 24 | 25 | int ReturnInt () 26 | { 27 | return 1; 28 | } 29 | 30 | class TestFunctor 31 | { 32 | public: 33 | explicit TestFunctor (int* ptr) : ptr_ (ptr) 34 | { 35 | 36 | } 37 | 38 | void operator() () 39 | { 40 | ++*ptr_; 41 | } 42 | 43 | private: 44 | int *ptr_; 45 | }; 46 | 47 | TEST_F (test_ScopeGuard, DifferentWaysToBind) 48 | { 49 | { 50 | swift::ScopeGuard guard = swift::MakeScopeGuard (ReturnInt); 51 | (void)guard; 52 | } 53 | 54 | vector v; 55 | void (vector::*push_back) (const int&) = &vector::push_back; 56 | v.push_back (1); 57 | { 58 | swift::ScopeGuard guard = swift::MakeScopeGuard (std::bind ( 59 | &vector::pop_back, &v)); 60 | (void)guard; 61 | } 62 | EXPECT_EQ (0, v.size ()); 63 | 64 | { 65 | swift::ScopeGuard guard = swift::MakeScopeGuard (std::bind ( 66 | push_back, &v, 2)); 67 | (void)guard; 68 | } 69 | EXPECT_EQ (1, v.size ()); 70 | 71 | { 72 | // v pass by lvalue 73 | swift::ScopeGuard guard = swift::MakeScopeGuard (std::bind ( 74 | push_back, v, 2)); 75 | (void)guard; 76 | } 77 | EXPECT_EQ (1, v.size ()); 78 | 79 | { 80 | // v pass by ref 81 | swift::ScopeGuard guard = swift::MakeScopeGuard (std::bind ( 82 | push_back, std::ref (v), 3)); 83 | (void)guard; 84 | } 85 | EXPECT_EQ (2, v.size ()); 86 | 87 | { 88 | // v pass into by ref 89 | swift::ScopeGuard guard = swift::MakeScopeGuard ([&v]() { 90 | v.push_back (4); 91 | }); 92 | (void)guard; 93 | } 94 | EXPECT_EQ (3, v.size ()); 95 | 96 | { 97 | // lambda with a copy of v 98 | swift::ScopeGuard guard = swift::MakeScopeGuard ([v]() mutable { 99 | v.push_back (5); 100 | }); 101 | (void)guard; 102 | } 103 | EXPECT_EQ (3, v.size ()); 104 | 105 | // test class object 106 | int n = 0; 107 | { 108 | TestFunctor f (&n); 109 | swift::ScopeGuard guard = swift::MakeScopeGuard (f); 110 | (void)guard; 111 | } 112 | EXPECT_EQ (1, n); 113 | 114 | { 115 | swift::ScopeGuard guard = swift::MakeScopeGuard (TestFunctor (&n)); 116 | (void)guard; 117 | } 118 | EXPECT_EQ (2, n); 119 | 120 | // use auto instead of ScopeGuard 121 | { 122 | auto guard = swift::MakeScopeGuard (TestFunctor (&n)); 123 | (void)guard; 124 | } 125 | EXPECT_EQ (3, n); 126 | 127 | { 128 | const auto& guard = swift::MakeScopeGuard (TestFunctor (&n)); 129 | (void)guard; 130 | } 131 | EXPECT_EQ (4, n); 132 | } 133 | 134 | /** 135 | * Add an integer to a vector if it was inserted into the 136 | * db successfully. Here is a schematic of how you would accomplish 137 | * this with scope guard. 138 | */ 139 | void TestUndoAction (bool failure) { 140 | vector v; 141 | { // defines a "mini" scope 142 | 143 | // be optimistic and insert this into memory 144 | v.push_back (1); 145 | 146 | // The guard is triggered to undo the insertion unless Dismiss() is called. 147 | swift::ScopeGuard guard = swift::MakeScopeGuard ([&] { v.pop_back (); }); 148 | 149 | // Do some action; Use the failure argument to pretend 150 | // if it failed or succeeded. 151 | 152 | // if there was no failure, dismiss the undo guard action. 153 | if (!failure) { 154 | guard.Dismiss (); 155 | } 156 | } // all stack allocated in the mini-scope will be destroyed here. 157 | 158 | if (failure) { 159 | EXPECT_EQ (0, v.size ()); // the action failed => undo insertion 160 | } 161 | else { 162 | EXPECT_EQ (1, v.size ()); // the action succeeded => keep insertion 163 | } 164 | } 165 | 166 | TEST_F (test_ScopeGuard, UndoAction) { 167 | TestUndoAction (true); 168 | TestUndoAction (false); 169 | } 170 | 171 | TEST_F (test_ScopeGuard, SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT_) { 172 | int x = 0; 173 | { 174 | SCOPE_GUARD_VARIABLES_AUTO_RUNNING_ON_EXIT{ 175 | ++x; 176 | }; 177 | EXPECT_EQ (0, x); 178 | } 179 | 180 | EXPECT_EQ (1, x); 181 | } 182 | -------------------------------------------------------------------------------- /test/base/test_sha1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 ApusApp 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | class test_Sha1 : public testing::Test 23 | { 24 | public: 25 | test_Sha1(); 26 | ~test_Sha1(); 27 | }; 28 | 29 | std::string SSL_Sha1Sum(const void* data, size_t size) 30 | { 31 | char tmp[3] = {'\0'}; 32 | char buf[41] = {'\0'}; 33 | swift::detail::Sha1Digest digest; 34 | SHA1(reinterpret_cast(data), size, digest.digest); 35 | for (unsigned i = 0; i < sizeof(digest.digest); ++i) { 36 | snprintf(tmp, sizeof(tmp), "%02x", digest.digest[i]); 37 | strcat(buf, tmp); 38 | } 39 | 40 | return std::string(buf, sizeof(buf) - 1); 41 | } 42 | 43 | TEST(test_Sha1, All) 44 | { 45 | swift::StringPiece str("abcdefghijklmnopqrstuvwxyz0123456789"); 46 | std::string sha1; 47 | std::string ssl_sha1 = SSL_Sha1Sum(str.data(), str.length()); 48 | swift::Sha1::Sha1Sum(str.data(), str.length(), &sha1); 49 | EXPECT_EQ(sha1, ssl_sha1); 50 | 51 | swift::Sha1 sha; 52 | EXPECT_FALSE(sha.Valid()); 53 | 54 | sha.Update(str); 55 | sha.Final(); 56 | EXPECT_EQ(sha.ToString(), ssl_sha1); 57 | sha.Reset(); 58 | EXPECT_FALSE(sha.Valid()); 59 | EXPECT_TRUE(sha.ToString().empty()); 60 | 61 | sha.Update(str.data(), str.size()); 62 | sha.Final(); 63 | EXPECT_TRUE(sha.Valid()); 64 | EXPECT_EQ(sha.ToString(), ssl_sha1); 65 | 66 | sha.Reset(); 67 | for (unsigned i = 0; i < str.length(); ++i) { 68 | char c = str[i]; 69 | sha.Update(&c, 1); 70 | } 71 | sha.Final(); 72 | EXPECT_EQ(sha.ToString(), ssl_sha1); 73 | 74 | swift::Sha1 sha1_sec; 75 | sha1_sec.Update(str); 76 | sha1_sec.Final(); 77 | EXPECT_EQ(sha1_sec, sha); 78 | EXPECT_TRUE(sha1_sec == sha); 79 | 80 | sha.Reset(); 81 | sha.Update("abcdefghijklmnopqrstuvwxyz", 26); 82 | sha.Update(swift::StringPiece ("0123456789", 10)); 83 | sha.Final(); 84 | EXPECT_EQ(sha1_sec, sha); 85 | EXPECT_TRUE(sha1_sec == sha); 86 | EXPECT_EQ(sha.ToString(), ssl_sha1); 87 | 88 | std::string s; 89 | swift::Sha1::Sha1Sum(str, &s); 90 | EXPECT_EQ(s, sha1); 91 | } 92 | 93 | TEST(test_Sha1, FileCopy) 94 | { 95 | swift::File src_file; 96 | src_file.Open("/etc/fstab", O_RDONLY); 97 | swift::File dest_file; 98 | dest_file.Open("fstab"); 99 | 100 | swift::Sha1 sha1; 101 | char buf[4096] = {'\0'}; 102 | size_t offset = 0; 103 | size_t length = 0; 104 | SHA_CTX s; 105 | unsigned char hash[20]; 106 | SHA1_Init(&s); 107 | 108 | while ((length = src_file.PRead(buf, sizeof(buf), offset)) > 0) { 109 | sha1.Update(reinterpret_cast(buf), length); 110 | SHA1_Update(&s, buf, length); 111 | if (dest_file.PWrite(buf, length, offset) != length) { 112 | break; 113 | } 114 | offset += length; 115 | length = 0; 116 | } 117 | 118 | sha1.Final(); 119 | SHA1_Final(hash, &s); 120 | printf("sha1: %s\n", sha1.ToString().c_str()); 121 | 122 | char b[3]; 123 | std::string str; 124 | for (int i=0; i < 20; i++) { 125 | snprintf (b, sizeof(b), "%.2x", (int)hash[i]); 126 | str.append(b); 127 | } 128 | 129 | printf("system sha1: %s\n", str.c_str()); 130 | EXPECT_EQ(str, sha1.ToString()); 131 | 132 | } -------------------------------------------------------------------------------- /test/base/test_threadpool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | class test_ThreadPool : public testing::Test 9 | { 10 | public: 11 | test_ThreadPool () {} 12 | ~test_ThreadPool () {} 13 | 14 | virtual void SetUp (void) 15 | { 16 | 17 | } 18 | 19 | virtual void TearDown (void) 20 | { 21 | 22 | } 23 | }; 24 | 25 | int TestT (int a) 26 | { 27 | std::this_thread::sleep_for (std::chrono::microseconds (500)); 28 | return a * a; 29 | } 30 | 31 | int TestAdd (int a, int b) 32 | { 33 | a += b; 34 | std::this_thread::sleep_for (std::chrono::microseconds (500)); 35 | return a; 36 | } 37 | 38 | int TestSub (int a, int b, int c) 39 | { 40 | a -= b; 41 | b -= c; 42 | std::this_thread::sleep_for (std::chrono::microseconds (500)); 43 | return a - b; 44 | } 45 | 46 | int TestMultiply (int a, int b, int c, int d) 47 | { 48 | std::this_thread::sleep_for (std::chrono::microseconds (500)); 49 | return a * b * c * d; 50 | } 51 | 52 | int TestDivision (int a, int b, int c, int d, int e) 53 | { 54 | std::this_thread::sleep_for (std::chrono::microseconds (500)); 55 | return a / b / c / d / e; 56 | } 57 | 58 | 59 | TEST_F (test_ThreadPool, All) 60 | { 61 | swift::ThreadPool pool (4); 62 | pool.Start (); 63 | 64 | for (int i = 0; i < 1000; ++i) { 65 | pool.Schedule (TestT, 3); 66 | pool.Schedule (TestAdd, 3, 5); 67 | pool.Schedule (TestSub, 3, 5, 7); 68 | pool.Schedule (TestMultiply, 3, 5, 7, 9); 69 | pool.Schedule (TestDivision, 3, 5, 7, 9, 11); 70 | } 71 | 72 | ASSERT_TRUE (pool.TasksRemaining () > 0); 73 | swift::ThreadPool::Task func; 74 | { 75 | func = std::move ([]() { TestAdd (100, 100); }); 76 | } 77 | 78 | auto func_1 = std::move (func); 79 | pool.Schedule (func_1); 80 | ASSERT_TRUE (func == nullptr); 81 | func_1 (); 82 | pool.Schedule (std::move (func_1)); 83 | ASSERT_TRUE (func_1 == nullptr); 84 | 85 | pool.Join (); 86 | } -------------------------------------------------------------------------------- /test/base/test_timestamp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | class test_Timestamp : public testing::Test 6 | { 7 | public: 8 | test_Timestamp () {} 9 | ~test_Timestamp () {} 10 | 11 | virtual void SetUp (void) 12 | { 13 | 14 | } 15 | 16 | virtual void TearDown (void) 17 | { 18 | 19 | } 20 | }; 21 | 22 | TEST_F (test_Timestamp, All) 23 | { 24 | swift::Timestamp ts; 25 | ASSERT_FALSE (ts.Valid ()); 26 | 27 | swift::Timestamp now = swift::Timestamp::Now (); 28 | ASSERT_TRUE (now.Valid ()); 29 | 30 | now.Swap (ts); 31 | ASSERT_FALSE (now.Valid ()); 32 | ASSERT_TRUE (ts.Valid ()); 33 | 34 | swift::Timestamp tt (ts.MicroSecondsSinceEpoch ()); 35 | ASSERT_TRUE (tt == ts); 36 | ASSERT_TRUE (ts.ToString () == tt.ToString ()); 37 | ASSERT_TRUE (ts.ToFormattedString () == tt.ToFormattedString ()); 38 | ASSERT_TRUE (ts.ToFormattedString (false) == tt.ToFormattedString (false)); 39 | ASSERT_TRUE (ts.ToSecDotMicroString () == tt.ToSecDotMicroString ()); 40 | 41 | ASSERT_FALSE (ts < tt); 42 | ASSERT_TRUE (0 == swift::TimeDifference (ts, tt)); 43 | 44 | swift::Timestamp add_time = swift::Timestamp::Invalid (); 45 | add_time = swift::AddTime (ts, 1000.0); 46 | ASSERT_FALSE (add_time < tt); 47 | ASSERT_TRUE (add_time > tt); 48 | ASSERT_TRUE (1000.0 == swift::TimeDifference (add_time, tt)); 49 | } -------------------------------------------------------------------------------- /test/disruptor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME disruptor_test) 5 | 6 | list (APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x ${CMAKE_CXX_FLAGS}") 7 | #add_definitions ("-std=c++0x") 8 | add_executable(${TARGET_NAME} test.cpp) 9 | #target_link_libraries(${TARGET_NAME} pthread) 10 | 11 | -------------------------------------------------------------------------------- /test/disruptor/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define RING_BUFFER_SIZE 1024 9 | 10 | using namespace swift::disruptor; 11 | using namespace std; 12 | 13 | int main (int argc, char** argv) 14 | { 15 | uint64_t iterations = 1000L * 1000L * 100; 16 | 17 | // data source / publisher 18 | auto source = std::make_shared> (); 19 | auto square = std::make_shared> (); 20 | auto cube = std::make_shared> (); 21 | auto diff = std::make_shared> (); 22 | 23 | auto a = std::make_shared ("a"); 24 | auto b = std::make_shared ("b"); 25 | auto c = std::make_shared ("c"); 26 | auto p = std::make_shared ("write", RING_BUFFER_SIZE); 27 | 28 | a->follows (p); 29 | b->follows (p); 30 | c->follows (a); 31 | c->follows (b); 32 | p->follows (c); 33 | 34 | // thread publisher 35 | auto pub_thread = [&] () 36 | { 37 | try { 38 | auto pos = p->begin (); 39 | auto end = p->end (); 40 | 41 | for (uint64_t i = 0; i < iterations;) { 42 | // 1. wait for write slot 43 | if (pos >= end) { 44 | end = p->wait_for (end); 45 | } 46 | 47 | // 2. write event in batches 48 | do { 49 | source->at (pos) = i; 50 | ++pos; 51 | ++i; 52 | 53 | } while (pos < end); 54 | 55 | // 3. publish pos 56 | p->publish (pos - 1); 57 | 58 | // note, publishing in 'batches' is 2x as fast, hitting this 59 | // memory barrior really slows things down in this trival example. 60 | } 61 | 62 | p->set_eof (); 63 | } 64 | catch (std::exception& e) { 65 | std::cerr << "publisher caught: " << e.what () << " at pos " << p->pos ().aquire () << "\n"; 66 | } 67 | }; 68 | 69 | // thread a 70 | auto thread_a = [&] () 71 | { 72 | try { 73 | auto pos = a->begin (); 74 | auto end = a->end (); 75 | while (true) { 76 | if (pos == end) { 77 | a->publish (pos - 1); 78 | end = a->wait_for (end); 79 | } 80 | 81 | square->at (pos) = source->at (pos) * source->at (pos); 82 | ++pos; 83 | } 84 | } 85 | catch (std::exception& e) { 86 | std::cerr << "a caught: " << e.what () << "\n"; 87 | } 88 | }; 89 | 90 | // thread b 91 | auto thread_b = [&] () 92 | { 93 | try { 94 | auto pos = b->begin (); 95 | auto end = b->end (); 96 | while (true) { 97 | if (pos == end) { 98 | b->publish (pos - 1); 99 | end = b->wait_for (end); 100 | } 101 | 102 | cube->at (pos) = source->at (pos) * source->at (pos) * source->at (pos); 103 | ++pos; 104 | } 105 | 106 | } 107 | catch (std::exception& e) { 108 | std::cerr << "b caught: " << e.what () << "\n"; 109 | } 110 | }; 111 | 112 | // thread c 113 | auto thread_c = [&] () 114 | { 115 | try { 116 | auto pos = c->begin (); 117 | auto end = c->end (); 118 | while (true) { 119 | if (pos == end) { 120 | c->publish (pos - 1); 121 | end = c->wait_for (end); 122 | } 123 | 124 | diff->at (pos) = cube->at (pos) - square->at (pos); 125 | ++pos; 126 | } 127 | 128 | } 129 | catch (std::exception& e) { 130 | std::cerr << "c caught: " << e.what () << "\n"; 131 | } 132 | }; 133 | 134 | std::thread pt (pub_thread); 135 | std::thread at (thread_a); 136 | std::thread bt (thread_b); 137 | std::thread ct (thread_c); 138 | 139 | struct timeval start_time, end_time; 140 | gettimeofday (&start_time, NULL); 141 | 142 | pt.join (); 143 | at.join (); 144 | bt.join (); 145 | ct.join (); 146 | 147 | gettimeofday (&end_time, NULL); 148 | 149 | double start, end; 150 | start = start_time.tv_sec + ((double)start_time.tv_usec / 1000000); 151 | end = end_time.tv_sec + ((double)end_time.tv_usec / 1000000); 152 | 153 | std::cout.precision (15); 154 | std::cout << "1P-3C-UNICAST performance: "; 155 | std::cout << (iterations * 1.0) / (end - start) << " ops/secs" << std::endl; 156 | 157 | std::cout << "Source: " << cube->at (0) << " 2x: " << square->at (0) << " diff: " << diff->at (0) << std::endl; 158 | std::cout << "Source: " << cube->at (1) << " 2x: " << square->at (1) << " diff: " << diff->at (1) << std::endl; 159 | std::cout << "Source: " << cube->at (2) << " 2x: " << square->at (2) << " diff: " << diff->at (2) << std::endl; 160 | std::cerr << "Exiting " << std::endl; 161 | 162 | return 0; 163 | } 164 | -------------------------------------------------------------------------------- /test/net/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.1) 2 | cmake_policy (VERSION 2.8.1) 3 | 4 | set (TARGET_NAME swift_net_test) 5 | 6 | aux_source_directory (. SRCS) 7 | add_executable (${TARGET_NAME} ${SRCS}) 8 | add_definitions ("-std=c++0x -Wno-deprecated -D_GLIBCXX_USE_NANOSLEEP") 9 | target_link_libraries (${TARGET_NAME} swift_net gtest pthread crypto glog gflags curl) 10 | -------------------------------------------------------------------------------- /test/net/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main (int argc, char* argv[]) 5 | { 6 | testing::InitGoogleTest (&argc, argv); 7 | swift::StackTrace::InitStackTraceHandler (); 8 | 9 | return RUN_ALL_TESTS (); 10 | } -------------------------------------------------------------------------------- /test/net/test_httpclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | class test_HttpClient : public testing::Test 21 | { 22 | public: 23 | test_HttpClient(); 24 | ~test_HttpClient(); 25 | 26 | virtual void SetUp (void) 27 | { 28 | } 29 | 30 | virtual void TearDown (void) 31 | { 32 | 33 | } 34 | }; 35 | 36 | TEST(test_HttpClient, Get) 37 | { 38 | swift::Request req; 39 | swift::File file; 40 | file.Open("/tmp/get.txt"); 41 | req.SetUrl(std::move(std::string("http://www.iqiyi.com"))); 42 | 43 | swift::Response resp; 44 | swift::HttpClient client; 45 | 46 | int code = client.Get(&req, &resp, &file); 47 | ASSERT_EQ(code, resp.GetStatusCode()); 48 | long size = resp.ContentLength(); 49 | ASSERT_EQ(file.GetFileSize(), size); 50 | 51 | resp.Reset(); 52 | code = client.Get(&req, &resp); 53 | ASSERT_EQ(code, resp.GetStatusCode()); 54 | size = resp.ContentLength(); 55 | ASSERT_EQ(resp.GetBody().size(), size); 56 | } 57 | 58 | --------------------------------------------------------------------------------