nlsCppSdk/utils/thread_data.h (136 lines of code) (raw):

/* * Copyright 2015 Alibaba Group Holding Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NLS_SDK_THREAD_DATA_H_ #define NLS_SDK_THREAD_DATA_H_ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <utility> #include <vector> namespace AlibabaNls { class DataItf { protected: virtual ~DataItf() {} virtual void Clear() = 0; virtual size_t ArrayNum() = 0; virtual size_t ElementNum() = 0; virtual size_t ElementSize() = 0; }; template <typename T> class DataBase : public DataItf { public: DataBase() { pthread_mutex_init(&data_mutex_, NULL); } virtual ~DataBase() { Clear(); pthread_mutex_destroy(&data_mutex_); } virtual int Pushback(const T *data, int element_num) { if ((NULL != data) && (element_num > 0)) { T *data_for_insert = new T[element_num]; memcpy(data_for_insert, data, sizeof(T) * element_num); pthread_mutex_lock(&data_mutex_); data_.push_back(std::make_pair(data_for_insert, element_num)); pthread_mutex_unlock(&data_mutex_); return 0; } else { return -1; } } virtual int Get(T *data, int element_num, int *start_array_idx, int *start_element_idx, bool is_delete_after_get = false) { int num_shift = 0; if ((NULL != data) && (element_num > 0) && (*start_array_idx >= 0)) { pthread_mutex_lock(&data_mutex_); for (; (*start_array_idx < data_.size()) && (num_shift < element_num);) { if (*start_element_idx + element_num - num_shift >= data_[*start_array_idx].second) { // get data partly from cur array int cur_copy_num = data_[*start_array_idx].second - *start_element_idx; memcpy(data + num_shift, data_[*start_array_idx].first + *start_element_idx, sizeof(T) * cur_copy_num); num_shift += cur_copy_num; *start_element_idx = 0; if (is_delete_after_get) { delete[](data_[*start_array_idx].first); data_.erase(data_.begin() + *start_array_idx); } else { (*start_array_idx)++; } continue; } else { // get data entirely from cur array int cur_copy_num = element_num - num_shift; memcpy(data + num_shift, data_[*start_array_idx].first + *start_element_idx, sizeof(T) * cur_copy_num); num_shift += cur_copy_num; *start_element_idx += cur_copy_num; break; } } pthread_mutex_unlock(&data_mutex_); } return num_shift; } virtual int TryGet(T *data, int element_num, int *start_array_idx, int *start_element_idx, bool is_delete_after_get = false) { int tmp_start_array_idx = *start_array_idx; int tmp_start_element_idx = *start_element_idx; if (element_num != Get(data, element_num, start_array_idx, start_element_idx)) { *start_array_idx = tmp_start_array_idx; *start_element_idx = tmp_start_element_idx; if (is_delete_after_get) { Flush(start_array_idx); } return 0; } else { if (is_delete_after_get) { Flush(start_array_idx); } return element_num; } } virtual void Flush(int *start_array_idx) { pthread_mutex_lock(&data_mutex_); for (; *start_array_idx > 0 && *start_array_idx < data_.size();) { if ((*data_.begin()).first) { delete[](*data_.begin()).first; } data_.erase(data_.begin()); (*start_array_idx)--; } pthread_mutex_unlock(&data_mutex_); } virtual void Clear() { pthread_mutex_lock(&data_mutex_); for (size_t i = 0; i < data_.size(); ++i) { if (data_[i].first) { delete[](data_[i].first); } } data_.clear(); pthread_mutex_unlock(&data_mutex_); } virtual size_t ArrayNum() { size_t array_num = 0; pthread_mutex_lock(&data_mutex_); array_num = data_.size(); pthread_mutex_unlock(&data_mutex_); return array_num; } virtual size_t ElementNum() { size_t element_num = 0; pthread_mutex_lock(&data_mutex_); for (size_t i = 0; i < data_.size(); ++i) { element_num += data_[i].second; } pthread_mutex_unlock(&data_mutex_); return element_num; } virtual size_t ElementSize() { return sizeof(T); } protected: std::vector<std::pair<T *, int> > data_; pthread_mutex_t data_mutex_; }; } // namespace AlibabaNls #endif // NLS_SDK_THREAD_DATA_H_