1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
11 #include <anna/core/core.hpp>
12 #include <anna/app/app.hpp>
14 #include <anna/io/Directory.hpp>
15 #include <anna/io/functions.hpp>
17 #include <anna/xml/Compiler.hpp>
18 #include <anna/xml/Node.hpp>
20 #include <anna/dbos/Repository.hpp>
21 #include <anna/dbos/AutoObject.hpp>
23 #include "filesystem/Directory.hpp"
24 #include "filesystem/File.hpp"
26 #include "storage/Directory.hpp"
27 #include "storage/File.hpp"
30 using namespace workdir;
32 template <typename T> void message (const char* text, T* tt) {
33 if (Logger::isActive (Logger::Debug) == false)
36 cout << " " << text << " (";
37 cout << anna::functions::asHexString (anna_ptrnumber_cast (tt));
41 cout << tt->asString ();
48 class WorkDirectory : public Application {
50 struct Flags { enum _v { None = 0, Clear = 1 }; };
54 xml::Node* asXML (xml::Node* parent) const ;
57 typedef vector <storage::File*> file_container;
58 typedef file_container::iterator file_iterator;
59 typedef file_container::reverse_iterator file_reverse_iterator;
61 dbos::Repository a_repository;
62 filesystem::Directory* a_root;
63 file_container a_files;
65 void initialize () noexcept(false);
66 void run () noexcept(false);
68 void forward (filesystem::Directory*) noexcept(false);
69 void instantiateOne (filesystem::Directory*) noexcept(false);
70 void fullCache (filesystem::Directory*, file_container&, const int flags) noexcept(false);
71 void reuseHoles (filesystem::Directory*, file_container&) noexcept(false);
72 void destroyObjects (filesystem::Directory* dir, file_container&) noexcept(false);
73 void clear (file_container&) ;
75 static void load (filesystem::Directory* parent, const int maxLevel, const int level = 0) noexcept(false);
80 int main (int argc, const char** argv)
82 CommandLine& commandLine (CommandLine::instantiate ());
83 WorkDirectory storageNull;
86 commandLine.initialize (argv, argc);
87 commandLine.verify ();
89 Logger::setLevel (Logger::Local6);
90 Logger::initialize ("workdir", new TraceWriter ("file.trace", 4 * 1024 * 1024));
94 catch (Exception& ex) {
95 cout << ex.asString () << endl;
101 WorkDirectory::WorkDirectory () :
102 Application ("workdir", "Dbos workdir", "1.0.0"),
103 a_repository ("workdir")
105 CommandLine& cl (CommandLine::instantiate ());
107 cl.add ("dir", CommandLine::Argument::Mandatory, "Nombre del directorio a procesar");
108 cl.add ("l", CommandLine::Argument::Optional, "Numero maximo de niveles de profundidad");
109 cl.add ("trace", CommandLine::Argument::Optional, "Nivel de trazado");
110 cl.add ("s", CommandLine::Argument::Mandatory, "Cache size");
113 void WorkDirectory::initialize ()
118 void WorkDirectory::run ()
121 LOGMETHOD (TraceMethod tm ("WorkDirectory", "run", ANNA_FILE_LOCATION));
123 CommandLine& cl (CommandLine::instantiate ());
125 const std::string& dir = cl.getValue ("dir");
126 const int maxLevel = cl.exists ("l") ? cl.getIntegerValue ("l"): -1;
128 if (cl.exists ("trace") == true)
129 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
131 const int cacheSize = cl.getIntegerValue ("s");
133 storage::Directory::setup (a_repository, cacheSize);
134 storage::File::setup (a_repository, cacheSize);
136 a_root = new filesystem::Directory (dir);
138 load (a_root, maxLevel);
145 writeContext ("file.context");
148 xml::Node* WorkDirectory::asXML (xml::Node* parent) const
151 xml::Node* result = app::Application::asXML (parent);
152 a_repository.asXML (result);
156 void WorkDirectory::forward (filesystem::Directory* dir)
159 cout << "forward: " << dir->getPath () << endl;
161 for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
162 dir = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
168 instantiateOne (dir);
169 fullCache (dir, a_files, Flags::Clear);
170 reuseHoles (dir, a_files);
171 destroyObjects (dir, a_files);
174 catch (RuntimeException& ex) {
181 * Crea una serie de instancia simultáneas sobre el mismo objeto para verificar que sólo lo carga
182 * de verdad sea necesario.
184 void WorkDirectory::instantiateOne (filesystem::Directory* dir)
187 TraceMethod tm ("WorkDirectory", "instantiateOne", ANNA_FILE_LOCATION);
189 cout << "WorkDirectory::instantiateOne: Instancia varias veces la misma instancia para verificar el reuso" << endl;
191 storage::Directory* aux;
194 dbos::AutoObject <storage::Directory> root1;
195 aux = root1 = storage::Directory::instantiate (dir);
196 message ("Root1", aux);
198 dbos::AutoObject <storage::Directory> root2;
199 aux = root2 = storage::Directory::instantiate (dir);
200 message ("Root2", aux);
203 dbos::AutoObject <storage::Directory> root3;
204 aux = root3 = storage::Directory::instantiate (dir);
205 message ("Root3", aux);
207 message ("StorageArea", storage::File::getStorageArea ());
212 void WorkDirectory::fullCache (filesystem::Directory* dir, WorkDirectory::file_container& files, const int flags)
215 TraceMethod tm ("WorkDirectory", "fullCache", ANNA_FILE_LOCATION);
217 cout << "WorkDirectory::fullCache: Llena la cache de objetos para verificar que crece tanto como sea necesario" << endl;
219 filesystem::File* file;
221 int maxSize = storage::File::getMaxSize ();
223 maxSize += rand () % maxSize;
225 for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
226 file = filesystem::File::down_cast (filesystem::Directory::child (ii));
229 storage::File* storageFile = storage::File::instantiate (file);
230 message ("File", storageFile);
231 files.push_back (storageFile);
233 // if (files.size () >= maxSize)
238 message ("StorageArea (full)", storage::File::getStorageArea ());
240 if (flags & Flags::Clear)
243 message ("StorageArea (empty)", storage::File::getStorageArea ());
248 void WorkDirectory::reuseHoles (filesystem::Directory* dir, WorkDirectory::file_container& files)
251 TraceMethod tm ("WorkDirectory", "reuseHoles", ANNA_FILE_LOCATION);
253 cout << "WorkDirectory::reuseHoles: Invoca dos veces a fullCache para verificar que el tamano se mantiene la segunda vez" << endl;
254 fullCache (dir, files, Flags::Clear);
255 fullCache (dir, files, Flags::Clear);
259 void WorkDirectory::destroyObjects (filesystem::Directory* dir, WorkDirectory::file_container& files)
262 TraceMethod tm ("WorkDirectory", "destroyObjects", ANNA_FILE_LOCATION);
264 cout << "WorkDirectory::destroyObjects: Carga un directorio distinto, para verificar que destruye los objetos segun se dejan de utilizar" << endl;
265 filesystem::File* file;
266 filesystem::Directory* other = NULL;
268 for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii && other == NULL; ii ++)
269 other = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
272 cout << dir->getPath () << ": No se puede realizar esta prueba" << endl << endl;
276 cout << "New Directory: " << other->getPath () << endl;
279 for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
280 file = filesystem::File::down_cast (filesystem::Directory::child (ii));
283 storage::File* storageFile = storage::File::instantiate (file);
284 message ("File", storageFile);
285 storage::File::release (storageFile);
289 message ("StorageArea", storage::File::getStorageArea ());
295 void WorkDirectory::clear (WorkDirectory::file_container& files)
300 /* Libera los objetos en distinto orden para empeorar el tratamiento huecos */
302 if ((anna::functions::millisecond () % 2) == 0) {
303 cout << "Clear directo" << endl;
304 for (file_iterator ii = files.begin (), maxii = files.end (); ii != maxii; ii ++) {
306 storage::File::release (file);
310 cout << "Clear inverso" << endl;
311 for (file_reverse_iterator ii = files.rbegin (), maxii = files.rend (); ii != maxii; ii ++) {
313 storage::File::release (file);
321 void WorkDirectory::load (filesystem::Directory* parent, const int maxLevel, const int level)
324 if (level == maxLevel)
327 io::Directory directory;
330 directory.read (parent->getPath (), io::Directory::Mode::ShortPath);
332 for (io::Directory::const_iterator ii = directory.begin (), maxii = directory.end (); ii != maxii; ii ++) {
333 const std::string& name = io::Directory::data (ii);
335 fullPath = filesystem::Abstract::calculePath (parent, name);
337 if (io::functions::isADirectory (fullPath)) {
339 filesystem::Directory* dd = new filesystem::Directory (parent, name);
340 load (dd, maxLevel, level + 1);
342 catch (RuntimeException& ex) {
347 //Auto association to the parent:
348 new filesystem::File (parent, name);