http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/include/ignite/thin/cache/cache_peek_mode.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/include/ignite/thin/cache/cache_peek_mode.h b/modules/platforms/cpp/thin-client/include/ignite/thin/cache/cache_peek_mode.h new file mode 100644 index 0000000..7357acd --- /dev/null +++ b/modules/platforms/cpp/thin-client/include/ignite/thin/cache/cache_peek_mode.h @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Declares ignite::thin::cache::CachePeekMode. + */ + +#ifndef _IGNITE_IMPL_THIN_CACHE_CACHE_PEEK_MODE +#define _IGNITE_IMPL_THIN_CACHE_CACHE_PEEK_MODE + +namespace ignite +{ + namespace thin + { + namespace cache + { + /** + * Enumeration of all supported cache peek modes. + */ + struct CachePeekMode + { + enum Type + { + /** + * Peeks into all available cache storages. + */ + ALL = 0x01, + + /** + * Peek into near cache only (don't peek into partitioned cache). + * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + NEAR_CACHE = 0x02, + + /** + * Peek value from primary copy of partitioned cache only (skip near cache). + * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + PRIMARY = 0x04, + + /** + * Peek value from backup copies of partitioned cache only (skip near cache). + * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + BACKUP = 0x08, + + /** + * Peeks value from the on-heap storage only. + */ + ONHEAP = 0x10, + + /** + * Peeks value from the off-heap storage only, without loading off-heap value into cache. + */ + OFFHEAP = 0x20 + }; + }; + } + } +} + +#endif //_IGNITE_IMPL_THIN_CACHE_CACHE_PEEK_MODE \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client.h b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client.h new file mode 100644 index 0000000..aa8c14a --- /dev/null +++ b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client.h @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Declares ignite::thin::IgniteClient class. + */ + +#ifndef _IGNITE_THIN_IGNITE_CLIENT +#define _IGNITE_THIN_IGNITE_CLIENT + +#include <vector> + +#include <ignite/common/concurrent.h> + +#include <ignite/thin/ignite_client_configuration.h> +#include <ignite/thin/cache/cache_client.h> + +namespace ignite +{ + namespace thin + { + /** + * Ignite client class. + * + * This is an entry point for Thin C++ Ignite client. Its main purpose is to establish connection to the remote + * server nodes. + * + * This class implemented as a reference to an implementation so copying of this class instance will only + * create another reference to the same underlying object. Underlying object released automatically once all + * the instances are destructed. + */ + class IGNITE_IMPORT_EXPORT IgniteClient + { + typedef common::concurrent::SharedPointer<void> SP_Void; + public: + /** + * Destructor. + */ + ~IgniteClient(); + + /** + * Start client. + * + * @param cfg Client configuration. + * @return IgniteClient instance. + * @throw IgnitError on inability to connect. + */ + static IgniteClient Start(const IgniteClientConfiguration& cfg); + + /** + * Get cache. + * + * @param name Cache name. + * @return Cache. + */ + template<typename K, typename V> + cache::CacheClient<K, V> GetCache(const char* name) + { + return cache::CacheClient<K, V>(InternalGetCache(name)); + } + + /** + * Get or create cache. + * + * @param name Cache name. + * @return Cache. + */ + template<typename K, typename V> + cache::CacheClient<K, V> GetOrCreateCache(const char* name) + { + return cache::CacheClient<K, V>(InternalGetOrCreateCache(name)); + } + + /** + * Create cache. + * + * @param name Cache name. + * @return Cache. + */ + template<typename K, typename V> + cache::CacheClient<K, V> CreateCache(const char* name) + { + return cache::CacheClient<K, V>(InternalCreateCache(name)); + } + + /** + * Destroy cache by name. + * + * @param name Cache name. + */ + void DestroyCache(const char* name); + + /** + * Get names of currently available caches or an empty collection + * if no caches are available. + * + * @param cacheNames Cache names. Output parameter. + */ + void GetCacheNames(std::vector<std::string>& cacheNames); + + private: + /** + * Get cache. + * Internal call. + * + * @param name Cache name. + * @return Cache. + */ + SP_Void InternalGetCache(const char* name); + + /** + * Get or create cache. + * Internal call. + * + * @param name Cache name. + * @return Cache. + */ + SP_Void InternalGetOrCreateCache(const char* name); + + /** + * Create cache. + * Internal call. + * + * @param name Cache name. + * @return Cache. + */ + SP_Void InternalCreateCache(const char* name); + + /** + * Constructor. + * + * @param impl Implementation. + */ + IgniteClient(SP_Void& impl); + + /** Implementation. */ + SP_Void impl; + }; + } +} + +#endif // _IGNITE_THIN_IGNITE_CLIENT http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h new file mode 100644 index 0000000..3aa9df0 --- /dev/null +++ b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Declares ignite::thin::IgniteClientConfiguration class. + */ + +#ifndef _IGNITE_THIN_IGNITE_CLIENT_CONFIGURATION +#define _IGNITE_THIN_IGNITE_CLIENT_CONFIGURATION + +#include <string> + +#include <ignite/thin/ssl_mode.h> + +namespace ignite +{ + namespace thin + { + /** + * Ignite thin client configuration. + * + * Used to configure IgniteClient. + */ + class IgniteClientConfiguration + { + public: + /** + * Default constructor. + * + * Constructs configuration with all parameters set to default values. + */ + IgniteClientConfiguration() : + sslMode(SslMode::DISABLE) + { + // No-op. + } + + /** + * Get server end points. + * @see SetEndPoints for format. + * @return Server end points. + */ + const std::string& GetEndPoints() const + { + return endPoints; + } + + /** + * Set addressess of the remote servers to connect. + * + * The format of the addresse is: <host>[:<port>[..<port_range>]]. If port is not specified, default port + * is used (10800). You can enlist several hosts separated by comma. + * + * For example: "localhost,example.com:12345,127.0.0.1:10800..10900,192.168.3.80:5893". + * + * @param endPoints Addressess of the remote servers to connect. + */ + void SetEndPoints(const std::string& endPoints) + { + this->endPoints = endPoints; + } + + /** + * Get user name used for the authentication. + * + * @return User name. + */ + const std::string& GetUser() const + { + return user; + } + + /** + * Set user name to use for the authentication. + * + * @param user User name. + */ + void SetUser(const std::string& user) + { + this->user = user; + } + + /** + * Get password used for the authentication. + * + * @return Password. + */ + const std::string& GetPassword() const + { + return password; + } + + /** + * Set password to use for the authentication. + * + * @param password Password. + */ + void SetPassword(const std::string& password) + { + this->password = password; + } + + /** + * Get SSL mode. + * + * @see SslMode for details. + * + * @return SSL mode. + */ + SslMode::Type GetSslMode() const + { + return sslMode; + } + + /** + * Set SSL mode. + * + * @see SslMode for details. + * + * @param sslMode SSL mode. + */ + void SetSslMode(SslMode::Type sslMode) + { + this->sslMode = sslMode; + } + + /** + * Get file path to SSL certificate to use during connection establishment. + * + * @return File path to SSL certificate. + */ + const std::string& GetSslCertFile() const + { + return sslCertFile; + } + + /** + * Set file path to SSL certificate to use during connection establishment. + * + * @param sslCertFile File path to SSL certificate. + */ + void SetSslCertFile(const std::string& sslCertFile) + { + this->sslCertFile = sslCertFile; + } + + /** + * Get file path to SSL private key to use during connection establishment. + * + * @return File path to SSL private key. + */ + const std::string& GetSslKeyFile() const + { + return sslKeyFile; + } + + /** + * Set file path to SSL private key to use during connection establishment. + * + * @param sslKeyFile File path to SSL private key. + */ + void SetSslKeyFile(const std::string& sslKeyFile) + { + this->sslKeyFile = sslKeyFile; + } + + /** + * Get file path to SSL certificate authority to authenticate server certificate during connection + * establishment. + * + * @return File path to SSL certificate authority. + */ + const std::string& GetSslCaFile() const + { + return sslCaFile; + } + + /** + * Set file path to SSL certificate authority to authenticate server certificate during connection + * establishment. + * + * @param sslCaFile File path to SSL certificate authority. + */ + void SetSslCaFile(const std::string& sslCaFile) + { + this->sslCaFile = sslCaFile; + } + + private: + /** Connection end points */ + std::string endPoints; + + /** Username. */ + std::string user; + + /** Password. */ + std::string password; + + /** SSL mode */ + SslMode::Type sslMode; + + /** SSL client certificate path */ + std::string sslCertFile; + + /** SSL client key path */ + std::string sslKeyFile; + + /** SSL client certificate authority path */ + std::string sslCaFile; + }; + } +} +#endif // _IGNITE_THIN_IGNITE_CLIENT_CONFIGURATION http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/include/ignite/thin/ssl_mode.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/include/ignite/thin/ssl_mode.h b/modules/platforms/cpp/thin-client/include/ignite/thin/ssl_mode.h new file mode 100644 index 0000000..2596f4f --- /dev/null +++ b/modules/platforms/cpp/thin-client/include/ignite/thin/ssl_mode.h @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Declares ignite::thin::SslMode. + */ + +#ifndef _IGNITE_THIN_SSL_MODE +#define _IGNITE_THIN_SSL_MODE + +namespace ignite +{ + namespace thin + { + /** SSL Mode. */ + struct SslMode + { + enum Type + { + /** Do not try establish SSL/TLS connection. */ + DISABLE = 0, + + /** Try to establish SSL/TLS connection. Fail if the server does not support SSL/TLS. */ + REQUIRE = 1, + }; + }; + } +} + +#endif //_IGNITE_THIN_SSL_MODE http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/os/linux/src/net/net_utils.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/os/linux/src/net/net_utils.cpp b/modules/platforms/cpp/thin-client/os/linux/src/net/net_utils.cpp new file mode 100644 index 0000000..acd3ca3 --- /dev/null +++ b/modules/platforms/cpp/thin-client/os/linux/src/net/net_utils.cpp @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstdio> +#include <cstdlib> + +#include <set> +#include <string> +#include <iostream> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <ifaddrs.h> +#include <errno.h> + +#include <ignite/ignite_error.h> + +#include "impl/net/net_utils.h" + +namespace ignite +{ + namespace impl + { + namespace thin + { + namespace net + { + namespace net_utils + { + void GetLocalAddresses(std::set<std::string>& addrs) + { + struct ifaddrs *outAddrs; + if(getifaddrs(&outAddrs) != 0) + { + freeifaddrs(outAddrs); + + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Error getting local addresses list"); + } + + for (struct ifaddrs *outAddr = outAddrs; outAddr != NULL; outAddr = outAddr->ifa_next) + { + if (outAddr->ifa_addr == NULL) + continue; + + if (outAddr->ifa_flags & IFF_LOOPBACK) + continue; + + if (!(outAddr->ifa_flags & IFF_UP)) + continue; + + void *inAddr; + + char strBuffer[INET6_ADDRSTRLEN]; + + int saFamily = outAddr->ifa_addr->sa_family; + + switch (saFamily) + { + case AF_INET: + { + sockaddr_in *s4 = reinterpret_cast<sockaddr_in*>(outAddr->ifa_addr); + inAddr = &s4->sin_addr; + break; + } + + case AF_INET6: + { + sockaddr_in6 *s6 = reinterpret_cast<sockaddr_in6*>(outAddr->ifa_addr); + inAddr = &s6->sin6_addr; + break; + } + + default: + continue; + } + + inet_ntop(saFamily, inAddr, strBuffer, sizeof(strBuffer)); + + std::string strAddr(strBuffer); + + if (!strAddr.empty()) + addrs.insert(strAddr); + } + + freeifaddrs(outAddrs); + } + } + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/os/linux/src/net/tcp_socket_client.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/os/linux/src/net/tcp_socket_client.cpp b/modules/platforms/cpp/thin-client/os/linux/src/net/tcp_socket_client.cpp new file mode 100644 index 0000000..fba5069 --- /dev/null +++ b/modules/platforms/cpp/thin-client/os/linux/src/net/tcp_socket_client.cpp @@ -0,0 +1,361 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/tcp.h> +#include <netdb.h> +#include <unistd.h> +#include <fcntl.h> + +#include <cstring> + +#include <sstream> + +#include <ignite/common/concurrent.h> + +#include <ignite/ignite_error.h> +#include "impl/net/tcp_socket_client.h" + +#define SOCKET_ERROR (-1) + +namespace +{ + /** + * Get last socket error message. + * @param error Error code. + * @return Last socket error message string. + */ + std::string GetSocketErrorMessage(int error) + { + std::stringstream res; + + res << "error_code=" << error; + + if (error == 0) + return res.str(); + + char buffer[1024] = ""; + + if (!strerror_r(error, buffer, sizeof(buffer))) + res << ", msg=" << buffer; + + return res.str(); + } + + /** + * Get last socket error message. + * @return Last socket error message string. + */ + std::string GetLastSocketErrorMessage() + { + int lastError = errno; + + return GetSocketErrorMessage(lastError); + } +} + +namespace ignite +{ + namespace impl + { + namespace thin + { + namespace net + { + TcpSocketClient::TcpSocketClient() : + socketHandle(SOCKET_ERROR), + blocking(true) + { + // No-op. + } + + TcpSocketClient::~TcpSocketClient() + { + Close(); + } + + bool TcpSocketClient::Connect(const char* hostname, uint16_t port, int32_t timeout) + { + + addrinfo hints = { 0 }; + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + std::stringstream converter; + converter << port; + + // Resolve the server address and port + addrinfo *result = NULL; + int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result); + + if (res != 0) + { + // TODO implement logging. + //std::string err = "Address resolving failed: " + GetLastSocketErrorMessage(); + //std::cout << err << std::endl; + + return false; + } + + // Attempt to connect to an address until one succeeds + for (addrinfo *it = result; it != NULL; it = it->ai_next) + { + // Create a SOCKET for connecting to server + socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol); + + if (socketHandle == SOCKET_ERROR) + { + std::string err = "Socket creation failed: " + GetLastSocketErrorMessage(); + + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, err.c_str()); + } + + TrySetOptions(); + + // Connect to server. + res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen)); + if (SOCKET_ERROR == res) + { + int lastError = errno; + + if (lastError != EWOULDBLOCK && lastError != EINPROGRESS) + { + // TODO implement logging. + //std::string err = "Connection failed: " + GetSocketErrorMessage(lastError); + //std::cout << err << std::endl; + + Close(); + + continue; + } + + res = WaitOnSocket(timeout, false); + + if (res < 0 || res == WaitResult::TIMEOUT) + { + // TODO implement logging. + //std::string err = "Connection timeout expired: " + GetSocketErrorMessage(-res); + //std::cout << err << std::endl; + + Close(); + + continue; + } + } + break; + } + + freeaddrinfo(result); + + return socketHandle != SOCKET_ERROR; + } + + void TcpSocketClient::Close() + { + InternalClose(); + } + + void TcpSocketClient::InternalClose() + { + if (socketHandle != SOCKET_ERROR) + { + close(socketHandle); + + socketHandle = SOCKET_ERROR; + } + } + + int TcpSocketClient::Send(const int8_t* data, size_t size, int32_t timeout) + { + if (!blocking) + { + int res = WaitOnSocket(timeout, false); + + if (res < 0 || res == WaitResult::TIMEOUT) + return res; + } + + return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0); + } + + int TcpSocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout) + { + if (!blocking) + { + int res = WaitOnSocket(timeout, true); + + if (res < 0 || res == WaitResult::TIMEOUT) + return res; + } + + return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0); + } + + bool TcpSocketClient::IsBlocking() const + { + return blocking; + } + + void TcpSocketClient::TrySetOptions() + { + int trueOpt = 1; + int bufSizeOpt = BUFFER_SIZE; + int idleOpt = KEEP_ALIVE_IDLE_TIME; + int idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD; + + int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF, + reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP socket send buffer size setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF, + reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP socket receive buffer size setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP no-delay mode setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP out-of-bound data inlining setup failed: " + GetLastSocketErrorMessage(); + } + + blocking = false; + + int flags; + if (((flags = fcntl(socketHandle, F_GETFL, 0)) < 0) || + (fcntl(socketHandle, F_SETFL, flags | O_NONBLOCK) < 0)) + { + blocking = true; +// std::string err = "Non-blocking mode setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive mode setup failed: " + GetLastSocketErrorMessage(); + + // There is no sense in configuring keep alive params if we faileed to set up keep alive mode. + return; + } + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE, + reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive idle timeout setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL, + reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive probes period setup failed: " + GetLastSocketErrorMessage(); + } + + } + + int TcpSocketClient::WaitOnSocket(int32_t timeout, bool rd) + { + int ready = 0; + int lastError = 0; + + fd_set fds; + + do { + struct timeval tv = { 0 }; + tv.tv_sec = timeout; + + FD_ZERO(&fds); + FD_SET(socketHandle, &fds); + + fd_set* readFds = 0; + fd_set* writeFds = 0; + + if (rd) + readFds = &fds; + else + writeFds = &fds; + + ready = select(static_cast<int>((socketHandle) + 1), + readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv)); + + if (ready == SOCKET_ERROR) + lastError = GetLastSocketError(); + + } while (ready == SOCKET_ERROR && IsSocketOperationInterrupted(lastError)); + + if (ready == SOCKET_ERROR) + return -lastError; + + socklen_t size = sizeof(lastError); + int res = getsockopt(socketHandle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size); + + if (res != SOCKET_ERROR && lastError != 0) + return -lastError; + + if (ready == 0) + return WaitResult::TIMEOUT; + + return WaitResult::SUCCESS; + } + + int TcpSocketClient::GetLastSocketError() + { + return errno; + } + + int TcpSocketClient::GetLastSocketError(int handle) + { + int lastError = 0; + socklen_t size = sizeof(lastError); + int res = getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size); + + return res == SOCKET_ERROR ? 0 : lastError; + } + + bool TcpSocketClient::IsSocketOperationInterrupted(int errorCode) + { + return errorCode == EINTR; + } + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/os/win/src/net/net_utils.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/os/win/src/net/net_utils.cpp b/modules/platforms/cpp/thin-client/os/win/src/net/net_utils.cpp new file mode 100644 index 0000000..57f59b4 --- /dev/null +++ b/modules/platforms/cpp/thin-client/os/win/src/net/net_utils.cpp @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstddef> + +#include <string> +#include <set> +#include <iostream> + +#include <winsock2.h> +#include <ws2ipdef.h> +#include <ws2tcpip.h> +#include <windows.h> +#include <iphlpapi.h> + +#include <ignite/ignite_error.h> + +#include "impl/net/net_utils.h" + +namespace ignite +{ + namespace impl + { + namespace thin + { + namespace net + { + namespace net_utils + { + void GetLocalAddresses(std::set<std::string>& addrs) + { + IP_ADAPTER_ADDRESSES outAddrs[64]; + + DWORD outAddrsSize = sizeof(outAddrs); + + DWORD error = ::GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &outAddrs[0], &outAddrsSize); + + if (ERROR_SUCCESS != error) + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Error getting local addresses list"); + + for (IP_ADAPTER_ADDRESSES* outAddr = &outAddrs[0]; NULL != outAddr; outAddr = outAddr->Next) + { + if (IF_TYPE_SOFTWARE_LOOPBACK == outAddr->IfType) + continue; + + for (IP_ADAPTER_UNICAST_ADDRESS* addr = outAddr->FirstUnicastAddress; + NULL != addr; + addr = addr->Next) + { + void *inAddr = 0; + + char strBuffer[INET6_ADDRSTRLEN] = { 0 }; + + int saFamily = addr->Address.lpSockaddr->sa_family; + + switch (saFamily) + { + case AF_INET: + { + SOCKADDR_IN* ipv4 = reinterpret_cast<SOCKADDR_IN*>(addr->Address.lpSockaddr); + inAddr = &ipv4->sin_addr; + + break; + } + + case AF_INET6: + { + SOCKADDR_IN6* ipv6 = reinterpret_cast<SOCKADDR_IN6*>(addr->Address.lpSockaddr); + inAddr = &ipv6->sin6_addr; + + break; + } + + default: + continue; + } + + inet_ntop(saFamily, inAddr, strBuffer, sizeof(strBuffer)); + + std::string strAddr(strBuffer); + + if (!strAddr.empty()) + addrs.insert(strAddr); + } + } + } + } + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/os/win/src/net/tcp_socket_client.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/os/win/src/net/tcp_socket_client.cpp b/modules/platforms/cpp/thin-client/os/win/src/net/tcp_socket_client.cpp new file mode 100644 index 0000000..b8d7e15 --- /dev/null +++ b/modules/platforms/cpp/thin-client/os/win/src/net/tcp_socket_client.cpp @@ -0,0 +1,417 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define WIN32_LEAN_AND_MEAN +#define _WINSOCKAPI_ + +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#include <mstcpip.h> + +#include <sstream> + +#include <ignite/ignite_error.h> + +#include <ignite/common/concurrent.h> + +#include "impl/net/tcp_socket_client.h" + +namespace +{ + /** + * Get socket error message for the error code. + * @param error Error code. + * @return Socket error message string. + */ + std::string GetSocketErrorMessage(HRESULT error) + { + std::stringstream res; + + res << "error_code=" << error; + + if (error == 0) + return res.str(); + + LPTSTR errorText = NULL; + + DWORD len = FormatMessage( + // use system message tables to retrieve error text + FORMAT_MESSAGE_FROM_SYSTEM + // allocate buffer on local heap for error text + | FORMAT_MESSAGE_ALLOCATE_BUFFER + // We're not passing insertion parameters + | FORMAT_MESSAGE_IGNORE_INSERTS, + // unused with FORMAT_MESSAGE_FROM_SYSTEM + NULL, + error, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + // output + reinterpret_cast<LPTSTR>(&errorText), + // minimum size for output buffer + 0, + // arguments - see note + NULL); + + if (NULL != errorText) + { + if (len != 0) + res << ", msg=" << std::string(errorText, len); + + LocalFree(errorText); + } + + return res.str(); + } + + /** + * Get last socket error message. + * @return Last socket error message string. + */ + std::string GetLastSocketErrorMessage() + { + HRESULT lastError = WSAGetLastError(); + + return GetSocketErrorMessage(lastError); + } +} + +namespace ignite +{ + namespace impl + { + namespace thin + { + namespace net + { + TcpSocketClient::TcpSocketClient() : + socketHandle(INVALID_SOCKET), + blocking(true) + { + // No-op. + } + + TcpSocketClient::~TcpSocketClient() + { + InternalClose(); + } + + bool TcpSocketClient::Connect(const char* hostname, uint16_t port, int32_t timeout) + { + static common::concurrent::CriticalSection initCs; + static bool networkInited = false; + + // Initing networking if is not inited. + if (!networkInited) + { + common::concurrent::CsLockGuard lock(initCs); + if (!networkInited) + { + WSADATA wsaData; + + networkInited = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0); + + if (!networkInited) + { + std::string err = "Networking initialisation failed: " + GetLastSocketErrorMessage(); + + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, err.c_str()); + } + } + } + + addrinfo hints = { 0 }; + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + std::stringstream converter; + converter << port; + + // Resolve the server address and port + addrinfo *result = NULL; + int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result); + + if (res != 0) + return false; + + // Attempt to connect to an address until one succeeds + for (addrinfo *it = result; it != NULL; it = it->ai_next) + { + // Create a SOCKET for connecting to server + socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol); + + if (socketHandle == INVALID_SOCKET) + { + std::string err = "Socket creation failed: " + GetLastSocketErrorMessage(); + + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, err.c_str()); + } + + TrySetOptions(); + + // Connect to server. + res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen)); + if (SOCKET_ERROR == res) + { + int lastError = WSAGetLastError(); + + if (lastError != WSAEWOULDBLOCK) + { + Close(); + + continue; + } + + res = WaitOnSocket(timeout, false); + + if (res < 0 || res == WaitResult::TIMEOUT) + { + Close(); + + continue; + } + } + break; + } + + freeaddrinfo(result); + + return socketHandle != INVALID_SOCKET; + } + + void TcpSocketClient::Close() + { + InternalClose(); + } + + void TcpSocketClient::InternalClose() + { + if (socketHandle != INVALID_SOCKET) + { + closesocket(socketHandle); + + socketHandle = INVALID_SOCKET; + } + } + + int TcpSocketClient::Send(const int8_t* data, size_t size, int32_t timeout) + { + if (!blocking) + { + int res = WaitOnSocket(timeout, false); + + if (res < 0 || res == WaitResult::TIMEOUT) + return res; + } + + return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0); + } + + int TcpSocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout) + { + if (!blocking) + { + int res = WaitOnSocket(timeout, true); + + if (res < 0 || res == WaitResult::TIMEOUT) + return res; + } + + return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0); + } + + bool TcpSocketClient::IsBlocking() const + { + return blocking; + } + + void TcpSocketClient::TrySetOptions() + { + BOOL trueOpt = TRUE; + ULONG uTrueOpt = TRUE; + int bufSizeOpt = BUFFER_SIZE; + + + int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF, + reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP socket send buffer size setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF, + reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP socket receive buffer size setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP no-delay mode setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP out-of-bound data inlining setup failed: " + GetLastSocketErrorMessage(); + } + + blocking = false; + res = ioctlsocket(socketHandle, FIONBIO, &uTrueOpt); + + if (res == SOCKET_ERROR) + { + blocking = true; +// std::string err = "Non-blocking mode setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, + reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive mode setup failed: " + GetLastSocketErrorMessage(); + + // There is no sense in configuring keep alive params if we faileed to set up keep alive mode. + return; + } + + // This option is available starting with Windows 10, version 1709. +#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) + DWORD idleOpt = KEEP_ALIVE_IDLE_TIME; + DWORD idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD; + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE, + reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive idle timeout setup failed: " + GetLastSocketErrorMessage(); + } + + res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL, + reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt)); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive probes period setup failed: " + GetLastSocketErrorMessage(); + } +#else // use old hardcore WSAIoctl + + // WinSock structure for KeepAlive timing settings + struct tcp_keepalive settings = { 0 }; + settings.onoff = 1; + settings.keepalivetime = KEEP_ALIVE_IDLE_TIME * 1000; + settings.keepaliveinterval = KEEP_ALIVE_PROBES_PERIOD * 1000; + + // pointers for WinSock call + DWORD bytesReturned; + WSAOVERLAPPED overlapped; + overlapped.hEvent = NULL; + + // Set KeepAlive settings + res = WSAIoctl( + socketHandle, + SIO_KEEPALIVE_VALS, + &settings, + sizeof(struct tcp_keepalive), + NULL, + 0, + &bytesReturned, + &overlapped, + NULL + ); + + if (SOCKET_ERROR == res) + { +// std::string err = "TCP keep-alive params setup failed: " + GetLastSocketErrorMessage(); + } +#endif + } + + int TcpSocketClient::WaitOnSocket(int32_t timeout, bool rd) + { + int ready = 0; + int lastError = 0; + + fd_set fds; + + do { + struct timeval tv = { 0 }; + tv.tv_sec = timeout; + + FD_ZERO(&fds); + FD_SET(socketHandle, &fds); + + fd_set* readFds = 0; + fd_set* writeFds = 0; + + if (rd) + readFds = &fds; + else + writeFds = &fds; + + ready = select(static_cast<int>((socketHandle) + 1), + readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv)); + + if (ready == SOCKET_ERROR) + lastError = GetLastSocketError(); + + } while (ready == SOCKET_ERROR && IsSocketOperationInterrupted(lastError)); + + if (ready == SOCKET_ERROR) + return -lastError; + + if (ready == 0) + return WaitResult::TIMEOUT; + + return WaitResult::SUCCESS; + } + + int TcpSocketClient::GetLastSocketError() + { + return WSAGetLastError(); + } + + int TcpSocketClient::GetLastSocketError(int handle) + { + int lastError = 0; + socklen_t size = sizeof(lastError); + int res = getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size); + + return res == SOCKET_ERROR ? 0 : lastError; + } + + bool TcpSocketClient::IsSocketOperationInterrupted(int errorCode) + { + return errorCode == WSAEINTR; + } + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj b/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj new file mode 100644 index 0000000..3221268 --- /dev/null +++ b/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5C037386-B5F5-4A58-9EE2-3D3A508AA866}</ProjectGuid> + <RootNamespace>ignite.thinclient</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>ignite.thin-client</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>ignite.thin-client</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>ignite.thin-client</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>ignite.thin-client</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src;$(OPENSSL_HOME_X86)\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";_DEBUG";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <DelayLoadDLLs> + </DelayLoadDLLs> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src;$(OPENSSL_HOME)\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <DelayLoadDLLs> + </DelayLoadDLLs> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src;$(OPENSSL_HOME_X86)\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src;$(OPENSSL_HOME)\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\os\win\src\net\tcp_socket_client.cpp" /> + <ClCompile Include="..\..\os\win\src\net\net_utils.cpp" /> + <ClCompile Include="..\..\src\ignite_client.cpp" /> + <ClCompile Include="..\..\src\impl\cache\cache_affinity_info.cpp" /> + <ClCompile Include="..\..\src\impl\cache\cache_client_impl.cpp" /> + <ClCompile Include="..\..\src\impl\cache\cache_client_proxy.cpp" /> + <ClCompile Include="..\..\src\impl\data_channel.cpp" /> + <ClCompile Include="..\..\src\impl\data_router.cpp" /> + <ClCompile Include="..\..\src\impl\ignite_client_impl.cpp" /> + <ClCompile Include="..\..\src\impl\message.cpp" /> + <ClCompile Include="..\..\src\impl\net\remote_type_updater.cpp" /> + <ClCompile Include="..\..\src\impl\protocol_version.cpp" /> + <ClCompile Include="..\..\src\impl\ssl\secure_socket_client.cpp" /> + <ClCompile Include="..\..\src\impl\ssl\ssl_gateway.cpp" /> + <ClCompile Include="..\..\src\impl\utility.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\ignite\impl\thin\cache\cache_client_proxy.h" /> + <ClInclude Include="..\..\include\ignite\impl\thin\readable.h" /> + <ClInclude Include="..\..\include\ignite\impl\thin\writable.h" /> + <ClInclude Include="..\..\include\ignite\impl\thin\writable_key.h" /> + <ClInclude Include="..\..\include\ignite\thin\cache\cache_client.h" /> + <ClInclude Include="..\..\include\ignite\thin\cache\cache_peek_mode.h" /> + <ClInclude Include="..\..\include\ignite\thin\ignite_client.h" /> + <ClInclude Include="..\..\include\ignite\thin\ignite_client_configuration.h" /> + <ClInclude Include="..\..\include\ignite\thin\ssl_mode.h" /> + <ClInclude Include="..\..\src\impl\cache\cache_affinity_info.h" /> + <ClInclude Include="..\..\src\impl\cache\cache_client_impl.h" /> + <ClInclude Include="..\..\src\impl\connectable_node_partitions.h" /> + <ClInclude Include="..\..\src\impl\data_channel.h" /> + <ClInclude Include="..\..\src\impl\data_router.h" /> + <ClInclude Include="..\..\src\impl\ignite_client_impl.h" /> + <ClInclude Include="..\..\src\impl\message.h" /> + <ClInclude Include="..\..\src\impl\net\end_point.h" /> + <ClInclude Include="..\..\src\impl\net\net_utils.h" /> + <ClInclude Include="..\..\src\impl\net\remote_type_updater.h" /> + <ClInclude Include="..\..\src\impl\net\tcp_range.h" /> + <ClInclude Include="..\..\src\impl\net\tcp_socket_client.h" /> + <ClInclude Include="..\..\src\impl\protocol_version.h" /> + <ClInclude Include="..\..\src\impl\response_status.h" /> + <ClInclude Include="..\..\src\impl\socket_client.h" /> + <ClInclude Include="..\..\src\impl\ssl\secure_socket_client.h" /> + <ClInclude Include="..\..\src\impl\ssl\ssl_bindings.h" /> + <ClInclude Include="..\..\src\impl\ssl\ssl_gateway.h" /> + <ClInclude Include="..\..\src\impl\utility.h" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\binary\project\vs\binary.vcxproj"> + <Project>{4f15669b-92eb-49f0-b774-8f19bae0b960}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\common\project\vs\common.vcxproj"> + <Project>{b63f2e01-5157-4719-8491-0e1c7cd3b701}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj.filters b/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj.filters new file mode 100644 index 0000000..2d20106 --- /dev/null +++ b/modules/platforms/cpp/thin-client/project/vs/thin-client.vcxproj.filters @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Code"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Code\impl"> + <UniqueIdentifier>{9bc8816b-8ec1-4da2-9381-d194f811280c}</UniqueIdentifier> + </Filter> + <Filter Include="Code\impl\net"> + <UniqueIdentifier>{a9e3beb1-9215-4edc-b0ea-eddd868bbc93}</UniqueIdentifier> + </Filter> + <Filter Include="Code\impl\ssl"> + <UniqueIdentifier>{46739e07-2e4d-400b-bba2-902d96158c44}</UniqueIdentifier> + </Filter> + <Filter Include="Code\cache"> + <UniqueIdentifier>{143c6ccd-4c0a-4ac3-a6a5-23aa030288db}</UniqueIdentifier> + </Filter> + <Filter Include="Code\impl\cache"> + <UniqueIdentifier>{372189a3-2442-47b1-bd75-7fe916a586ec}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\impl\ignite_client_impl.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\ignite_client.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\data_router.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\protocol_version.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\ssl\secure_socket_client.cpp"> + <Filter>Code\impl\ssl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\ssl\ssl_gateway.cpp"> + <Filter>Code\impl\ssl</Filter> + </ClCompile> + <ClCompile Include="..\..\os\win\src\net\tcp_socket_client.cpp"> + <Filter>Code\impl\net</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\message.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\utility.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\cache\cache_client_proxy.cpp"> + <Filter>Code\impl\cache</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\cache\cache_client_impl.cpp"> + <Filter>Code\impl\cache</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\net\remote_type_updater.cpp"> + <Filter>Code\impl\net</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\data_channel.cpp"> + <Filter>Code\impl</Filter> + </ClCompile> + <ClCompile Include="..\..\os\win\src\net\net_utils.cpp"> + <Filter>Code\impl\net</Filter> + </ClCompile> + <ClCompile Include="..\..\src\impl\cache\cache_affinity_info.cpp"> + <Filter>Code\impl\cache</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\ignite\thin\ignite_client.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\thin\ignite_client_configuration.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\thin\ssl_mode.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\thin\cache\cache_client.h"> + <Filter>Code\cache</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\impl\thin\writable.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\impl\thin\readable.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\impl\thin\cache\cache_client_proxy.h"> + <Filter>Code\impl\cache</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\impl\thin\writable_key.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\connectable_node_partitions.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\data_channel.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\data_router.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\ignite_client_impl.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\message.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\protocol_version.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\response_status.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\socket_client.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\utility.h"> + <Filter>Code\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\ssl\secure_socket_client.h"> + <Filter>Code\impl\ssl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\ssl\ssl_bindings.h"> + <Filter>Code\impl\ssl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\ssl\ssl_gateway.h"> + <Filter>Code\impl\ssl</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\net\end_point.h"> + <Filter>Code\impl\net</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\net\net_utils.h"> + <Filter>Code\impl\net</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\net\remote_type_updater.h"> + <Filter>Code\impl\net</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\net\tcp_range.h"> + <Filter>Code\impl\net</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\net\tcp_socket_client.h"> + <Filter>Code\impl\net</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\cache\cache_client_impl.h"> + <Filter>Code\impl\cache</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\thin\cache\cache_peek_mode.h"> + <Filter>Code\cache</Filter> + </ClInclude> + <ClInclude Include="..\..\src\impl\cache\cache_affinity_info.h"> + <Filter>Code\impl\cache</Filter> + </ClInclude> + </ItemGroup> +</Project> http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/src/ignite_client.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/src/ignite_client.cpp b/modules/platforms/cpp/thin-client/src/ignite_client.cpp new file mode 100644 index 0000000..57909e4 --- /dev/null +++ b/modules/platforms/cpp/thin-client/src/ignite_client.cpp @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ignite/thin/ignite_client.h> +#include <ignite/thin/ignite_client_configuration.h> + +#include "impl/ignite_client_impl.h" +#include "impl/cache/cache_client_impl.h" + +using namespace ignite::impl::thin; +using namespace cache; +using namespace ignite::common::concurrent; + +namespace +{ + IgniteClientImpl& GetClientImpl(SharedPointer<void>& ptr) + { + return *reinterpret_cast<IgniteClientImpl*>(ptr.Get()); + } + + const IgniteClientImpl& GetClientImpl(const SharedPointer<void>& ptr) + { + return *reinterpret_cast<const IgniteClientImpl*>(ptr.Get()); + } + + CacheClientImpl& GetCacheImpl(SharedPointer<void>& ptr) + { + return *reinterpret_cast<CacheClientImpl*>(ptr.Get()); + } + + const CacheClientImpl& GetCacheImpl(const SharedPointer<void>& ptr) + { + return *reinterpret_cast<const CacheClientImpl*>(ptr.Get()); + } +} + +namespace ignite +{ + namespace thin + { + void IgniteClient::DestroyCache(const char* name) + { + GetClientImpl(impl).DestroyCache(name); + } + + void IgniteClient::GetCacheNames(std::vector<std::string>& cacheNames) + { + GetClientImpl(impl).GetCacheNames(cacheNames); + } + + IgniteClient::SP_Void IgniteClient::InternalGetCache(const char* name) + { + return GetClientImpl(impl).GetCache(name); + } + + IgniteClient::SP_Void IgniteClient::InternalGetOrCreateCache(const char* name) + { + return GetClientImpl(impl).GetOrCreateCache(name); + } + + IgniteClient::SP_Void IgniteClient::InternalCreateCache(const char* name) + { + return static_cast<SP_Void>(GetClientImpl(impl).CreateCache(name)); + } + + IgniteClient::IgniteClient(SP_Void& impl) + { + this->impl.Swap(impl); + } + + IgniteClient::~IgniteClient() + { + // No-op. + } + + IgniteClient IgniteClient::Start(const IgniteClientConfiguration& cfg) + { + SharedPointer<IgniteClientImpl> res(new IgniteClientImpl(cfg)); + + res.Get()->Start(); + + SP_Void ptr(res); + + return IgniteClient(ptr); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.cpp b/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.cpp new file mode 100644 index 0000000..2daa6f3 --- /dev/null +++ b/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.cpp @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ignite/impl/thin/writable_key.h> + +#include "impl/connectable_node_partitions.h" +#include "impl/cache/cache_affinity_info.h" + +namespace ignite +{ + namespace impl + { + namespace thin + { + namespace cache + { + CacheAffinityInfo::CacheAffinityInfo(const std::vector<ConnectableNodePartitions>& info) + { + std::vector<ConnectableNodePartitions>::const_iterator it; + + for (it = info.begin(); it != info.end(); ++it) + { + const std::vector<int32_t>& parts = it->GetPartitions(); + const std::vector<net::EndPoint>& endPoints = it->GetEndPoints(); + + for (size_t i = 0; i < parts.size(); ++i) + { + assert(parts[i] >= 0); + + size_t upart = static_cast<size_t>(parts[i]); + + if (upart >= affinityMapping.size()) + affinityMapping.resize(upart + 1); + + EndPoints& dst = affinityMapping[upart]; + + dst.insert(dst.end(), endPoints.begin(), endPoints.end()); + } + } + } + + CacheAffinityInfo::~CacheAffinityInfo() + { + // No-op. + } + + int32_t CacheAffinityInfo::GetPartitionsNum() const + { + return static_cast<int32_t>(affinityMapping.size()); + } + + const EndPoints& CacheAffinityInfo::GetMapping(int32_t part) const + { + assert(part >= 0); + assert(static_cast<size_t>(part) < affinityMapping.size()); + + return affinityMapping[part]; + } + + const EndPoints& CacheAffinityInfo::GetMapping(const WritableKey& key) const + { + int32_t part = GetPartitionForKey(key); + + return affinityMapping[part]; + } + + int32_t CacheAffinityInfo::GetPartitionForKey(const WritableKey& key) const + { + int32_t hash = key.GetHashCode(); + uint32_t uhash = static_cast<uint32_t>(hash); + + int32_t parts = GetPartitionsNum(); + + int32_t part = 0; + + if ((parts & (parts - 1)) == 0) + { + int32_t mask = parts - 1; + + part = (uhash ^ (uhash >> 16)) & mask; + } + else + { + part = std::abs(hash % parts); + + if (part < 0) + part = 0; + } + + return part; + } + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed658597/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.h b/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.h new file mode 100644 index 0000000..8394516 --- /dev/null +++ b/modules/platforms/cpp/thin-client/src/impl/cache/cache_affinity_info.h @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_IMPL_THIN_CACHE_CACHE_AFFINITY_INFO +#define _IGNITE_IMPL_THIN_CACHE_CACHE_AFFINITY_INFO + +#include <stdint.h> + +#include <vector> + +#include <ignite/common/concurrent.h> + +#include "impl/net/end_point.h" + +namespace ignite +{ + namespace impl + { + namespace thin + { + /* Forward declaration. */ + class WritableKey; + + /* Forward declaration. */ + class ConnectableNodePartitions; + + namespace cache + { + /** End point collection. */ + typedef std::vector<net::EndPoint> EndPoints; + + /** + * Cache Affinity Info. + */ + class CacheAffinityInfo + { + public: + /** + * Constructor. + * + * @param info Node partitions info. + */ + CacheAffinityInfo(const std::vector<ConnectableNodePartitions>& info); + + /** + * Destructor. + */ + ~CacheAffinityInfo(); + + /** + * Get number of partitions. + * + * @return Number of partitions. + */ + int32_t GetPartitionsNum() const; + + /** + * Get mapping for the partition. + * + * @param part Partition. + * @return Mapping. + */ + const EndPoints& GetMapping(int32_t part) const; + + /** + * Get mapping for the partition. + * + * @param key Key. + * @return Mapping. + */ + const EndPoints& GetMapping(const WritableKey& key) const; + + /** + * Calculate partition for the key assuming it uses Rendezvous Affinity Function. + * + * @param key Key. + * @return Partition for the key. + */ + int32_t GetPartitionForKey(const WritableKey& key) const; + + private: + /** Affinity mapping. */ + std::vector<EndPoints> affinityMapping; + }; + + /** Shared pointer to Cache Affinity Info. */ + typedef common::concurrent::SharedPointer<CacheAffinityInfo> SP_CacheAffinityInfo; + } + } + } +} +#endif // _IGNITE_IMPL_THIN_CACHE_CACHE_AFFINITY_INFO