list_manager.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "bundle_list.h"
00016 #include "list_manager.h"
00017
00018 #include <basis/astring.h>
00019 #include <basis/functions.h>
00020 #include <basis/mutex.h>
00021 #include <structures/string_array.h>
00022
00023 using namespace basis;
00024 using namespace octopi;
00025 using namespace structures;
00026 using namespace timely;
00027
00028 namespace synchronic {
00029
00030
00031
00032
00033 #undef GRAB_LOCK
00034 #define GRAB_LOCK \
00035 auto_synchronizer l(*_locking)
00036
00037 #undef LOG
00038 #define LOG(to_print) \
00039 CLASS_EMERGENCY_LOG(program_wide_logger::get(), to_print)
00040
00041 list_manager::list_manager(const string_array &list_name, bool backgrounded)
00042 : tentacle(list_name, backgrounded),
00043 _entries(new bundle_list),
00044 _locking(new mutex)
00045 {
00046 }
00047
00048 list_manager::~list_manager()
00049 {
00050 WHACK(_entries);
00051 WHACK(_locking);
00052 }
00053
00054 const string_array &list_manager::list_name() const { return group(); }
00055
00056 int list_manager::entries() const
00057 {
00058 GRAB_LOCK;
00059 return _entries->elements();
00060 }
00061
00062 void list_manager::reset()
00063 {
00064 GRAB_LOCK;
00065 _entries->zap(0, _entries->elements() - 1);
00066 }
00067
00068 bool list_manager::is_listed(const string_array &classifier)
00069 {
00070 GRAB_LOCK;
00071 int indy = locked_find(classifier);
00072 return !negative(indy);
00073 }
00074
00075 bool list_manager::update(const string_array &classifier, int offset)
00076 {
00077 GRAB_LOCK;
00078 int indy = locked_find(classifier);
00079 if (negative(indy)) return false;
00080 _entries->borrow(indy)->_updated = time_stamp(offset);
00081 return true;
00082 }
00083
00084 void list_manager::clean(int older_than)
00085 {
00086 GRAB_LOCK;
00087 for (int i = 0; i < _entries->elements(); i++) {
00088 synchronizable *curr = _entries->borrow(i);
00089 if (curr->_updated < time_stamp(-older_than)) {
00090
00091 _entries->zap(i, i);
00092 i--;
00093 }
00094 }
00095 }
00096
00097 bool list_manager::zap(const string_array &classifier)
00098 {
00099 GRAB_LOCK;
00100 int indy = locked_find(classifier);
00101 if (negative(indy)) return false;
00102 _entries->zap(indy, indy);
00103 return true;
00104 }
00105
00106 int list_manager::locked_find(const string_array &classifier)
00107 {
00108 for (int i = 0; i < _entries->elements(); i++) {
00109
00110 if (_entries->get(i)->classifier().length() != classifier.length())
00111 continue;
00112
00113
00114
00115 bool problems = false;
00116 for (int j = classifier.length() - 1; j >= 0; j--) {
00117 if (_entries->get(i)->classifier()[j] != classifier[j]) {
00118 problems = true;
00119 break;
00120 }
00121 }
00122 if (problems) continue;
00123
00124 return i;
00125 }
00126 return common::NOT_FOUND;
00127 }
00128
00129 synchronizable *list_manager::clone_object(const string_array &classifier)
00130 {
00131 GRAB_LOCK;
00132 int indy = locked_find(classifier);
00133 if (negative(indy)) return NIL;
00134 return dynamic_cast<synchronizable *>(_entries->get(indy)->clone());
00135 }
00136
00137 void list_manager::retrieve(bundle_list &to_fill) const
00138 {
00139 to_fill.reset();
00140 GRAB_LOCK;
00141 for (int i = 0; i < _entries->elements(); i++)
00142 to_fill += dynamic_cast<synchronizable *>(_entries->get(i)->clone());
00143 }
00144
00145 outcome list_manager::consume(infoton &to_chow,
00146 const octopus_request_id &formal(item_id), byte_array &transformed)
00147 {
00148 #ifdef DEBUG_LIST_MANAGER
00149 FUNCDEF("consume");
00150 #endif
00151 transformed.reset();
00152 synchronizable *bun = dynamic_cast<synchronizable *>(&to_chow);
00153 if (!bun) return BAD_INPUT;
00154
00155 GRAB_LOCK;
00156
00157
00158 switch (bun->_mod) {
00159 case synchronizable::ADDED:
00160 case synchronizable::CHANGED: {
00161
00162 int indy = locked_find(bun->classifier());
00163 if (negative(indy)) {
00164
00165 *_entries += dynamic_cast<synchronizable *>(bun->clone());
00166 } else {
00167
00168 _entries->borrow(indy)->merge(*bun);
00169 _entries->borrow(indy)->_updated = time_stamp();
00170 }
00171 return OKAY;
00172 }
00173 case synchronizable::DELETED: {
00174 int indy = locked_find(bun->classifier());
00175 if (non_negative(indy)) {
00176
00177 outcome ret = _entries->borrow(indy)->merge(*bun);
00178 _entries->borrow(indy)->_updated = time_stamp();
00179 if (ret == synchronizable::EMPTY) {
00180
00181 #ifdef DEBUG_LIST_MANAGER
00182 LOG(astring("removing entry now due to merge outcome: ")
00183 + _entries->borrow(indy)->text_form());
00184 #endif
00185 _entries->zap(indy, indy);
00186 }
00187 return OKAY;
00188 } else {
00189
00190 #ifdef DEBUG_LIST_MANAGER
00191 LOG(astring("could not find entry for ") + bun->text_form());
00192 #endif
00193 return NOT_FOUND;
00194 }
00195 break;
00196 }
00197 default: return NO_HANDLER;
00198 }
00199 return OKAY;
00200 }
00201
00202 void list_manager::expunge(const octopus_entity &formal(to_remove))
00203 {
00204
00205 }
00206
00207 }
00208