87 lines
2.7 KiB
C++
87 lines
2.7 KiB
C++
// So NTFS (and most systems) sort the tree by default in lexicographical descending order.
|
|
// For lookups, this often isn't that useful if you only know substrings of the path.
|
|
|
|
|
|
// struct BTNode {
|
|
// u16 key_count;
|
|
// BTNode* keys;
|
|
// u16 allocated;
|
|
// };
|
|
|
|
// struct B_Tree {
|
|
// BTNode* root;
|
|
// Allocator allocator;
|
|
// };
|
|
|
|
// A compact collection of data with sorting indices
|
|
// Maybe we can make B+ trees for sorting according to
|
|
// size and modtime.
|
|
|
|
// It really doesn't make sense to store data in memory as a B-tree except
|
|
// if we need ordered insertions and deletes.
|
|
//
|
|
|
|
// Returns offset
|
|
force_inline s32 AddString_NoCount (Serializer* serializer, u8* data, u8 count) { // #TODO: , bool null_terminate=false
|
|
u8* current_point = &serializer->data[serializer->count];
|
|
s64 final_count = serializer->allocated + (count * sizeof(u8));
|
|
|
|
if (serializer->allocated < final_count) {
|
|
array_reserve(*serializer, final_count);
|
|
}
|
|
|
|
memcpy(current_point, data, count * sizeof(u8));
|
|
serializer->count += count * sizeof(u8);
|
|
}
|
|
|
|
constexpr s64 DFS_Preallocation_Count = 4194304; // 2^22
|
|
|
|
// template <typename Length_Type>
|
|
struct DFS_Array {
|
|
Serializer* strings;
|
|
|
|
ArenaArray<u32>* offsets; // offsets into string_arena
|
|
ArenaArray<u8>* lengths; // this type may vary <hmmm> Not sure if I should make it a template argument. Seems yucky.
|
|
ArenaArray<u64>* modtimes;
|
|
ArenaArray<u64>* sizes;
|
|
ArenaArray<s32>* parent_indices;
|
|
|
|
s64 index; // current index when inserting;
|
|
|
|
// #Temporary arrays for linking???
|
|
ArenaArray<u32>* record_ids;
|
|
ArenaArray<u32>* parent_ids;
|
|
|
|
// #TODO: Sort indices (should these be trees?)
|
|
// ArenaArray<s32> indices_sorted_by_modtime;
|
|
// ArenaArray<s32> indices_sorted_by_size;
|
|
};
|
|
|
|
void initialize (DFS_Array* dfsa) {
|
|
Assert(dfsa != nullptr);
|
|
dfsa->strings = new_serializer(Arena_Reserve::Size_2G);
|
|
|
|
dfsa->offsets = arena_array_new<u32>(DFS_Preallocation_Count, Arena_Reserve::Size_2G);
|
|
dfsa->lengths = arena_array_new<u8> (DFS_Preallocation_Count, Arena_Reserve::Size_2G);
|
|
dfsa->modtimes = arena_array_new<u64>(DFS_Preallocation_Count, Arena_Reserve::Size_2G);
|
|
dfsa->sizes = arena_array_new<u64>(DFS_Preallocation_Count, Arena_Reserve::Size_2G);
|
|
dfsa->parent_indices = arena_array_new<s32>(DFS_Preallocation_Count, Arena_Reserve::Size_2G);
|
|
|
|
dfsa->index = 0;
|
|
}
|
|
|
|
struct Dense_FS { // Link to OS_Drive
|
|
OS_Drive* drive; // backlink for reference.
|
|
DFS_Array paths;
|
|
DFS_Array files;
|
|
|
|
ArenaTable<u32, s32> path_table; // <entry_id, array_offset>.
|
|
};
|
|
|
|
void initialize (Dense_FS* dfs, OS_Drive* drive) {
|
|
Assert(drive != nullptr);
|
|
dfs->drive = drive;
|
|
initialize(&dfs->paths);
|
|
initialize(&dfs->files);
|
|
table_init(&dfs->path_table, DFS_Preallocation_Count);
|
|
} |