<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:  
#include "backup_manager.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

#if DEBUG_HOTBACKUP
#define WARN(string, arg) HotBackup::CaptureWarn(string, arg)
#define TRACE(string, arg) HotBackup::CaptureTrace(string, arg)
#define ERROR(string, arg) HotBackup::CaptureError(string, arg)
#else
#define WARN(string, arg) 
#define TRACE(string, arg) 
#define ERROR(string, arg) 
#endif

///////////////////////////////////////////////////////////////////////////////
//
// backup_manager() -
//
// Description: 
//
//     Constructor.
//
backup_manager::backup_manager() 
    : m_doing_backup(false),
      m_doing_copy(true) // <CER> Set to false to turn off copy
{
}


///////////////////////////////////////////////////////////////////////////////
//
// start_backup() -
//
// Description: 
//
//     Turns ON boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::start_backup()
{
    assert(m_doing_backup == false);

    m_doing_backup = true;
    
    // Start backing all the files in the directory.
    if (m_doing_copy) {
        m_dir.start_copy();
    }
}


///////////////////////////////////////////////////////////////////////////////
//
// stop_backup() -
//
// Description: 
//
//     Turns OFF boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::stop_backup()
{
    assert(m_doing_backup == true);
    
    // TODO: Make this: abort copy?
    m_dir.wait_for_copy_to_finish();
    
    m_doing_backup = false;
    
}


///////////////////////////////////////////////////////////////////////////////
//
// add_directory() -
//
// Description: 
//
//     Adds the given source directory to our set of directories
// to backup.  This also uses the given destination argument as
// the top level of our backup directory.  All files underneath
// each directory tree should match once the backup is complete.
//
void backup_manager::add_directory(const char *source_dir,
                                   const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);
    
    // TODO: assert that the directory's are not the same.
    // TODO: assert that the destination directory is empty.
    
    // TEMP: We only have one directory object at this point, for now...
    m_dir.set_directories(source_dir, dest_dir);
    
    // Loop through all the current file descriptions and prepare them
    // for backup.
    for(int i = 0; i < m_map.size(); ++i) {
        file_description *file = m_map.get(i);
        if(file == NULL) {
            continue;
        }
        
        const char * source_path = file->get_full_source_name();
        if(!m_dir.is_prefix(source_path)) {
            continue;
        }

        const char * file_name = m_dir.translate_prefix(source_path);
        file->prepare_for_backup(file_name);
        m_dir.open_path(file_name);
        file->create();
    }
}


///////////////////////////////////////////////////////////////////////////////
//
// remove_directory() -
//
// Description: 
//
//     TBD...
//
void backup_manager::remove_directory(const char *source_dir,
                                      const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);
    
    // TODO: Do we need to pause copy?
    // TODO: Do we want an option to erase the backup?
}


///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     TBD: How is create different from open?  Is the only
// difference that we KNOW the file doesn't yet exist (from
// copy) for the create case?
//
void backup_manager::create(int fd, const char *file) 
{
    TRACE("entering create() with fd = ", fd);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_full_source_name(file);
    
    // If this file is not in the path of our source dir, don't create it.
    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }
    
    // If we aren't doing backup, don't bother creating the backup copy.
    if (!m_doing_backup) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);<commit_msg>refs #6186 Moved preparation of opened file_description objects to start_backup method.<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:  
#include "backup_manager.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

#if DEBUG_HOTBACKUP
#define WARN(string, arg) HotBackup::CaptureWarn(string, arg)
#define TRACE(string, arg) HotBackup::CaptureTrace(string, arg)
#define ERROR(string, arg) HotBackup::CaptureError(string, arg)
#else
#define WARN(string, arg) 
#define TRACE(string, arg) 
#define ERROR(string, arg) 
#endif

///////////////////////////////////////////////////////////////////////////////
//
// backup_manager() -
//
// Description: 
//
//     Constructor.
//
backup_manager::backup_manager() 
    : m_doing_backup(false),
      m_doing_copy(true) // <CER> Set to false to turn off copy
{
}


///////////////////////////////////////////////////////////////////////////////
//
// start_backup() -
//
// Description: 
//
//     Turns ON boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::start_backup()
{
    assert(m_doing_backup == false);
    
    // TODO: Assert that the directories have been set.
    
    // Start backing all the files in the directory.
    if (m_doing_copy) {
        m_dir.start_copy();
    }
    
    // TODO: Does this need a lock?
    // Loop through all the current file descriptions and prepare them
    // for backup.
    for(int i = 0; i < m_map.size(); ++i) {
        file_description *file = m_map.get(i);
        if(file == NULL) {
            continue;
        }
        
        const char * source_path = file->get_full_source_name();
        if(!m_dir.is_prefix(source_path)) {
            continue;
        }

        const char * file_name = m_dir.translate_prefix(source_path);
        file->prepare_for_backup(file_name);
        m_dir.open_path(file_name);
        file->create();
    }
    
    // This boolean acts like a switch:
    // Once set to true, future calls to open() and create() will
    // create and CAPTURE the respective files and directories.
    m_doing_backup = true;
}


///////////////////////////////////////////////////////////////////////////////
//
// stop_backup() -
//
// Description: 
//
//     Turns OFF boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::stop_backup()
{
    assert(m_doing_backup == true);
    
    // TODO: Make this: abort copy?
    m_dir.wait_for_copy_to_finish();
    m_doing_backup = false;
    
}


///////////////////////////////////////////////////////////////////////////////
//
// add_directory() -
//
// Description: 
//
//     Adds the given source directory to our set of directories
// to backup.  This also uses the given destination argument as
// the top level of our backup directory.  All files underneath
// each directory tree should match once the backup is complete.
//
void backup_manager::add_directory(const char *source_dir,
                                   const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: assert that the directory's are not the same.
    // TODO: assert that the destination directory is empty.
    // TEMP: We only have one directory object at this point, for now...
    m_dir.set_directories(source_dir, dest_dir);
    
}


///////////////////////////////////////////////////////////////////////////////
//
// remove_directory() -
//
// Description: 
//
//     TBD...
//
void backup_manager::remove_directory(const char *source_dir,
                                      const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: Do we need to pause copy?
    // TODO: Do we want an option to erase the backup?
}


///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     TBD: How is create different from open?  Is the only
// difference that we KNOW the file doesn't yet exist (from
// copy) for the create case?
//
void backup_manager::create(int fd, const char *file) 
{
    TRACE("entering create() with fd = ", fd);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_full_source_name(file);

    // If this file is not in the path of our source dir, don't create it.
    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }
    
    // If we aren't doing backup, don't bother creating the backup copy.
    if (!m_doing_backup) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);
{'fraction_non_alphanumeric': 0.213983499048022, 'fraction_numerical': 0.0014808546646921938, 'mean_word_length': 1.8599516031457954, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2081499', 'n_tokens_mistral': 2785, 'n_tokens_neox': 2708, 'n_words': 774}