MASA-Core
SpecialRowsArea.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2010-2015   Edans Sandes
00004  *
00005  * This file is part of MASA-Core.
00006  * 
00007  * MASA-Core is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  * 
00012  * MASA-Core is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with MASA-Core.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  ******************************************************************************/
00021 
00022 #include "SpecialRowsArea.hpp"
00023 
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <algorithm>
00027 
00028 #include <dirent.h>
00029 #include <sys/stat.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 
00033 #include "../io/SplitCellsReader.hpp"
00034 #include "../io/InitialCellsReader.hpp"
00035 
00036 #define DEBUG (0)
00037 
00038 SpecialRowsArea::SpecialRowsArea(string directory, long long ram_limit, long long disk_limit, const score_params_t* score_params) {
00039         this->directory = directory;
00040         this->ram_limit = ram_limit;
00041         this->disk_limit = disk_limit;
00042         //printf("SpecialRowsArea::SpecialRowsArea   directory: %s\n", directory.c_str());
00043         this->partitions.clear();
00044         this->rowsCount = 0;
00045         this->score_params = score_params;
00046         this->persistentPartitions = true;//(ram_limit+disk_limit) > 0; // FIXME or TODO
00047 }
00048 
00049 SpecialRowsArea::~SpecialRowsArea() {
00050         for (map<string, SpecialRowsPartition*>::const_iterator i = partitions.begin(); i != partitions.end(); i++) {
00051                 delete i->second;
00052         }
00053         partitions.clear();
00054 }
00055 
00056 SpecialRowsPartition* SpecialRowsArea::createPartition(int i0, int j0, int i1, int j1) {
00057         string path = getPartitionPath(i0, j0, i1, j1);
00058         SpecialRowsPartition* partition = new SpecialRowsPartition(path, i0, j0, i1, j1, false, score_params);
00059         partition->setRamProportion(ram_limit, disk_limit);
00060 
00061         partitions[path] = partition;
00062         return partition;
00063 }
00064 
00065 SpecialRowsPartition* SpecialRowsArea::openPartition(int i0, int j0, int i1, int j1) {
00066         string path = getPartitionPath(i0, j0, i1, j1);
00067         if (partitions[path] == NULL) {
00068                 SpecialRowsPartition* partition = new SpecialRowsPartition(path, i0, j0, i1, j1, true, score_params);
00069                 partitions[path] = partition;
00070                 return partition;
00071         } else {
00072                 partitions[path]->reload();
00073         }
00074 
00075         //printf("SpecialRowsArea::openPartition   path: %s  %p\n", path.c_str(), partitions[path]);
00076         return partitions[path];
00077 }
00078 
00079 void SpecialRowsArea::truncatePartition(SpecialRowsPartition* partition, int max_i, int max_j) {
00080         partition->truncate(max_i, max_j);
00081 
00082         string old_path = partition->getPath();
00083         string new_path = getPartitionPath(partition->getI0(), partition->getJ0(), max_i, max_j);
00084         partition->changePath(new_path);
00085 
00086         partitions.erase(old_path);
00087         partitions[new_path] = partition;
00088 
00089         rowsCount += partition->getRowsCount();
00090         /*for (map<string, SpecialRowsPartition*>::const_iterator i = partitions.begin(); i != partitions.end(); i++) {
00091                 printf("+map %s->%p\n", i->first.c_str(), i->second);
00092         }*/
00093 }
00094 
00095 int SpecialRowsArea::getRowsCount() const {
00096         if (!persistentPartitions) {
00097                 return 0;
00098         }
00099         // Only works for newly created areas.
00100         return rowsCount;
00101 }
00102 
00103 int SpecialRowsArea::getPartitionsCount() const {
00104         // Only works for newly created areas.
00105         return partitions.size();
00106 }
00107 
00108 const string& SpecialRowsArea::getDirectory() const {
00109         return directory;
00110 }
00111 
00112 void SpecialRowsArea::setPersistentPartitions(bool persistent) {
00113         this->persistentPartitions = persistent;
00114 }
00115 
00116 SpecialRowsPartition* SpecialRowsArea::openPartition(int i, int j) {
00117         DIR *dir = NULL;
00118         //printf("Opening Dir: %s\n", path.c_str());
00119         dir = opendir (directory.c_str());
00120         struct dirent *dp;          /* returned from readdir() */
00121 
00122         if (dir == NULL) {
00123                 fprintf(stderr, "Could not open special rows directory: %s\n", directory.c_str());
00124                 exit(1);
00125         }
00126 
00127         while ((dp = readdir (dir)) != NULL) {
00128                 int i0;
00129                 int j0;
00130                 int i1;
00131                 int j1;
00132                 if (sscanf(dp->d_name, "%08X.%08X.%08X.%08X", &i0, &j0, &i1, &j1) == 4) {
00133                         if (i0 < i && i <= i1 && j0 < j && j <= j1) {
00134                                 closedir (dir);
00135                                 if (DEBUG) printf("DEBUG: OPEN >>>>>> %s (%d,%d,%d,%d)\n", dp->d_name, i0, j0, i1, j1);
00136                                 return openPartition(i0, j0, i1, j1);
00137                         }
00138                 }
00139                 if (DEBUG) printf("%d %d %d %d\n", i0, j0, i1, j1);
00140         }
00141         closedir (dir);
00142 
00143         return NULL;
00144 }
00145 
00146 void SpecialRowsArea::createSplittedPartitions(int i0, int j0, int i1, int j1, int ni, int nj, SeekableCellsReader* firstRow, SeekableCellsReader* firstColumn, CellsWriter* lastRow, CellsWriter* lastColumn) {
00147 //      SeekableCellsReader* firstRow = partition->getFirstRowReader();
00148 //      SeekableCellsReader* firstColumn = partition->getFirstColumnReader();
00149 //      CellsWriter* lastRow = partition->getLastRowWriter();
00150 //      CellsWriter* lastColumn = partition->getLastColumnWriter();
00151 
00152         long long int h = (i1 - i0);
00153         long long int w = (j1 - j0);
00154 
00155         SpecialRowsPartition*** p = new SpecialRowsPartition**[ni];
00156         for (int pi=0; pi<ni; pi++) {
00157                 p[pi] = new SpecialRowsPartition*[nj];
00158                 for (int pj=0; pj<nj; pj++) {
00159 
00160                         int pi0 = (int)(((long long int)i0) + h*pi/ni);
00161                         int pj0 = (int)(((long long int)j0) + w*pj/nj);
00162                         int pi1 = (int)(((long long int)i0) + h*(pi+1)/ni);
00163                         int pj1 = (int)(((long long int)j0) + w*(pj+1)/nj);
00164                         printf(">>>>>>>>>> %d %d %d %d   %d\n", pi0, pj0, pi1, pj1, firstRow->getOffset());
00165 
00166                         p[pi][pj] = createPartition(pi0, pj0, pi1, pj1);
00167                         if (pi == ni-1) {
00168                                 p[pi][pj]->setLastRowWriter(lastRow);
00169                         }
00170                         if (pj == nj-1) {
00171                                 p[pi][pj]->setLastColumnWriter(lastColumn);
00172                         }
00173 
00174                         if (pi == 0 && pj == 0) {
00175                                 p[pi][pj]->setFirstColumnReader(firstColumn);
00176                                 p[pi][pj]->setFirstRowReader(firstRow);
00177                         } else {
00178                                 if (pi == 0) {
00179                                         if (firstRow != NULL && (firstRow->getType() != INIT_WITH_CUSTOM_DATA)) {
00180                                                 p[pi][pj]->setFirstRowReader(((InitialCellsReader*)firstRow)->clone(pj0-j0));
00181                                         } else {
00182                                                 p[pi][pj]->setFirstRowReader(firstRow);
00183                                         }
00184                                 }
00185                                 if (pj == 0) {
00186                                         if (firstColumn != NULL && (firstColumn->getType() != INIT_WITH_CUSTOM_DATA)) {
00187                                                 p[pi][pj]->setFirstColumnReader(((InitialCellsReader*)firstColumn)->clone(pi0-i0));
00188                                         } else {
00189                                                 p[pi][pj]->setFirstColumnReader(firstColumn);
00190                                         }
00191                                 }
00192 //                              if (pi == 0 && firstRow != NULL) {
00193 //                                      p[pi][pj]->setFirstRowReader(new SplitCellsReader(firstRow, pj0, pj==nj-1));
00194 //                              }
00195 //                              if (pj == 0 && firstColumn != NULL) {
00196 //                                      p[pi][pj]->setFirstColumnReader(new SplitCellsReader(firstColumn, pi0, pi==ni-1));
00197 //                              }
00198                         }
00199                         if (pi != 0) {
00200                                 p[pi-1][pj]->createChain(p[pi][pj]);
00201                         }
00202                         if (pj != 0) {
00203                                 p[pi][pj-1]->createChain(p[pi][pj]);
00204                         }
00205                 }
00206         }
00207 }
00208 
00209 string SpecialRowsArea::getPartitionPath(int i0, int j0, int i1, int j1) {
00210         if (!persistentPartitions) {
00211                 return "";
00212         }
00213         char str[500];
00214         sprintf(str, "%s/%08X.%08X.%08X.%08X", directory.c_str(), i0, j0, i1, j1);
00215         return string(str);
00216 }
00217 
00218 
00219 static bool sort_f(const SpecialRowsPartition* a, const SpecialRowsPartition* b) {
00220         int deltaI = a->getI0() - b->getI0();
00221         int deltaJ = a->getJ0() - b->getJ0();
00222         if (deltaI == 0) {
00223                 return deltaJ < 0;
00224         } else {
00225                 return deltaI < 0;
00226         }
00227 }
00228 
00229 vector<SpecialRowsPartition*> SpecialRowsArea::getSortedPartitions() {
00230         vector<SpecialRowsPartition*> sortedPartitions;
00231         for (map<string, SpecialRowsPartition*>::iterator it = partitions.begin(); it != partitions.end(); ++it) {
00232                 sortedPartitions.push_back(it->second);
00233         }
00234         std::sort (sortedPartitions.begin(), sortedPartitions.end(), sort_f);
00235         vector<int> openY;
00236         return sortedPartitions;
00237 }
00238 
00239