/* * Copyright (C) 2011-2017 Redis Labs Ltd. * * This file is part of memtier_benchmark. * * memtier_benchmark is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. * * memtier_benchmark is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with memtier_benchmark. If not, see . */ #ifndef _OBJ_GEN_H #define _OBJ_GEN_H #include #include "file_io.h" struct random_data; struct config_weight_list; class random_generator { public: random_generator(); unsigned long long get_random(); unsigned long long get_random_max() const; void set_seed(int seed); private: #ifdef HAVE_RANDOM_R struct random_data m_data_blob; char m_state_array[512]; #elif (defined HAVE_DRAND48) unsigned short m_data_blob[3]; #endif }; class gaussian_noise: public random_generator { public: gaussian_noise() { m_hasSpare = false; } unsigned long long gaussian_distribution_range(double stddev, double median, unsigned long long min, unsigned long long max); private: double gaussian_distribution(const double &stddev); bool m_hasSpare; double m_spare; }; class data_object { protected: const char *m_key; unsigned int m_key_len; const char *m_value; unsigned int m_value_len; unsigned int m_expiry; public: data_object(); ~data_object(); void clear(void); void set_key(const char* key, unsigned int key_len); const char* get_key(unsigned int* key_len); void set_value(const char* value, unsigned int value_len); const char* get_value(unsigned int* value_len); void set_expiry(unsigned int expiry); unsigned int get_expiry(void); }; #define OBJECT_GENERATOR_KEY_ITERATORS 2 /* number of iterators */ #define OBJECT_GENERATOR_KEY_SET_ITER 1 #define OBJECT_GENERATOR_KEY_GET_ITER 0 #define OBJECT_GENERATOR_KEY_RANDOM -1 #define OBJECT_GENERATOR_KEY_GAUSSIAN -2 class object_generator { public: enum data_size_type { data_size_unknown, data_size_fixed, data_size_range, data_size_weighted }; protected: data_size_type m_data_size_type; union { unsigned int size_fixed; struct { unsigned int size_min; unsigned int size_max; } size_range; config_weight_list* size_list; } m_data_size; const char *m_data_size_pattern; bool m_random_data; unsigned int m_expiry_min; unsigned int m_expiry_max; const char *m_key_prefix; unsigned long long m_key_min; unsigned long long m_key_max; double m_key_stddev; double m_key_median; data_object m_object; std::vector m_next_key; unsigned long long m_key_index; char m_key_buffer[250]; char *m_value_buffer; int m_random_fd; gaussian_noise m_random; unsigned int m_value_buffer_size; unsigned int m_value_buffer_mutation_pos; void alloc_value_buffer(void); void alloc_value_buffer(const char* copy_from); void random_init(void); public: object_generator(size_t n_key_iterators = OBJECT_GENERATOR_KEY_ITERATORS); object_generator(const object_generator& copy); virtual ~object_generator(); virtual object_generator* clone(void); unsigned long long random_range(unsigned long long r_min, unsigned long long r_max); unsigned long long normal_distribution(unsigned long long r_min, unsigned long long r_max, double r_stddev, double r_median); void set_random_data(bool random_data); void set_data_size_fixed(unsigned int size); void set_data_size_range(unsigned int size_min, unsigned int size_max); void set_data_size_list(config_weight_list* data_size_list); void set_data_size_pattern(const char* pattern); void set_expiry_range(unsigned int expiry_min, unsigned int expiry_max); void set_key_prefix(const char *key_prefix); void set_key_range(unsigned long long key_min, unsigned long long key_max); void set_key_distribution(double key_stddev, double key_median); void set_random_seed(int seed); unsigned long long get_key_index(int iter); virtual const char* get_key(int iter, unsigned int *len); virtual data_object* get_object(int iter); const char * get_key_prefix(); const char* get_value(unsigned long long key_index, unsigned int *len); unsigned int get_expiry(); }; class imported_keylist; class memcache_item; class imported_keylist { protected: struct key { unsigned int key_len; char key_data[0]; }; const char *m_filename; std::vector m_keys; public: imported_keylist(const char *filename); ~imported_keylist(); bool read_keys(void); unsigned int size(); const char* get(unsigned int pos, unsigned int *len); }; class import_object_generator : public object_generator { protected: imported_keylist* m_keys; file_reader m_reader; memcache_item* m_cur_item; bool m_reader_opened; bool m_no_expiry; public: import_object_generator(const char *filename, imported_keylist* keys, bool no_expiry); import_object_generator(const import_object_generator& from); virtual ~import_object_generator(); virtual import_object_generator* clone(void); virtual const char* get_key(int iter, unsigned int *len); virtual data_object* get_object(int iter); bool open_file(void); }; #endif /* _OBJ_GEN_H */