/* create new directory */ int fs_mkdir(const char *pathname, mode_t mode) { struct inode_s *ino, *dir, *tmpdir; char path[MAX_PATH], name[MAX_NAME]; ino = dir = tmpdir = NULL; process_path(pathname, path, name); tmpdir = current_dir(); /* get inode numbers from parent and new dir */ if ( (dir = find_inode(tmpdir, path, FS_SEARCH_GET)) == NULL) goto err; release_inode(tmpdir); if ( (ino = find_inode(dir, name, FS_SEARCH_ADD)) == NULL) goto err; /* fill new dir inode */ fill_inode(ino, mode); ino->i_mode = (ino->i_mode & ~I_TYPE) | I_DIRECTORY; /* add '.' */ empty_entry(ino, ino->i_num, "."); ino->i_nlinks++; /* and '..' */ empty_entry(ino, dir->i_num, ".."); dir->i_nlinks++; dir->i_dirty = 1; /* update dir size */ ino->i_size = DIRENTRY_SIZE * 2; release_inode(dir); release_inode(ino); return OK; err: release_inode(tmpdir); release_inode(dir); release_inode(ino); return ERROR; }
/** * Used for iterating over the hashtable. Checks if there is another * entry in the hashtable after the current entry. * * @return true if there is another entry, false otherwise */ bool Hashtable::internal_hasNext() { for (size_t ix = this->walk_index; ix <= this->size_mask; ix ++){ struct table_entry *entry = &this->table[ix]; if (!empty_entry(entry)){ return true; } } return false; }
/** * Used for iterating over the hashtable. Returns the next entry in the * hashtable. If there is no entry then this returns NULL. * * @return next entry from the hashtable */ table_entry *Hashtable::internal_next() { for (size_t ix = this->walk_index; ix <= this->size_mask; ix ++){ struct table_entry *entry = &this->table[ix]; if (!empty_entry(entry)){ this->walk_index = ix+1; return entry; } } return NULL; }
/** * Returns an array of the keys from the hashtable. * * @param keys The pointer to array of keys. */ void Hashtable::keys(void **keys) { int keycount = 0; keys = (void **)malloc(sizeof(void *)*this->count()); for (size_t ix = 0; ix <= this->size_mask; ix ++){ struct table_entry *entry = &this->table[ix]; //printf("ix: %d\n", ix); if (!empty_entry(entry)){ //printf("not empty\n"); keys[keycount] = entry->key; //printf("key: %s\n", (char *)keys[keycount]); keycount++; } } }
/** * Resizes the hashtable, re-allocates memory and frees up memory * from the original table * * @param min_size The minimum size of the new hashtable. * */ void Hashtable::resize(size_t min_size) { // Compute new size taking deleted items into account: next power of two // with at least 50% table free. size_t entries = this->entries - this->deleted; if (min_size < 2 * entries){ min_size = 2 * entries; } size_t new_size = Hashtable::INITIAL_SIZE; while (new_size < min_size){ new_size <<= 1; } table_entry *oldtable = this->table; size_t old_size = this->size_mask; this->table = (table_entry *)calloc(new_size, sizeof(struct table_entry)); for (size_t ix = 0; ix < new_size; ix ++){ this->table->hash = Hashtable::EMPTY_HASH; } this->size_mask = new_size - 1; this->entries = entries; this->deleted = 0; for (size_t ix = 0; ix <= old_size; ix ++){ struct table_entry *entry = &oldtable[ix]; if (!empty_entry(entry)){ bool found; struct table_entry *new_entry = this->lookup(entry->key, entry->hash, &found); new_entry->hash = entry->hash; new_entry->key = entry->key; new_entry->value = entry->value; } } // Release old table resources. free(oldtable); }