create hash-tree hierarchy direntry file

This commit is contained in:
Victor 2023-11-19 16:53:29 -08:00
parent 68212773a6
commit 29dfe9a4a5
3 changed files with 175 additions and 38 deletions

41
include/direntry.h Normal file
View File

@ -0,0 +1,41 @@
typedef struct fileNode {
char *name = NULL;
int inode_number;
int permissions;
char *Symbolink;
struct treeNode *subdirectory;
struct fileNode *next;
void serialize(char* buffer) {
u_int64_t t = inode_number;
for (int j = 0; j < 8; j++){
buffer[j] = t & (((u_int64_t)1<<(8))-1);
t >>= 8;
}
strcpy(buffer+8, file_name);
}
void deserialize(char* buffer) {
inode_number = 0;
for (int j = 0; j < 8; j++)
inode_number = inode_number | (((u_int64_t)(unsigned char)buffer[j])<<(8*j));
strcpy(file_name, buffer+8);
}
} FileNode;
typedef struct {
int size;
FileNode **table;
} HashTable;
typedef struct treeNode {
char *dirName;
HashTable *contents;
struct treeNode *parent;
FileNode *self_info; //self fileNode infromation
} TreeNode;
/*root directory have its own initialization, so parent wont be NULL*/
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode);
/*if want to use dir mode use the subdirectory treeNode pointer */
//e.g. FileNode *Dirnode = fischl_find_entry(); can see file inside with Dirnode->subdirectory
//e.g. go to the current Dirnode parent directory, use TreeNode *get_Dir_parent = Dirnode->subdirectory->parent;
FileNode *fischl_find_entry(TreeNode *root, const char *path);

133
lib/direntry.cpp Normal file
View File

@ -0,0 +1,133 @@
/*********************************Hash operation********************************************
********************************************************************************************/
// Hash operation
unsigned int hash(HashTable *h, char *key) {
unsigned int hashval = 0;
for (; *key != '\0'; key++) hashval = *key + (hashval << 5) - hashval;
return hashval % h->size;
}
HashTable *createHashTable(int size) {
HashTable *newTable = (HashTable *)malloc(sizeof(HashTable));
newTable->size = size;
newTable->table = (FileNode **)malloc(sizeof(FileNode *) * size);
for (int i = 0; i < size; i++) newTable->table[i] = NULL;
return newTable;
}
FileNode *insertHash(HashTable *h, char *key, TreeNode *subdirectory) {
unsigned int hashval = hash(h, key);
FileNode *newNode = (FileNode *)malloc(sizeof(FileNode));
newNode->name = strdup(key);
newNode->subdirectory = subdirectory;
newNode->next = h->table[hashval];
h->table[hashval] = newNode;
return newNode;
}
FileNode *lookupHash(HashTable *h, char *key) {
unsigned int hashval = hash(h, key);
FileNode *node = h->table[hashval];
while (node != NULL) {
if (strcmp(node->name, key) == 0) return node;
node = node->next;
}
return NULL; // Not found
}
void freeHashTable(HashTable *table) {
if (table == NULL) return;
for (int i = 0; i < table->size; ++i) {
FileNode *current = table->table[i];
while (current != NULL) {
FileNode *temp = current;
current = current->next;
// free(temp->name);
// free(temp);
}
}
free(table->table);
free(table);
}
void freeTree(TreeNode *node) {
//printf("***********************FREE TREE %s**************************\n",node->dirName);
//printf("***********************FREE TREE **************************\n");
if (node == NULL) return;
if (node->contents != NULL) {
for (int i = 0; i < node->contents->size; ++i) {
FileNode *current = node->contents->table[i];
while (current != NULL) {
FileNode *temp = current;
current = current->next;
if (temp->subdirectory != NULL) {
freeTree(temp->subdirectory);
}
// Free the FileNode if it's not a directory
printf("free who %s\n",temp->name);
free(temp->name);
free(temp);
}
}
//printf("free %s's hash table\n",node->dirName);
freeHashTable(node->contents);
//node->contents = NULL;
}
//printf("free directory %s\n",node->dirName);
free(node->dirName);
node->dirName = NULL;
free(node);
node = NULL;
//printf("***********************END**************************\n");
}
/*********************************Direntry operation******************************************
********************************************************************************************/
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode){
char *Name = strdup(fileName);
TreeNode *newDir = NULL;
/*If directory, malloc TreeNode, and then create filenode that belongs to Parent hash table content*/
if ((new_inode->permissions & S_IFMT) == S_IFDIR) {
newDir = (TreeNode *)malloc(sizeof(TreeNode));
newDir->dirName = Name;
newDir->contents = createHashTable(20);//hasSize define 20
newDir->parent = parent;
}
FileNode *newFile = insertHash(parent->contents, Name, newDir); //newDir == NULL indicates it's a file
//assign INode *new_inode metadata to data member in FileNode structure
newFile->permissions = new_inode->permissions;
newFile->inode_number = new_inode_number;
//Diretory have its own file information, that is . here
if(newDir != NULL)
newDir->self_info = newFile;
//free(Name); cannot free name
return 0;
}
FileNode *fischl_find_entry(TreeNode *root, const char *path){
//support . and .. function
char *pathCopy = strdup(path);
char *segment = strtok(pathCopy, "/");
TreeNode *current = root;
FileNode *file = NULL;
while (segment != NULL && current != NULL) {
file = lookupHash(current->contents, segment);
if (file != NULL && file->subdirectory == NULL) {
free(pathCopy);
return file; //File found
//return current; return filenode
}
current = file ? file->subdirectory : NULL;
segment = strtok(NULL, "/");
}
free(pathCopy);
return file; // NULL if not found
//return current; return filenode
}

View File

@ -2,45 +2,8 @@
#include "files.h"
#include <string.h>
#include <sstream>
#include "direntry.h"
/*********************************************************************
Directory Entry definition and function
*********************************************************************/
struct DirectoryEntry {
u_int64_t inode_number;
char file_name[56];
void serialize(char* buffer) {
u_int64_t t = inode_number;
for (int j = 0; j < 8; j++){
buffer[j] = t & (((u_int64_t)1<<(8))-1);
t >>= 8;
}
strcpy(buffer+8, file_name);
}
void deserialize(char* buffer) {
inode_number = 0;
for (int j = 0; j < 8; j++)
inode_number = inode_number | (((u_int64_t)(unsigned char)buffer[j])<<(8*j));
strcpy(file_name, buffer+8);
}
};
//Directory collection
typedef struct {
//DirectoryEntry entries[MAX_ENTRIES]; with tree structure
unsigned int num_entries;
} Directory;
/*
* fishcl_add_entry()
*
* adds a file entry to the specified directory, using the same
* semantics as fishcl_find_entry(). It returns NULL if it failed.
*
*/
static int fishcl_add_entry(Directory *dir, unsigned int inode_number, const char *name){
}
FilesOperation::FilesOperation(RawDisk& disk_): disk(disk_) {
inop.initialize(disk);