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 "files.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sstream>
|
#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_) {
|
FilesOperation::FilesOperation(RawDisk& disk_): disk(disk_) {
|
||||||
inop.initialize(disk);
|
inop.initialize(disk);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user