00001 /******************************************************************************* 00002 Copyright (c) 2011, Yahoo! Inc. 00003 All rights reserved. 00004 00005 Redistribution and use of this software in source and binary forms, 00006 with or without modification, are permitted provided that the following 00007 conditions are met: 00008 00009 * Redistributions of source code must retain the above 00010 copyright notice, this list of conditions and the 00011 following disclaimer. 00012 00013 * Redistributions in binary form must reproduce the above 00014 copyright notice, this list of conditions and the 00015 following disclaimer in the documentation and/or other 00016 materials provided with the distribution. 00017 00018 * Neither the name of Yahoo! Inc. nor the names of its 00019 contributors may be used to endorse or promote products 00020 derived from this software without specific prior 00021 written permission of Yahoo! Inc. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00024 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00025 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00026 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 00035 The Initial Developer of the Original Code is Shravan Narayanamurthy. 00036 ******************************************************************************/ 00037 /* 00038 * DM_Server.h 00039 * 00040 * 00041 * Created on: 19-Oct-2010 00042 * 00043 */ 00044 00045 #ifndef DM_SERVER_H_ 00046 #define DM_SERVER_H_ 00047 #include <Ice/Ice.h> 00048 #include "DistributedMap.h" 00049 #include "Hashmap_Array.h" 00050 #include <IceUtil/Mutex.h> 00051 #include <IceUtil/Handle.h> 00052 #include <list> 00053 #include "Server_Helper.h" 00054 00055 using namespace GlobalTable; 00056 using namespace std; 00057 00058 const int QUE_FULL = 50; 00059 const int NUM_CONSUMERS = 3; 00060 const int CHUNK = 10; 00061 00062 /** 00063 * Container class for a put and get job. 00064 * The putNget_async operation is an asynchronous operation 00065 * with asynchronous method dispatch. 00066 * 00067 * Hence a call should be queued up for later processing 00068 * and this class stores all the details pertinent to that call. 00069 */ 00070 class PNGJob: public IceUtil::Shared { 00071 public: 00072 //!The call back object 00073 AMD_DistributedMap_putNgetPtr png_cb; 00074 00075 //!The word on which this operation 00076 //!is called 00077 string word; 00078 00079 //!The serialized form of data that 00080 //!needs to be accumulated into the 00081 //!entry pointed by word 00082 string delta; 00083 00084 PNGJob(const AMD_DistributedMap_putNgetPtr& cb, const string& word, 00085 const string& delta) : 00086 png_cb(cb), word(word), delta(delta) { 00087 } 00088 }; 00089 typedef IceUtil::Handle<PNGJob> PNGJobPtr; 00090 00091 00092 //!The Server class that implements the DistributedMap Ice interface 00093 /** 00094 * 00095 * It essentially holds a part of the distributed 00096 * map. Associates a 'key' to a particular 'value' 00097 * 00098 * The implementation abstracts out the semantics. 00099 * The only accepted key & value types are strings 00100 * Other types of objects have to be serialized 00101 * before they can be stored. 00102 * 00103 * It provides the usual get, set & remove operations 00104 * with the usual semantics. 00105 * 00106 * It also provides accumulator semantics with the 00107 * put operation. Values stored using a put operation 00108 * are accumulated instead of being replaced. Note 00109 * that the semantics of this accumulating is provided 00110 * by a helper class that implements the Server_Helper 00111 * interface 00112 * 00113 * There is also a putNget operation which uses AMD to 00114 * not block dispatch threads. The putNget is also an 00115 * AMI. More info on AMI in client class. Please look up 00116 * Ice documentation for more details. This operation puts 00117 * a value for the given key and returns the result of the 00118 * accumulate operation. 00119 * 00120 * It also provides a barrier implementation that lets 00121 * clients synchronize. This is a very simple use of AMD 00122 * The dispatch threads are released without busy waiting. 00123 * Only a counter is incremented with every call. Once the 00124 * counter reaches num_clients registered, a response is 00125 * sent to all queued up call back objects. 00126 */ 00127 class DM_Server: public DistributedMap { 00128 public: 00129 //!The num of clients that will be accessing the DistributedMap 00130 //!This parameter is used to provide a barrier 00131 DM_Server(int num_clients, Server_Helper&); 00132 virtual ~DM_Server(); 00133 00134 //!The put operation. 00135 //!Note the slight difference in semantics 00136 //!This has accumulator semantics. The value is accumulated 00137 //!and not replaced 00138 void put(const string& key, const string& val, const Ice::Current&); 00139 00140 //!The set operation. 00141 //!The value is replaced if the key already exists 00142 void set(const string& key, const string& val, const Ice::Current&); 00143 00144 //!The get operation. 00145 //!Sets val with the value of the key and returns true 00146 //!if the key exists. Else does not set val and returns false 00147 bool get(const string& key, string& val, const Ice::Current&); 00148 00149 //!The remove operation. 00150 //!Removes the key-value pair from the table 00151 //!If the key does not exist, returns false. Else returns true 00152 bool remove(const string&, string&, const Ice::Current&); 00153 00154 //!The put and get operation. 00155 //!Does a put(word,delta) and returns the updated value 00156 //!png_cb is the AMD call back object 00157 void putNget_async(const AMD_DistributedMap_putNgetPtr& png_cb, 00158 const string& word, const string& delta, const Ice::Current&); 00159 00160 //!Barrier. Helps clients synchronize 00161 void 00162 waitForAllClients_async( 00163 const AMD_DistributedMap_waitForAllClientsPtr&, 00164 const Ice::Current&); 00165 00166 private: 00167 int _num_clients, _clients_done; 00168 int _num_consumers, _waiting_thrds; 00169 typedef vector<AMD_DistributedMap_waitForAllClientsPtr> cb_vector_t; 00170 cb_vector_t _cbs; 00171 list<PNGJobPtr> _png_jobs; 00172 IceUtil::Mutex _cb_mutex, _png_jobs_mutex; 00173 IceUtil::Monitor<IceUtil::Mutex> _monitor_mutex; 00174 00175 //!The data structure to store the key-value mapping 00176 //!Its an array of hashmaps. 00177 typedef Hashmap_Array<string, string> hashmap_array; 00178 hashmap_array _tc_table; 00179 00180 Server_Helper& _server_helper; 00181 00182 bool get_counts(const string&, string&); 00183 void upd_counts(const string& word, const string& delta); 00184 }; 00185 00186 #endif /* DM_SERVER_H_ */