feisty meow concerns codebase 2.140
list_manager.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : list_manager *
4* Author : Chris Koeritz *
5* *
6*******************************************************************************
7* Copyright (c) 2002-$now By Author. This program is free software; you can *
8* redistribute it and/or modify it under the terms of the GNU General Public *
9* License as published by the Free Software Foundation; either version 2 of *
10* the License or (at your option) any later version. This is online at: *
11* http://www.fsf.org/copyleft/gpl.html *
12* Please send any updates to: fred@gruntose.com *
13\*****************************************************************************/
14
15#include "bundle_list.h"
16#include "list_manager.h"
17
18#include <basis/astring.h>
19#include <basis/functions.h>
20#include <basis/mutex.h>
22
23using namespace basis;
24using namespace octopi;
25using namespace structures;
26using namespace timely;
27
28namespace synchronic {
29
30//#define DEBUG_LIST_MANAGER
31 // uncomment for noisier version.
32
33#undef GRAB_LOCK
34#define GRAB_LOCK \
35 auto_synchronizer l(*_locking)
36
37#undef LOG
38#define LOG(to_print) \
39 CLASS_EMERGENCY_LOG(program_wide_logger::get(), to_print)
40
41list_manager::list_manager(const string_array &list_name, bool backgrounded)
42: tentacle(list_name, backgrounded),
43 _entries(new bundle_list),
44 _locking(new mutex)
45{
46}
47
49{
50 WHACK(_entries);
51 WHACK(_locking);
52}
53
54const string_array &list_manager::list_name() const { return group(); }
55
57{
59 return _entries->elements();
60}
61
63{
65 _entries->zap(0, _entries->elements() - 1);
66}
67
69{
71 int indy = locked_find(classifier);
72 return !negative(indy);
73}
74
75bool list_manager::update(const string_array &classifier, int offset)
76{
78 int indy = locked_find(classifier);
79 if (negative(indy)) return false; // not found.
80 _entries->borrow(indy)->_updated = time_stamp(offset);
81 return true;
82}
83
84void list_manager::clean(int older_than)
85{
87 for (int i = 0; i < _entries->elements(); i++) {
88 synchronizable *curr = _entries->borrow(i);
89 if (curr->_updated < time_stamp(-older_than)) {
90 // this one is too old to keep around.
91 _entries->zap(i, i);
92 i--; // skip back before deleted item.
93 }
94 }
95}
96
97bool list_manager::zap(const string_array &classifier)
98{
100 int indy = locked_find(classifier);
101 if (negative(indy)) return false; // not found.
102 _entries->zap(indy, indy);
103 return true; // did find and whack it.
104}
105
106int list_manager::locked_find(const string_array &classifier)
107{
108 for (int i = 0; i < _entries->elements(); i++) {
109 // check that the classifier lengths are equal; otherwise no match.
110 if (_entries->get(i)->classifier().length() != classifier.length())
111 continue;
112 // starting from the end of most significance, we compare the strings.
113 // we don't want to bother comparing the end that's most likely to be
114 // the same for items in the list (the front, that is).
115 bool problems = false;
116 for (int j = classifier.length() - 1; j >= 0; j--) {
117 if (_entries->get(i)->classifier()[j] != classifier[j]) {
118 problems = true;
119 break; // get out now since we're hosed.
120 }
121 }
122 if (problems) continue; // nope, there was a mismatch.
123 // success; this guy matches.
124 return i;
125 }
126 return common::NOT_FOUND; // not found.
127}
128
130{
131 GRAB_LOCK;
132 int indy = locked_find(classifier);
133 if (negative(indy)) return NULL_POINTER;
134 return dynamic_cast<synchronizable *>(_entries->get(indy)->clone());
135}
136
138{
139 to_fill.reset();
140 GRAB_LOCK;
141 for (int i = 0; i < _entries->elements(); i++)
142 to_fill += dynamic_cast<synchronizable *>(_entries->get(i)->clone());
143}
144
146 const octopus_request_id &formal(item_id), byte_array &transformed)
147{
148#ifdef DEBUG_LIST_MANAGER
149 FUNCDEF("consume");
150#endif
151 transformed.reset();
152 synchronizable *bun = dynamic_cast<synchronizable *>(&to_chow);
153 if (!bun) return BAD_INPUT;
154
155 GRAB_LOCK;
156
157 // now perform an appropriate action depending on the type of update.
158 switch (bun->_mod) {
161 // see if the item already exists; if it does, overwrite it.
162 int indy = locked_find(bun->classifier());
163 if (negative(indy)) {
164 // the item is new, so just drop it in the list.
165 *_entries += dynamic_cast<synchronizable *>(bun->clone());
166 } else {
167 // not a new item, so merge with the existing contents.
168 _entries->borrow(indy)->merge(*bun);
169 _entries->borrow(indy)->_updated = time_stamp();
170 }
171 return OKAY;
172 }
174 int indy = locked_find(bun->classifier());
175 if (non_negative(indy)) {
176 // found it, so whack the entry as needed by calling merge.
177 outcome ret = _entries->borrow(indy)->merge(*bun);
178 _entries->borrow(indy)->_updated = time_stamp();
179 if (ret == synchronizable::EMPTY) {
180 // they have told us that this must go now.
181#ifdef DEBUG_LIST_MANAGER
182 LOG(astring("removing entry now due to merge outcome: ")
183 + _entries->borrow(indy)->text_form());
184#endif
185 _entries->zap(indy, indy);
186 }
187 return OKAY;
188 } else {
189 // that item was not listed.
190#ifdef DEBUG_LIST_MANAGER
191 LOG(astring("could not find entry for ") + bun->text_form());
192#endif
193 return NOT_FOUND;
194 }
195 break;
196 }
197 default: return NO_HANDLER;
198 }
199 return OKAY;
200}
201
203{
204 FUNCDEF("expunge");
205}
206
207} //namespace.
208
#define LOG(s)
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition array.h:349
int length() const
Returns the current reported length of the allocated C array.
Definition array.h:115
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A very common template for a dynamic array of bytes.
Definition byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition outcome.h:31
An infoton is an individual request parcel with accompanying information.
Definition infoton.h:32
const structures::string_array & classifier() const
this array of strings is the "name" for this infoton.
Definition infoton.cpp:85
Provides a way of identifying users of an octopus object.
Definition entity_defs.h:35
Identifies requests made on an octopus by users.
Manages a service within an octopus by processing certain infotons.
Definition tentacle.h:36
const structures::string_array & group() const
returns the name of the group that this tentacle services.
Definition tentacle.cpp:96
@ NO_HANDLER
no handler for that type of infoton.
Definition tentacle.h:73
int elements() const
the maximum number of elements currently allowed in this amorph.
Definition amorph.h:66
basis::outcome zap(int start, int end)
Removes a range of indices from the amorph.
Definition amorph.h:357
void reset()
cleans out all of the contents.
Definition amorph.h:81
const contents * get(int field) const
Returns a constant pointer to the information at the index "field".
Definition amorph.h:312
contents * borrow(int field)
Returns a pointer to the information at the index "field".
Definition amorph.h:448
An array of strings with some additional helpful methods.
Provides a structure for managing a collection of synchronizables.
Definition bundle_list.h:26
bool zap(const structures::string_array &classifier)
void retrieve(bundle_list &to_fill) const
list_manager(const structures::string_array &list_name, bool backgrounded)
bool update(const structures::string_array &classifier, int offset=0)
virtual void expunge(const octopi::octopus_entity &to_remove)
called to remove traces of the entity "to_remove".
void clean(int older_than)
bool is_listed(const structures::string_array &classifier)
virtual basis::outcome consume(octopi::infoton &to_chow, const octopi::octopus_request_id &item_id, basis::byte_array &transformed)
this is the main function that processes infotons for this tentacle.
const structures::string_array & list_name() const
synchronizable * clone_object(const structures::string_array &classifier)
Encapsulates all of the attributes known for an object.
virtual clonable * clone() const =0
must be provided to allow creation of a copy of this object.
virtual basis::astring text_form() const =0
local version just makes text_form() more functional.
timely::time_stamp _updated
Represents a point in time relative to the operating system startup time.
Definition time_stamp.h:38
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
Definition definitions.h:48
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
#define GRAB_LOCK
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition functions.h:121
bool non_negative(const type &a)
non_negative returns true if "a" is greater than or equal to zero.
Definition functions.h:45
bool negative(const type &a)
negative returns true if "a" is less than zero.
Definition functions.h:43
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55
#include <time.h>