/* Copyright (C) 2014 Carlos Aguilar Melchor, Joris Barrier, Marc-Olivier Killijian * This file is part of XPIR. * * XPIR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * XPIR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XPIR. If not, see . */ #include "DBDirectoryProcessor.hpp" /************************************************/ /* Default constructor : no splitting */ /* -> 1 input file -> 1 output stream */ /************************************************/ DBDirectoryProcessor::DBDirectoryProcessor() : filesSplitting(false) { // TODO(feature) deal with sub-directories in the database ! directory=std::string(DEFAULT_DIR_NAME); maxFileBytesize=0; // Then create the catalog and get the filenumbers and size DIR *dir = opendir (directory.c_str()); struct dirent *ent = nullptr; // If there is no error when opening the directory if (dir != NULL) { uint32_t i=0; // For each entry while ( (ent = readdir (dir)) != NULL) { // Ignore files . and .. if (strcmp(ent->d_name, ".") > 0 && strcmp(ent->d_name, "..")) { // Count processed files (one out of 2**7?) if ((i << 25)==0) std::cout << "DBDirectoryProcessor: " << i+1 << " entries processed\r" << std::flush;i++; // Add File object on the file list std::string fileName= std::string( ent->d_name ); file_list.push_back( fileName ); uint64_t fileSize = getFileSize(directory + fileName); if (fileSize > maxFileBytesize) maxFileBytesize = fileSize; } } std::cout << "DBDirectoryProcessor: " << i << " entries processed" << std::endl; if (i==0) { std::cout <<"DBDirectoryProcessor: No entries in the database" << std::endl; error = true; } closedir (dir); } else // If there was a problem opening the directory { std::cout << "DBDirectoryProcessor: Error opening database directory" << std::endl; error = true; } std::cout << "DBDirectoryProcessor: The size of the database is " << maxFileBytesize*file_list.size() << " bytes" << std::endl; std::cout << "DBDirectoryProcessor: The number of elements in the catalog is " << file_list.size() << std::endl; } // This constructor is called when we need File-splitting DBDirectoryProcessor::DBDirectoryProcessor(uint64_t nbStreams) : filesSplitting(true) { directory=std::string(DEFAULT_DIR_NAME); maxFileBytesize=0; // Then create the catalog and get the filenumbers and size DIR *dir = opendir (directory.c_str()); struct dirent *ent = nullptr; // If there is no error when opening the directory if (dir != NULL) { ent = readdir (dir); // WARNING: In case of file-splitting, we deal only with the first file // On some filesystems, the dir contains also special files such as "." and "..", skip them while (ent->d_name == NULL || ent->d_type != DT_REG) { ent = readdir (dir); } // Add File object on the file list std::string fileName=directory + std::string( ent->d_name ); realFileName=fileName; uint64_t realFileSize = getFileSize(realFileName); maxFileBytesize = realFileSize/nbStreams; if(maxFileBytesize==0) { std::cout << "DBDirectoryProcessor: ERROR cannot split a file en less than one byte elements!" << std::endl; std::cout << "DBDirectoryProcessor: file " << realFileName << " is only "<< realFileSize << " long" << std::endl; error = true; } closedir (dir); for(int i=0;iopen( local_directory + file_list[streamNb], std::ios::binary ); is->seekg(requested_offset); } else { // But when we are doing file splitting, we just need to position the ifstream at the correct position uint64_t splitting_offset=streamNb*getmaxFileBytesize(); is->open( realFileName, std::ios::binary ); is->seekg(splitting_offset + requested_offset); } fdPool.insert( std::pair(streamNb, is)); return true; } uint64_t DBDirectoryProcessor::readStream(uint64_t streamNb, char * buf, uint64_t size) { std::ifstream *s = fdPool[streamNb]; uint64_t sizeRead=0; //std::cout << "sizeRead = "<