/* 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 = "<