Skip to content

Commit

Permalink
Add new functions and files
Browse files Browse the repository at this point in the history
  • Loading branch information
janjurca committed Mar 6, 2024
1 parent 6c8c808 commit 6344cbb
Show file tree
Hide file tree
Showing 14 changed files with 412 additions and 112 deletions.
21 changes: 12 additions & 9 deletions include/filestorm/data_sizes.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,25 +132,28 @@ template <DataUnit T> class DataSize {
throw std::runtime_error(fmt::format("Invalid data size string (decimal places are not supported): {}", str));
}

DataUnit unit;
uint64_t bytes;

if (unit_str == "B") {
unit = DataUnit::B;
bytes = static_cast<uint64_t>(value);
} else if (unit_str == "KB" || unit_str == "K") {
unit = DataUnit::KB;
bytes = static_cast<uint64_t>(value) * static_cast<uint64_t>(DataUnit::KB);
} else if (unit_str == "MB" || unit_str == "M") {
unit = DataUnit::MB;
bytes = static_cast<uint64_t>(value) * static_cast<uint64_t>(DataUnit::MB);
} else if (unit_str == "GB" || unit_str == "G") {
unit = DataUnit::GB;
bytes = static_cast<uint64_t>(value) * static_cast<uint64_t>(DataUnit::GB);
} else if (unit_str == "TB" || unit_str == "T") {
unit = DataUnit::TB;
bytes = static_cast<uint64_t>(value) * static_cast<uint64_t>(DataUnit::TB);
} else if (unit_str == "PB" || unit_str == "P") {
unit = DataUnit::PB;
bytes = static_cast<uint64_t>(value) * static_cast<uint64_t>(DataUnit::PB);
} else {
throw std::runtime_error(fmt::format("Invalid data size unit: {}", unit_str));
}

return DataSize<T>(static_cast<uint64_t>(value * (static_cast<uint64_t>(T) / static_cast<uint64_t>(unit))), false);
uint64_t unit_size = static_cast<uint64_t>(T);
if (bytes % unit_size != 0) {
throw std::runtime_error(fmt::format("Invalid data size string (cannot convert to the specified unit without a remainder): {}", str));
}
return DataSize<T>(bytes / unit_size, false);
}
};

Expand Down
24 changes: 24 additions & 0 deletions include/filestorm/filefrag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <fcntl.h>
#if defined(__linux__)
# include <linux/fiemap.h>
# include <linux/fs.h>
#else
# warning "The file fragments code is for Linux only and the fragmentation monitorning wont be available on other platforms."
#endif
#include <spdlog/spdlog.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <iostream>
#include <vector>

#define MAX_EXTENTS 32

struct extents {
uint64_t start;
uint64_t length;
uint64_t flags;
};

std::vector<extents> get_extents(const char *file_path);
18 changes: 18 additions & 0 deletions include/filestorm/filetree.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <filestorm/filefrag.h>
#include <filestorm/utils.h>

