create hash-tree hierarchy direntry file
This commit is contained in:
parent
68212773a6
commit
29dfe9a4a5
41
include/direntry.h
Normal file
41
include/direntry.h
Normal 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
133
lib/direntry.cpp
Normal 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
|
||||
}
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user