Revert "Remove mysql and oracle resources for anna-ericsson project"
[anna.git] / example / dbos / workdir / main.cpp
diff --git a/example/dbos/workdir/main.cpp b/example/dbos/workdir/main.cpp
new file mode 100644 (file)
index 0000000..3b9c99f
--- /dev/null
@@ -0,0 +1,351 @@
+// ANNA - Anna is Not Nothingness Anymore                                                         //
+//                                                                                                //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
+//                                                                                                //
+// See project site at http://redmine.teslayout.com/projects/anna-suite                           //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#include <iostream>
+
+#include <anna/core/core.hpp>
+#include <anna/app/app.hpp>
+
+#include <anna/io/Directory.hpp>
+#include <anna/io/functions.hpp>
+
+#include <anna/xml/Compiler.hpp>
+#include <anna/xml/Node.hpp>
+
+#include <anna/dbos/Repository.hpp>
+#include <anna/dbos/AutoObject.hpp>
+
+#include "filesystem/Directory.hpp"
+#include "filesystem/File.hpp"
+
+#include "storage/Directory.hpp"
+#include "storage/File.hpp"
+
+using namespace std;
+using namespace workdir;
+
+template <typename T> void message (const char* text, T* tt) throw () {
+   if (Logger::isActive (Logger::Debug) == false)
+      return;
+
+   cout << "   " << text << " (";
+   cout << anna::functions::asHexString (anna_ptrnumber_cast (tt)); 
+   cout << "): ";
+   
+   if (tt != NULL)
+      cout << tt->asString ();
+   else
+      cout << "<null>";
+   
+   cout << endl;
+}
+
+class WorkDirectory : public Application {
+public:
+   struct Flags { enum _v { None = 0, Clear = 1 }; };
+   
+   WorkDirectory ();
+
+   xml::Node* asXML (xml::Node* parent) const throw ();
+   
+private:
+   typedef vector <storage::File*> file_container;
+   typedef file_container::iterator file_iterator;
+   typedef file_container::reverse_iterator file_reverse_iterator;
+   
+   dbos::Repository a_repository;
+   filesystem::Directory* a_root;
+   file_container a_files;
+
+   void initialize () throw (RuntimeException); 
+   void run () throw (RuntimeException);
+   
+   void forward (filesystem::Directory*) throw (RuntimeException);
+   void instantiateOne (filesystem::Directory*) throw (RuntimeException);   
+   void fullCache (filesystem::Directory*, file_container&, const int flags) throw (RuntimeException);   
+   void reuseHoles (filesystem::Directory*, file_container&) throw (RuntimeException);
+   void destroyObjects (filesystem::Directory* dir, file_container&) throw (RuntimeException);
+   void clear (file_container&) throw ();
+   
+   static void load (filesystem::Directory* parent, const int maxLevel, const int level = 0) throw (RuntimeException);
+};
+
+using namespace std;
+
+int main (int argc, const char** argv)
+{
+   CommandLine& commandLine (CommandLine::instantiate ());
+   WorkDirectory storageNull;
+
+   try {
+      commandLine.initialize (argv, argc);
+      commandLine.verify ();
+
+      Logger::setLevel (Logger::Local6); 
+      Logger::initialize ("workdir", new TraceWriter ("file.trace", 4 * 1024 * 1024));
+      storageNull.start ();
+   }
+   catch (Exception& ex) {
+      cout << ex.asString () << endl;
+   }
+   
+   return 0;
+}
+
+WorkDirectory::WorkDirectory () : 
+   Application ("workdir", "Dbos workdir", "1.0.0"),
+   a_repository ("workdir")
+{
+   CommandLine& cl (CommandLine::instantiate ());
+      
+   cl.add ("dir", CommandLine::Argument::Mandatory, "Nombre del directorio a procesar");
+   cl.add ("l", CommandLine::Argument::Optional, "Numero maximo de niveles de profundidad");
+   cl.add ("trace", CommandLine::Argument::Optional, "Nivel de trazado");
+   cl.add ("s", CommandLine::Argument::Mandatory, "Cache size");
+}
+
+void WorkDirectory::initialize ()
+   throw (RuntimeException)
+{
+}
+
+void WorkDirectory::run () 
+   throw (RuntimeException)
+{
+   LOGMETHOD (TraceMethod tm ("WorkDirectory", "run", ANNA_FILE_LOCATION)); 
+
+   CommandLine& cl (CommandLine::instantiate ());  
+
+   const std::string& dir = cl.getValue ("dir");
+   const int maxLevel = cl.exists ("l") ? cl.getIntegerValue ("l"): -1; 
+
+   if (cl.exists ("trace") == true) 
+      Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
+
+   const int cacheSize = cl.getIntegerValue ("s");
+   
+   storage::Directory::setup (a_repository, cacheSize);
+   storage::File::setup (a_repository, cacheSize);
+   
+   a_root = new filesystem::Directory (dir);
+   
+   load (a_root, maxLevel);
+   
+   a_root->print ();
+   cout << endl;
+
+   forward (a_root);
+      
+   writeContext ("file.context");
+}  
+
+xml::Node* WorkDirectory::asXML (xml::Node* parent) const
+   throw ()
+{
+   xml::Node* result = app::Application::asXML (parent);
+   a_repository.asXML (result);
+   return result;
+}
+
+void WorkDirectory::forward (filesystem::Directory* dir)
+   throw (RuntimeException)
+{
+   cout << "forward: " << dir->getPath () << endl;
+   
+   for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
+      dir = filesystem::Directory::down_cast (filesystem::Directory::child (ii));
+      
+      if (dir == NULL) 
+         continue;
+     
+      try { 
+         instantiateOne (dir);
+         fullCache (dir, a_files, Flags::Clear);
+         reuseHoles (dir, a_files);
+         destroyObjects (dir, a_files);
+         forward (dir);      
+      }
+      catch (RuntimeException& ex) {
+         ex.trace ();
+      }
+   }   
+}
+
+/*
+ * Crea una serie de instancia simultáneas sobre el mismo objeto para verificar que sólo lo carga 
+ * de verdad sea necesario.
+ */ 
+void WorkDirectory::instantiateOne (filesystem::Directory* dir) 
+   throw (RuntimeException)
+{
+   TraceMethod tm ("WorkDirectory", "instantiateOne", ANNA_FILE_LOCATION);
+   
+   cout << "WorkDirectory::instantiateOne: Instancia varias veces la misma instancia para verificar el reuso" << endl;
+   
+   storage::Directory* aux;
+
+   {
+      dbos::AutoObject <storage::Directory> root1;   
+      aux = root1 = storage::Directory::instantiate (dir);
+      message ("Root1", aux);
+      
+      dbos::AutoObject <storage::Directory> root2;   
+      aux = root2 = storage::Directory::instantiate (dir);
+      message ("Root2", aux);
+   }
+   
+   dbos::AutoObject <storage::Directory> root3;   
+   aux = root3 = storage::Directory::instantiate (dir);
+   message ("Root3", aux);
+
+   message ("StorageArea", storage::File::getStorageArea ());
+
+   cout << endl;
+}
+
+void WorkDirectory::fullCache (filesystem::Directory* dir, WorkDirectory::file_container& files, const int flags) 
+   throw (RuntimeException)
+{
+   TraceMethod tm ("WorkDirectory", "fullCache", ANNA_FILE_LOCATION);
+   
+   cout << "WorkDirectory::fullCache: Llena la cache de objetos para verificar que crece tanto como sea necesario" << endl;
+
+   filesystem::File* file;
+   
+   int maxSize = storage::File::getMaxSize ();
+   
+   maxSize += rand () % maxSize;
+   
+   for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
+      file = filesystem::File::down_cast (filesystem::Directory::child (ii));
+      
+      if (file != NULL) {
+         storage::File* storageFile = storage::File::instantiate (file);
+         message ("File", storageFile);
+         files.push_back (storageFile);
+         
+//         if (files.size () >= maxSize)
+//            break;
+      }
+   }
+     
+   message ("StorageArea (full)", storage::File::getStorageArea ());
+
+   if (flags & Flags::Clear)
+      clear (files);
+   
+   message ("StorageArea (empty)", storage::File::getStorageArea ());
+   
+   cout << endl;
+}
+
+void WorkDirectory::reuseHoles (filesystem::Directory* dir, WorkDirectory::file_container& files)
+   throw (RuntimeException)
+{
+   TraceMethod tm ("WorkDirectory", "reuseHoles", ANNA_FILE_LOCATION);
+   
+   cout << "WorkDirectory::reuseHoles: Invoca dos veces a fullCache para verificar que el tamano se mantiene la segunda vez" << endl;   
+   fullCache (dir, files, Flags::Clear);
+   fullCache (dir, files, Flags::Clear);      
+   cout << endl;
+}
+
+void WorkDirectory::destroyObjects (filesystem::Directory* dir, WorkDirectory::file_container& files)
+   throw (RuntimeException)
+{
+   TraceMethod tm ("WorkDirectory", "destroyObjects", ANNA_FILE_LOCATION);
+   
+   cout << "WorkDirectory::destroyObjects: Carga un directorio distinto, para verificar que destruye los objetos segun se dejan de utilizar" << endl;   
+   filesystem::File* file;
+   filesystem::Directory* other = NULL;
+   
+   for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii && other == NULL; ii ++) 
+      other = filesystem::Directory::down_cast (filesystem::Directory::child (ii));    
+         
+   if (other == NULL) {
+      cout << dir->getPath () << ": No se puede realizar esta prueba" << endl << endl;
+      return;
+   }
+   
+   cout << "New Directory: " << other->getPath () << endl;   
+   dir = other;
+   
+   for (filesystem::Directory::child_iterator ii = dir->child_begin (), maxii = dir->child_end (); ii != maxii; ii ++) {
+      file = filesystem::File::down_cast (filesystem::Directory::child (ii));
+      
+      if (file != NULL) {
+         storage::File* storageFile = storage::File::instantiate (file);
+         message ("File", storageFile);
+         storage::File::release (storageFile);         
+      }
+   }
+   
+   message ("StorageArea", storage::File::getStorageArea ());
+   
+   cout << endl;
+}
+
+
+void WorkDirectory::clear (WorkDirectory::file_container& files)
+   throw ()
+{
+   storage::File* file;
+   
+   /* Libera los objetos en distinto orden para empeorar el tratamiento huecos */
+
+   if ((anna::functions::millisecond () % 2) == 0) {
+      cout << "Clear directo" << endl;
+      for (file_iterator ii = files.begin (), maxii = files.end (); ii != maxii; ii ++) {
+         file = *ii;
+         storage::File::release (file);
+      }      
+   }
+   else {
+      cout << "Clear inverso" << endl;
+      for (file_reverse_iterator ii = files.rbegin (), maxii = files.rend (); ii != maxii; ii ++) {
+         file = *ii;
+         storage::File::release (file);
+      }            
+   }
+   
+   files.clear ();
+}
+
+/*static*/
+void WorkDirectory::load (filesystem::Directory* parent, const int maxLevel, const int level) 
+   throw (RuntimeException)
+{
+   if (level == maxLevel)
+      return;
+   
+   io::Directory directory;
+   string fullPath;
+   
+   directory.read (parent->getPath (), io::Directory::Mode::ShortPath);
+   
+   for (io::Directory::const_iterator ii = directory.begin (), maxii = directory.end (); ii != maxii; ii ++) { 
+      const std::string& name = io::Directory::data (ii);
+      
+      fullPath = filesystem::Abstract::calculePath (parent, name);
+      
+      if (io::functions::isADirectory (fullPath)) {
+         try {
+            filesystem::Directory* dd = new filesystem::Directory (parent, name);
+            load (dd, maxLevel, level + 1);
+         }
+         catch (RuntimeException& ex) {
+            ex.trace ();
+         }
+      }
+      else {
+         //Auto association to the parent: 
+         new filesystem::File (parent, name);         
+      }
+   }      
+}