#include <atomic>
Expand All @@ -21,12 +22,14 @@ class FileTree {
unsigned int _max_depth;

struct Node {
public:
std::string name;
Type type;
Node* parent;
long size;
std::map<std::string, std::unique_ptr<Node>> folders;
std::map<std::string, std::unique_ptr<Node>> files;
int extents_count = -1;

Node(const std::string& n, Type t, Node* p, long size = 0) : name(n), type(t), parent(p), size(size) {}
std::string path(bool include_root = false) const {
Expand All @@ -39,8 +42,23 @@ class FileTree {
}
return parent->path(include_root) + "/" + name;
}
/*
int getExtentsCount(bool update = true) {
if (extents_count == -1 || update) {
if (type == Type::FILE) {
extents_count = get_extents(path().c_str()).size();
} else {
extents_count = 0;
}
}
return extents_count;
}
*/
};

std::vector<Node*> all_files;
std::vector<Node*> all_directories;

private:
std::unique_ptr<Node> root;

Expand Down
4 changes: 3 additions & 1 deletion include/filestorm/scenarios/scenario.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <filestorm/actions/actions.h>
#include <filestorm/data_sizes.h>
#include <filestorm/filetree.h>
#include <filestorm/utils/psm.h>

Expand Down Expand Up @@ -98,5 +99,6 @@ class AgingScenario : public Scenario {

double CAF(double x) { return sqrt(1 - (x * x)); }
DataSize<DataUnit::B> get_file_size();
DataSize<DataUnit::B> get_file_size(uint64_t min, uint64_t max);
DataSize<DataUnit::B> get_file_size(uint64_t min, uint64_t max, bool safe = true);
DataSize<DataUnit::B> get_block_size() { return DataSize<DataUnit::B>::fromString(getParameter("blocksize").get_string()); };
};
13 changes: 13 additions & 0 deletions include/filestorm/utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <algorithm> // Make sure this is included
#include <random>
#include <random> // Assuming you're using random number generation
#include <string>
#include <vector>

Expand All @@ -9,3 +12,13 @@ std::string strip(const std::string& str, const char stripChar = ' ');

std::string toLower(const std::string& str);
std::string toUpper(const std::string& str);

inline void generate_random_chunk(char* chunk, size_t size) {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis(0, 255);

std::generate_n(chunk, size, []() { return dis(gen); });
}

double ceilTo(double value, int decimals);
10 changes: 9 additions & 1 deletion include/filestorm/utils/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
#include <filesystem>

namespace fs_utils {
std::filesystem::space_info get_fs_status(const std::filesystem::path& path) { return std::filesystem::space(path); }
std::filesystem::space_info get_fs_status(const std::filesystem::path& path) {
auto info = std::filesystem::space(path);
if (info.capacity < info.free || info.capacity < info.available) {
info.free = 0;
info.available = 0;
}

return info;
}
uint64_t file_size(const std::filesystem::path& path) { return std::filesystem::file_size(path); }
} // namespace fs_utils
3 changes: 1 addition & 2 deletions include/filestorm/utils/psm.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ class ProbabilisticStateMachine {

void performTransition(std::map<std::string, double>& probabilities) {
// Choose a transition based on probabilities
double randomValue = ((double)rand() / (RAND_MAX));
double randomValue = ((double)rand() / (double)(RAND_MAX));
double cumulativeProbability = 0.0;

for (const auto& transition : _transitions) {
if (transition.second.from() != _currentState) {
continue;
}
cumulativeProbability += probabilities[transition.second.probability_key()];
// spdlog::debug("Cumulative probability: {}", cumulativeProbability);
if (randomValue <= cumulativeProbability) {
// Transition to the next state
_currentState = transition.second.to();
Expand Down
66 changes: 66 additions & 0 deletions misc/extents_scan.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <fcntl.h>
#include <linux/fiemap.h>
#include <linux/fs.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <iostream>

#define MAX_EXTENTS 32

struct fiemap_extent_data {
struct fiemap *fiemap_ptr;
};

// Function to print the extents of a file
void print_file_extents(const char *file_path) {
int fd = open(file_path, O_RDONLY);
if (fd < 0) {
perror("open");
return;
}

struct fiemap_extent_data fed;
memset(&fed, 0, sizeof(fed));

size_t fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent) * MAX_EXTENTS;
fed.fiemap_ptr = (struct fiemap *)malloc(fiemap_size);
if (fed.fiemap_ptr == NULL) {
perror("malloc");
close(fd);
return;
}
memset(fed.fiemap_ptr, 0, fiemap_size);

fed.fiemap_ptr->fm_start = 0;
fed.fiemap_ptr->fm_length = ~0ULL; // Request all extents from the start
fed.fiemap_ptr->fm_flags = FIEMAP_FLAG_SYNC;
fed.fiemap_ptr->fm_extent_count = MAX_EXTENTS;

if (ioctl(fd, FS_IOC_FIEMAP, fed.fiemap_ptr) == -1) {
perror("ioctl");
free(fed.fiemap_ptr);
close(fd);
return;
}

std::cout << "Number of extents: " << fed.fiemap_ptr->fm_mapped_extents << std::endl;
for (unsigned int i = 0; i < fed.fiemap_ptr->fm_mapped_extents; i++) {
std::cout << "Extent " << i << ": Start=" << fed.fiemap_ptr->fm_extents[i].fe_logical << ", Length=" << fed.fiemap_ptr->fm_extents[i].fe_length
<< ", Flags=" << fed.fiemap_ptr->fm_extents[i].fe_flags << std::endl;
}

free(fed.fiemap_ptr);
close(fd);
}

int main(int argc, char *argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <file_path>" << std::endl;
return 1;
}

print_file_extents(argv[1]);
return 0;
}
55 changes: 55 additions & 0 deletions source/filefrag.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <filestorm/filefrag.h>

struct fiemap_extent_data {
struct fiemap *fiemap_ptr;
};

std::vector<extents> get_extents(const char *file_path) {
#if defined(__linux__)
std::vector<extents> extents_list;
int fd = open(file_path, O_RDONLY);
if (fd < 0) {
perror("open");
throw std::runtime_error("Error opening file, for extents scan.");
}

struct fiemap_extent_data fed;
memset(&fed, 0, sizeof(fed));

size_t fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent) * MAX_EXTENTS;
fed.fiemap_ptr = (struct fiemap *)malloc(fiemap_size);
if (fed.fiemap_ptr == NULL) {
perror("malloc");
close(fd);
throw std::runtime_error("Error allocating memory for fiemap.");
}
memset(fed.fiemap_ptr, 0, fiemap_size);

fed.fiemap_ptr->fm_start = 0;
fed.fiemap_ptr->fm_length = ~0ULL; // Request all extents from the start
fed.fiemap_ptr->fm_flags = FIEMAP_FLAG_SYNC;
fed.fiemap_ptr->fm_extent_count = MAX_EXTENTS;

if (ioctl(fd, FS_IOC_FIEMAP, fed.fiemap_ptr) == -1) {
perror("ioctl");
free(fed.fiemap_ptr);
close(fd);
throw std::runtime_error("Error getting file extents.");
}

for (unsigned int i = 0; i < fed.fiemap_ptr->fm_mapped_extents; i++) {
extents_list.push_back({fed.fiemap_ptr->fm_extents[i].fe_logical, fed.fiemap_ptr->fm_extents[i].fe_length, fed.fiemap_ptr->fm_extents[i].fe_flags});
}

free(fed.fiemap_ptr);
close(fd);
return extents_list;
#else
static bool warning_printed = false;
if (!warning_printed) {
spdlog::debug("This code is for Linux only and the fragmentation monitorning wont be available on other platforms.");
warning_printed = true;
}
return {};
#endif
}
Loading

0 comments on commit 6344cbb

Please sign in to comment.