* Replaced Chain with the new SinglyLinkedList.

* Renamed openModeToAccess() to open_mode_to_access().
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26718 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-08-01 14:20:16 +00:00
parent c1c81d42d1
commit 2accd07be4
13 changed files with 298 additions and 356 deletions
@@ -67,7 +67,7 @@ Attribute::CheckAccess(const char *name, int openMode)
|| !strcmp(name, "size")*/) || !strcmp(name, "size")*/)
RETURN_ERROR(B_NOT_ALLOWED); RETURN_ERROR(B_NOT_ALLOWED);
return fInode->CheckPermissions(openModeToAccess(openMode) return fInode->CheckPermissions(open_mode_to_access(openMode)
| (openMode & O_TRUNC ? W_OK : 0)); | (openMode & O_TRUNC ? W_OK : 0));
} }
@@ -377,9 +377,10 @@ BPlusTree::~BPlusTree()
// traversing the tree - a TreeIterator doesn't lock the inode) // traversing the tree - a TreeIterator doesn't lock the inode)
mutex_lock(&fIteratorLock); mutex_lock(&fIteratorLock);
TreeIterator *iterator = NULL; SinglyLinkedList<TreeIterator>::Iterator iterator
while ((iterator = fIterators.Next(iterator)) != NULL) = fIterators.GetIterator();
iterator->Stop(); while (iterator.HasNext())
iterator.Next()->Stop();
mutex_destroy(&fIteratorLock); mutex_destroy(&fIteratorLock);
} }
@@ -569,9 +570,10 @@ BPlusTree::_UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex,
// any time, so we need to protect this loop // any time, so we need to protect this loop
MutexLocker _(fIteratorLock); MutexLocker _(fIteratorLock);
TreeIterator *iterator = NULL; SinglyLinkedList<TreeIterator>::Iterator iterator
while ((iterator = fIterators.Next(iterator)) != NULL) = fIterators.GetIterator();
iterator->Update(offset, nextOffset, keyIndex, splitAt, change); while (iterator.HasNext())
iterator.Next()->Update(offset, nextOffset, keyIndex, splitAt, change);
} }
@@ -1862,8 +1864,7 @@ BPlusTree::Find(const uint8 *key, uint16 keyLength, off_t *_value)
TreeIterator::TreeIterator(BPlusTree *tree) TreeIterator::TreeIterator(BPlusTree *tree)
: :
fTree(tree), fTree(tree),
fCurrentNodeOffset(BPLUSTREE_NULL), fCurrentNodeOffset(BPLUSTREE_NULL)
fNext(NULL)
{ {
tree->_AddIterator(this); tree->_AddIterator(this);
} }
+139 -135
View File
@@ -8,7 +8,6 @@
#include "bfs.h" #include "bfs.h"
#include "Journal.h" #include "Journal.h"
#include "Chain.h"
// #pragma mark - on-disk structures // #pragma mark - on-disk structures
@@ -38,7 +37,7 @@ struct bplustree_header {
uint32 MaxNumberOfLevels() const uint32 MaxNumberOfLevels() const
{ return BFS_ENDIAN_TO_HOST_INT32(max_number_of_levels); } { return BFS_ENDIAN_TO_HOST_INT32(max_number_of_levels); }
inline bool CheckNode(bplustree_node *node) const; inline bool CheckNode(bplustree_node* node) const;
inline bool IsValidLink(off_t link) const; inline bool IsValidLink(off_t link) const;
} _PACKED; } _PACKED;
@@ -75,11 +74,11 @@ struct bplustree_node {
uint16 AllKeyLength() const uint16 AllKeyLength() const
{ return BFS_ENDIAN_TO_HOST_INT16(all_key_length); } { return BFS_ENDIAN_TO_HOST_INT16(all_key_length); }
inline uint16 *KeyLengths() const; inline uint16* KeyLengths() const;
inline off_t *Values() const; inline off_t* Values() const;
inline uint8 *Keys() const; inline uint8* Keys() const;
inline int32 Used() const; inline int32 Used() const;
uint8 *KeyAt(int32 index, uint16 *keyLength) const; uint8* KeyAt(int32 index, uint16* keyLength) const;
inline bool IsLeaf() const; inline bool IsLeaf() const;
@@ -87,8 +86,8 @@ struct bplustree_node {
uint8 CountDuplicates(off_t offset, bool isFragment) const; uint8 CountDuplicates(off_t offset, bool isFragment) const;
off_t DuplicateAt(off_t offset, bool isFragment, int8 index) const; off_t DuplicateAt(off_t offset, bool isFragment, int8 index) const;
uint32 FragmentsUsed(uint32 nodeSize) const; uint32 FragmentsUsed(uint32 nodeSize) const;
inline duplicate_array *FragmentAt(int8 index) const; inline duplicate_array* FragmentAt(int8 index) const;
inline duplicate_array *DuplicateArray() const; inline duplicate_array* DuplicateArray() const;
static inline uint8 LinkType(off_t link); static inline uint8 LinkType(off_t link);
static inline off_t MakeLink(uint8 type, off_t link, static inline off_t MakeLink(uint8 type, off_t link,
@@ -137,15 +136,15 @@ struct node_and_key {
class CachedNode { class CachedNode {
public: public:
CachedNode(BPlusTree *tree) CachedNode(BPlusTree* tree)
: :
fTree(tree), fTree(tree),
fNode(NULL) fNode(NULL)
{ {
} }
CachedNode(BPlusTree *tree, off_t offset, bool check = true) CachedNode(BPlusTree* tree, off_t offset, bool check = true)
: :
fTree(tree), fTree(tree),
fNode(NULL) fNode(NULL)
@@ -158,29 +157,29 @@ class CachedNode {
Unset(); Unset();
} }
const bplustree_node *SetTo(off_t offset, bool check = true); const bplustree_node* SetTo(off_t offset, bool check = true);
bplustree_node *SetToWritable(Transaction &transaction, off_t offset, bplustree_node* SetToWritable(Transaction& transaction, off_t offset,
bool check = true); bool check = true);
bplustree_node *MakeWritable(Transaction &transaction); bplustree_node* MakeWritable(Transaction& transaction);
const bplustree_header *SetToHeader(); const bplustree_header* SetToHeader();
bplustree_header *SetToWritableHeader(Transaction &transaction); bplustree_header* SetToWritableHeader(Transaction& transaction);
bplustree_header *MakeWritableHeader(Transaction &transaction); bplustree_header* MakeWritableHeader(Transaction& transaction);
void UnsetUnchanged(Transaction &transaction); void UnsetUnchanged(Transaction& transaction);
void Unset(); void Unset();
status_t Free(Transaction &transaction, off_t offset); status_t Free(Transaction& transaction, off_t offset);
status_t Allocate(Transaction &transaction, bplustree_node **node, status_t Allocate(Transaction& transaction, bplustree_node** node,
off_t *offset); off_t* offset);
bool IsWritable() const { return fWritable; } bool IsWritable() const { return fWritable; }
bplustree_node *Node() const { return fNode; } bplustree_node* Node() const { return fNode; }
protected: protected:
bplustree_node *InternalSetTo(Transaction *transaction, off_t offset); bplustree_node* InternalSetTo(Transaction* transaction, off_t offset);
BPlusTree *fTree; BPlusTree* fTree;
bplustree_node *fNode; bplustree_node* fNode;
off_t fOffset; off_t fOffset;
off_t fBlockNumber; off_t fBlockNumber;
bool fWritable; bool fWritable;
@@ -188,141 +187,147 @@ class CachedNode {
class BPlusTree { class BPlusTree {
public: public:
BPlusTree(Transaction &transaction, Inode *stream, BPlusTree(Transaction& transaction, Inode* stream,
int32 nodeSize = BPLUSTREE_NODE_SIZE); int32 nodeSize = BPLUSTREE_NODE_SIZE);
BPlusTree(Inode *stream); BPlusTree(Inode* stream);
BPlusTree(); BPlusTree();
~BPlusTree(); ~BPlusTree();
status_t SetTo(Transaction &transaction, Inode *stream, status_t SetTo(Transaction& transaction, Inode* stream,
int32 nodeSize = BPLUSTREE_NODE_SIZE); int32 nodeSize = BPLUSTREE_NODE_SIZE);
status_t SetTo(Inode *stream); status_t SetTo(Inode* stream);
status_t SetStream(Inode *stream); status_t SetStream(Inode* stream);
status_t InitCheck(); status_t InitCheck();
status_t Validate(); status_t Validate();
status_t Remove(Transaction &transaction, const uint8 *key, status_t Remove(Transaction& transaction, const uint8* key,
uint16 keyLength, off_t value); uint16 keyLength, off_t value);
status_t Insert(Transaction &transaction, const uint8 *key, status_t Insert(Transaction& transaction, const uint8* key,
uint16 keyLength, off_t value); uint16 keyLength, off_t value);
status_t Remove(Transaction &transaction, const char *key, status_t Remove(Transaction& transaction, const char* key,
off_t value); off_t value);
status_t Insert(Transaction &transaction, const char *key, status_t Insert(Transaction& transaction, const char* key,
off_t value);
status_t Insert(Transaction& transaction, int32 key,
off_t value);
status_t Insert(Transaction& transaction, uint32 key,
off_t value);
status_t Insert(Transaction& transaction, int64 key,
off_t value);
status_t Insert(Transaction& transaction, uint64 key,
off_t value);
status_t Insert(Transaction& transaction, float key,
off_t value);
status_t Insert(Transaction& transaction, double key,
off_t value); off_t value);
status_t Insert(Transaction &transaction, int32 key, off_t value);
status_t Insert(Transaction &transaction, uint32 key, off_t value);
status_t Insert(Transaction &transaction, int64 key, off_t value);
status_t Insert(Transaction &transaction, uint64 key, off_t value);
status_t Insert(Transaction &transaction, float key, off_t value);
status_t Insert(Transaction &transaction, double key, off_t value);
status_t Replace(Transaction &transaction, const uint8 *key, status_t Replace(Transaction& transaction, const uint8* key,
uint16 keyLength, off_t value); uint16 keyLength, off_t value);
status_t Find(const uint8 *key, uint16 keyLength, off_t *value); status_t Find(const uint8* key, uint16 keyLength, off_t* value);
static int32 TypeCodeToKeyType(type_code code); static int32 TypeCodeToKeyType(type_code code);
static int32 ModeToKeyType(mode_t mode); static int32 ModeToKeyType(mode_t mode);
private: private:
BPlusTree(const BPlusTree &); BPlusTree(const BPlusTree& other);
BPlusTree &operator=(const BPlusTree &); BPlusTree& operator=(const BPlusTree& other);
// no implementation // no implementation
int32 _CompareKeys(const void *key1, int keylength1, int32 _CompareKeys(const void* key1, int keylength1,
const void *key2, int keylength2); const void* key2, int keylength2);
status_t _FindKey(const bplustree_node *node, const uint8 *key, status_t _FindKey(const bplustree_node* node, const uint8* key,
uint16 keyLength, uint16 *index = NULL, uint16 keyLength, uint16* index = NULL,
off_t *next = NULL); off_t* next = NULL);
status_t _SeekDown(Stack<node_and_key> &stack, const uint8 *key, status_t _SeekDown(Stack<node_and_key>& stack, const uint8* key,
uint16 keyLength); uint16 keyLength);
status_t _FindFreeDuplicateFragment(Transaction &transaction, status_t _FindFreeDuplicateFragment(Transaction& transaction,
const bplustree_node *node, CachedNode &cached, const bplustree_node* node, CachedNode& cached,
off_t *_offset, bplustree_node **_fragment, off_t* _offset, bplustree_node** _fragment,
uint32 *_index); uint32* _index);
status_t _InsertDuplicate(Transaction &transaction, status_t _InsertDuplicate(Transaction& transaction,
CachedNode &cached, const bplustree_node *node, CachedNode& cached, const bplustree_node* node,
uint16 index, off_t value); uint16 index, off_t value);
void _InsertKey(bplustree_node *node, uint16 index, uint8 *key, void _InsertKey(bplustree_node* node, uint16 index,
uint16 keyLength, off_t value); uint8* key, uint16 keyLength, off_t value);
status_t _SplitNode(bplustree_node *node, off_t nodeOffset, status_t _SplitNode(bplustree_node* node, off_t nodeOffset,
bplustree_node *other, off_t otherOffset, bplustree_node* other, off_t otherOffset,
uint16 *_keyIndex, uint8 *key, uint16 *_keyLength, uint16* _keyIndex, uint8* key, uint16* _keyLength,
off_t *_value); off_t* _value);
status_t _RemoveDuplicate(Transaction &transaction, status_t _RemoveDuplicate(Transaction& transaction,
const bplustree_node *node, CachedNode &cached, const bplustree_node* node, CachedNode& cached,
uint16 keyIndex, off_t value); uint16 keyIndex, off_t value);
void _RemoveKey(bplustree_node *node, uint16 index); void _RemoveKey(bplustree_node* node, uint16 index);
void _UpdateIterators(off_t offset, off_t nextOffset, void _UpdateIterators(off_t offset, off_t nextOffset,
uint16 keyIndex, uint16 splitAt, int8 change); uint16 keyIndex, uint16 splitAt, int8 change);
void _AddIterator(TreeIterator *iterator); void _AddIterator(TreeIterator* iterator);
void _RemoveIterator(TreeIterator *iterator); void _RemoveIterator(TreeIterator* iterator);
private: private:
friend class TreeIterator; friend class TreeIterator;
friend class CachedNode; friend class CachedNode;
Inode *fStream; Inode* fStream;
const bplustree_header *fHeader; const bplustree_header* fHeader;
CachedNode fCachedHeader; CachedNode fCachedHeader;
int32 fNodeSize; int32 fNodeSize;
bool fAllowDuplicates; bool fAllowDuplicates;
status_t fStatus; status_t fStatus;
mutex fIteratorLock; mutex fIteratorLock;
Chain<TreeIterator> fIterators; SinglyLinkedList<TreeIterator> fIterators;
}; };
// #pragma mark - helper classes/functions // #pragma mark - helper classes/functions
extern int32 compareKeys(type_code type, const void *key1, int keyLength1, extern int32 compareKeys(type_code type, const void* key1, int keyLength1,
const void *key2, int keyLength2); const void* key2, int keyLength2);
class TreeIterator { class TreeIterator : public SinglyLinkedListLinkImpl<TreeIterator> {
public: public:
TreeIterator(BPlusTree *tree); TreeIterator(BPlusTree* tree);
~TreeIterator(); ~TreeIterator();
status_t Goto(int8 to); status_t Goto(int8 to);
status_t Traverse(int8 direction, void *key, uint16 *keyLength, status_t Traverse(int8 direction, void* key, uint16* keyLength,
uint16 maxLength, off_t *value, uint16 maxLength, off_t* value,
uint16 *duplicate = NULL); uint16* duplicate = NULL);
status_t Find(const uint8 *key, uint16 keyLength); status_t Find(const uint8* key, uint16 keyLength);
status_t Rewind(); status_t Rewind();
status_t GetNextEntry(void *key, uint16 *keyLength, uint16 maxLength, status_t GetNextEntry(void* key, uint16* keyLength,
off_t *value, uint16 *duplicate = NULL); uint16 maxLength, off_t* value,
status_t GetPreviousEntry(void *key, uint16 *keyLength, uint16* duplicate = NULL);
uint16 maxLength, off_t *value, status_t GetPreviousEntry(void* key, uint16* keyLength,
uint16 *duplicate = NULL); uint16 maxLength, off_t* value,
uint16* duplicate = NULL);
void SkipDuplicates(); void SkipDuplicates();
#ifdef DEBUG #ifdef DEBUG
void Dump(); void Dump();
#endif #endif
private: private:
BPlusTree *fTree; friend class BPlusTree;
off_t fCurrentNodeOffset; // traverse position // called by BPlusTree
void Update(off_t offset, off_t nextOffset, uint16 keyIndex,
uint16 splitAt, int8 change);
void Stop();
private:
BPlusTree* fTree;
off_t fCurrentNodeOffset;
// traverse position
int32 fCurrentKey; int32 fCurrentKey;
off_t fDuplicateNode; off_t fDuplicateNode;
uint16 fDuplicate, fNumDuplicates; uint16 fDuplicate, fNumDuplicates;
bool fIsFragment; bool fIsFragment;
private:
friend class Chain<TreeIterator>;
friend class BPlusTree;
void Update(off_t offset, off_t nextOffset, uint16 keyIndex,
uint16 splitAt, int8 change);
void Stop();
TreeIterator *fNext;
}; };
@@ -331,67 +336,67 @@ class TreeIterator {
inline status_t inline status_t
BPlusTree::Remove(Transaction &transaction, const char *key, off_t value) BPlusTree::Remove(Transaction& transaction, const char* key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_STRING_TYPE) if (fHeader->data_type != BPLUSTREE_STRING_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Remove(transaction, (uint8 *)key, strlen(key), value); return Remove(transaction, (uint8*)key, strlen(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, const char *key, off_t value) BPlusTree::Insert(Transaction& transaction, const char* key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_STRING_TYPE) if (fHeader->data_type != BPLUSTREE_STRING_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)key, strlen(key), value); return Insert(transaction, (uint8*)key, strlen(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, int32 key, off_t value) BPlusTree::Insert(Transaction& transaction, int32 key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_INT32_TYPE) if (fHeader->data_type != BPLUSTREE_INT32_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, uint32 key, off_t value) BPlusTree::Insert(Transaction& transaction, uint32 key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_UINT32_TYPE) if (fHeader->data_type != BPLUSTREE_UINT32_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, int64 key, off_t value) BPlusTree::Insert(Transaction& transaction, int64 key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_INT64_TYPE) if (fHeader->data_type != BPLUSTREE_INT64_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, uint64 key, off_t value) BPlusTree::Insert(Transaction& transaction, uint64 key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_UINT64_TYPE) if (fHeader->data_type != BPLUSTREE_UINT64_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, float key, off_t value) BPlusTree::Insert(Transaction& transaction, float key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_FLOAT_TYPE) if (fHeader->data_type != BPLUSTREE_FLOAT_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
inline status_t inline status_t
BPlusTree::Insert(Transaction &transaction, double key, off_t value) BPlusTree::Insert(Transaction& transaction, double key, off_t value)
{ {
if (fHeader->data_type != BPLUSTREE_DOUBLE_TYPE) if (fHeader->data_type != BPLUSTREE_DOUBLE_TYPE)
return B_BAD_TYPE; return B_BAD_TYPE;
return Insert(transaction, (uint8 *)&key, sizeof(key), value); return Insert(transaction, (uint8*)&key, sizeof(key), value);
} }
@@ -405,16 +410,16 @@ TreeIterator::Rewind()
} }
inline status_t inline status_t
TreeIterator::GetNextEntry(void *key, uint16 *keyLength, uint16 maxLength, TreeIterator::GetNextEntry(void* key, uint16* keyLength, uint16 maxLength,
off_t *value, uint16 *duplicate) off_t* value, uint16* duplicate)
{ {
return Traverse(BPLUSTREE_FORWARD, key, keyLength, maxLength, value, return Traverse(BPLUSTREE_FORWARD, key, keyLength, maxLength, value,
duplicate); duplicate);
} }
inline status_t inline status_t
TreeIterator::GetPreviousEntry(void *key, uint16 *keyLength, uint16 maxLength, TreeIterator::GetPreviousEntry(void* key, uint16* keyLength, uint16 maxLength,
off_t *value, uint16 *duplicate) off_t* value, uint16* duplicate)
{ {
return Traverse(BPLUSTREE_BACKWARD, key, keyLength, maxLength, value, return Traverse(BPLUSTREE_BACKWARD, key, keyLength, maxLength, value,
duplicate); duplicate);
@@ -425,14 +430,14 @@ TreeIterator::GetPreviousEntry(void *key, uint16 *keyLength, uint16 maxLength,
inline bool inline bool
bplustree_header::CheckNode(bplustree_node *node) const bplustree_header::CheckNode(bplustree_node* node) const
{ {
// sanity checks (links, all_key_count) // sanity checks (links, all_key_count)
return IsValidLink(node->LeftLink()) return IsValidLink(node->LeftLink())
&& IsValidLink(node->RightLink()) && IsValidLink(node->RightLink())
&& IsValidLink(node->OverflowLink()) && IsValidLink(node->OverflowLink())
&& (int8 *)node->Values() + node->NumKeys() * sizeof(off_t) && (int8*)node->Values() + node->NumKeys() * sizeof(off_t)
<= (int8 *)node + NodeSize(); <= (int8*)node + NodeSize();
} }
@@ -447,25 +452,25 @@ bplustree_header::IsValidLink(off_t link) const
// #pragma mark - bplustree_node inline functions // #pragma mark - bplustree_node inline functions
inline uint16 * inline uint16*
bplustree_node::KeyLengths() const bplustree_node::KeyLengths() const
{ {
return (uint16 *)(((char *)this) + key_align(sizeof(bplustree_node) return (uint16*)(((char*)this) + key_align(sizeof(bplustree_node)
+ AllKeyLength())); + AllKeyLength()));
} }
inline off_t * inline off_t*
bplustree_node::Values() const bplustree_node::Values() const
{ {
return (off_t *)((char *)KeyLengths() + NumKeys() * sizeof(uint16)); return (off_t*)((char*)KeyLengths() + NumKeys() * sizeof(uint16));
} }
inline uint8 * inline uint8*
bplustree_node::Keys() const bplustree_node::Keys() const
{ {
return (uint8 *)this + sizeof(bplustree_node); return (uint8*)this + sizeof(bplustree_node);
} }
@@ -484,25 +489,24 @@ bplustree_node::IsLeaf() const
} }
inline duplicate_array * inline duplicate_array*
bplustree_node::FragmentAt(int8 index) const bplustree_node::FragmentAt(int8 index) const
{ {
return (duplicate_array *)((off_t *)this return (duplicate_array*)((off_t*)this + index * (NUM_FRAGMENT_VALUES + 1));
+ index * (NUM_FRAGMENT_VALUES + 1));
} }
inline duplicate_array * inline duplicate_array*
bplustree_node::DuplicateArray() const bplustree_node::DuplicateArray() const
{ {
return (duplicate_array *)&this->overflow_link; return (duplicate_array*)&overflow_link;
} }
inline uint8 inline uint8
bplustree_node::LinkType(off_t link) bplustree_node::LinkType(off_t link)
{ {
return *(uint64 *)&link >> 62; return *(uint64*)&link >> 62;
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef CACHED_BLOCK_H #ifndef CACHED_BLOCK_H
@@ -12,7 +12,6 @@
#include "Volume.h" #include "Volume.h"
#include "Journal.h" #include "Journal.h"
#include "Chain.h"
#include "Debug.h" #include "Debug.h"
@@ -23,34 +22,34 @@
class CachedBlock { class CachedBlock {
public: public:
CachedBlock(Volume *volume); CachedBlock(Volume* volume);
CachedBlock(Volume *volume, off_t block); CachedBlock(Volume* volume, off_t block);
CachedBlock(Volume *volume, block_run run); CachedBlock(Volume* volume, block_run run);
CachedBlock(CachedBlock *cached); CachedBlock(CachedBlock* cached);
~CachedBlock(); ~CachedBlock();
inline void Keep(); inline void Keep();
inline void Unset(); inline void Unset();
inline const uint8 *SetTo(off_t block, off_t base, size_t length); inline const uint8* SetTo(off_t block, off_t base, size_t length);
inline const uint8 *SetTo(off_t block); inline const uint8* SetTo(off_t block);
inline const uint8 *SetTo(block_run run); inline const uint8* SetTo(block_run run);
inline uint8 *SetToWritable(Transaction &transaction, off_t block, inline uint8* SetToWritable(Transaction& transaction, off_t block,
off_t base, size_t length, bool empty = false); off_t base, size_t length, bool empty = false);
inline uint8 *SetToWritable(Transaction &transaction, off_t block, inline uint8* SetToWritable(Transaction& transaction, off_t block,
bool empty = false); bool empty = false);
inline uint8 *SetToWritable(Transaction &transaction, block_run run, inline uint8* SetToWritable(Transaction& transaction, block_run run,
bool empty = false); bool empty = false);
inline status_t MakeWritable(Transaction &transaction); inline status_t MakeWritable(Transaction& transaction);
const uint8 *Block() const { return fBlock; } const uint8* Block() const { return fBlock; }
off_t BlockNumber() const { return fBlockNumber; } off_t BlockNumber() const { return fBlockNumber; }
uint32 BlockSize() const { return fVolume->BlockSize(); } uint32 BlockSize() const { return fVolume->BlockSize(); }
uint32 BlockShift() const { return fVolume->BlockShift(); } uint32 BlockShift() const { return fVolume->BlockShift(); }
private: private:
CachedBlock(const CachedBlock &); CachedBlock(const CachedBlock& other);
CachedBlock &operator=(const CachedBlock &); CachedBlock& operator=(const CachedBlock& other);
// no implementation // no implementation
protected: protected:
@@ -64,7 +63,7 @@ class CachedBlock {
inline inline
CachedBlock::CachedBlock(Volume *volume) CachedBlock::CachedBlock(Volume* volume)
: :
fVolume(volume), fVolume(volume),
fBlockNumber(0), fBlockNumber(0),
@@ -74,7 +73,7 @@ CachedBlock::CachedBlock(Volume *volume)
inline inline
CachedBlock::CachedBlock(Volume *volume, off_t block) CachedBlock::CachedBlock(Volume* volume, off_t block)
: :
fVolume(volume), fVolume(volume),
fBlockNumber(0), fBlockNumber(0),
@@ -85,7 +84,7 @@ CachedBlock::CachedBlock(Volume *volume, off_t block)
inline inline
CachedBlock::CachedBlock(Volume *volume, block_run run) CachedBlock::CachedBlock(Volume* volume, block_run run)
: :
fVolume(volume), fVolume(volume),
fBlockNumber(0), fBlockNumber(0),
@@ -96,7 +95,7 @@ CachedBlock::CachedBlock(Volume *volume, block_run run)
inline inline
CachedBlock::CachedBlock(CachedBlock *cached) CachedBlock::CachedBlock(CachedBlock* cached)
: :
fVolume(cached->fVolume), fVolume(cached->fVolume),
fBlockNumber(cached->BlockNumber()), fBlockNumber(cached->BlockNumber()),
@@ -130,42 +129,42 @@ CachedBlock::Unset()
} }
inline const uint8 * inline const uint8*
CachedBlock::SetTo(off_t block, off_t base, size_t length) CachedBlock::SetTo(off_t block, off_t base, size_t length)
{ {
Unset(); Unset();
fBlockNumber = block; fBlockNumber = block;
return fBlock = (uint8 *)block_cache_get_etc(fVolume->BlockCache(), return fBlock = (uint8*)block_cache_get_etc(fVolume->BlockCache(),
block, base, length); block, base, length);
} }
inline const uint8 * inline const uint8*
CachedBlock::SetTo(off_t block) CachedBlock::SetTo(off_t block)
{ {
return SetTo(block, block, 1); return SetTo(block, block, 1);
} }
inline const uint8 * inline const uint8*
CachedBlock::SetTo(block_run run) CachedBlock::SetTo(block_run run)
{ {
return SetTo(fVolume->ToBlock(run)); return SetTo(fVolume->ToBlock(run));
} }
inline uint8 * inline uint8*
CachedBlock::SetToWritable(Transaction &transaction, off_t block, off_t base, CachedBlock::SetToWritable(Transaction& transaction, off_t block, off_t base,
size_t length, bool empty) size_t length, bool empty)
{ {
Unset(); Unset();
fBlockNumber = block; fBlockNumber = block;
if (empty) { if (empty) {
fBlock = (uint8 *)block_cache_get_empty(fVolume->BlockCache(), fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
block, transaction.ID()); block, transaction.ID());
} else { } else {
fBlock = (uint8 *)block_cache_get_writable_etc(fVolume->BlockCache(), fBlock = (uint8*)block_cache_get_writable_etc(fVolume->BlockCache(),
block, base, length, transaction.ID()); block, base, length, transaction.ID());
} }
@@ -173,22 +172,22 @@ CachedBlock::SetToWritable(Transaction &transaction, off_t block, off_t base,
} }
inline uint8 * inline uint8*
CachedBlock::SetToWritable(Transaction &transaction, off_t block, bool empty) CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
{ {
return SetToWritable(transaction, block, block, 1, empty); return SetToWritable(transaction, block, block, 1, empty);
} }
inline uint8 * inline uint8*
CachedBlock::SetToWritable(Transaction &transaction, block_run run, bool empty) CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty)
{ {
return SetToWritable(transaction, fVolume->ToBlock(run), empty); return SetToWritable(transaction, fVolume->ToBlock(run), empty);
} }
inline status_t inline status_t
CachedBlock::MakeWritable(Transaction &transaction) CachedBlock::MakeWritable(Transaction& transaction)
{ {
if (fBlock == NULL) if (fBlock == NULL)
return B_NO_INIT; return B_NO_INIT;
@@ -197,5 +196,4 @@ CachedBlock::MakeWritable(Transaction &transaction)
transaction.ID()); transaction.ID());
} }
#endif // CACHED_BLOCK_H
#endif /* CACHED_BLOCK_H */
@@ -1,56 +0,0 @@
#ifndef CHAIN_H
#define CHAIN_H
/* Chain - a chain implementation; it's used for the callback management
** throughout the code (currently TreeIterator, and AttributeIterator).
**
** Initial version by Axel Dörfler, axeld@pinc-software.de
** This file may be used under the terms of the OpenBeOS License.
*/
#include "system_dependencies.h"
/** The Link class you want to use with the Chain class needs to have
* a "fNext" member which is accessable from within the Chain class.
*/
template<class Link> class Chain {
public:
Chain()
:
fFirst(NULL)
{
}
void Add(Link *link)
{
link->fNext = fFirst;
fFirst = link;
}
void Remove(Link *link)
{
// search list for the correct callback to remove
Link *last = NULL,*entry;
for (entry = fFirst;link != entry;entry = entry->fNext)
last = entry;
if (link == entry) {
if (last)
last->fNext = link->fNext;
else
fFirst = link->fNext;
}
}
Link *Next(Link *last)
{
if (last == NULL)
return fFirst;
return last->fNext;
}
private:
Link *fFirst;
};
#endif /* CHAIN_H */
@@ -596,9 +596,10 @@ Inode::_RemoveSmallData(bfs_inode *node, small_data *item, int32 index)
memset(item, 0, item->Size()); memset(item, 0, item->Size());
// update all current iterators // update all current iterators
AttributeIterator *iterator = NULL; SinglyLinkedList<AttributeIterator>::Iterator iterator
while ((iterator = fIterators.Next(iterator)) != NULL) { = fIterators.GetIterator();
iterator->Update(index, -1); while (iterator.HasNext()) {
iterator.Next()->Update(index, -1);
} }
return B_OK; return B_OK;
@@ -780,9 +781,10 @@ Inode::_AddSmallData(Transaction &transaction, NodeGetter &nodeGetter,
memset(item, 0, (uint8 *)node + fVolume->InodeSize() - (uint8 *)item); memset(item, 0, (uint8 *)node + fVolume->InodeSize() - (uint8 *)item);
// update all current iterators // update all current iterators
AttributeIterator *iterator = NULL; SinglyLinkedList<AttributeIterator>::Iterator iterator
while ((iterator = fIterators.Next(iterator)) != NULL) { = fIterators.GetIterator();
iterator->Update(index, 1); while (iterator.HasNext()) {
iterator.Next()->Update(index, 1);
} }
return B_OK; return B_OK;
@@ -2356,7 +2358,7 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
return B_IS_A_DIRECTORY; return B_IS_A_DIRECTORY;
// we want to open the file, so we should have the rights to do so // we want to open the file, so we should have the rights to do so
if (inode->CheckPermissions(openModeToAccess(openMode)) != B_OK) if (inode->CheckPermissions(open_mode_to_access(openMode)) != B_OK)
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
if (openMode & O_TRUNC) { if (openMode & O_TRUNC) {
+2 -5
View File
@@ -9,7 +9,6 @@
#include "system_dependencies.h" #include "system_dependencies.h"
#include "CachedBlock.h" #include "CachedBlock.h"
#include "Chain.h"
#include "Debug.h" #include "Debug.h"
#include "Journal.h" #include "Journal.h"
#include "Volume.h" #include "Volume.h"
@@ -236,7 +235,7 @@ private:
// the correct keys from the indices // the correct keys from the indices
mutable recursive_lock fSmallDataLock; mutable recursive_lock fSmallDataLock;
Chain<AttributeIterator> fIterators; SinglyLinkedList<AttributeIterator> fIterators;
}; };
#if _KERNEL_MODE && KDEBUG #if _KERNEL_MODE && KDEBUG
@@ -384,7 +383,7 @@ private:
}; };
class AttributeIterator { class AttributeIterator : public SinglyLinkedListLinkImpl<AttributeIterator> {
public: public:
AttributeIterator(Inode* inode); AttributeIterator(Inode* inode);
~AttributeIterator(); ~AttributeIterator();
@@ -394,13 +393,11 @@ public:
ino_t* id); ino_t* id);
private: private:
friend class Chain<AttributeIterator>;
friend class Inode; friend class Inode;
void Update(uint16 index, int8 change); void Update(uint16 index, int8 change);
private: private:
AttributeIterator* fNext;
int32 fCurrentSmallData; int32 fCurrentSmallData;
Inode* fInode; Inode* fInode;
Inode* fAttributes; Inode* fAttributes;
@@ -13,7 +13,6 @@
#endif #endif
#include "Volume.h" #include "Volume.h"
#include "Chain.h"
#include "Utility.h" #include "Utility.h"
+34 -37
View File
@@ -1,6 +1,5 @@
/* Query - query parsing and evaluation /*
* * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2004, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef QUERY_H #ifndef QUERY_H
@@ -8,9 +7,9 @@
#include "system_dependencies.h" #include "system_dependencies.h"
#include "Chain.h"
#include "Index.h" #include "Index.h"
class Volume; class Volume;
class Term; class Term;
class Equation; class Equation;
@@ -19,60 +18,58 @@ class Query;
class Expression { class Expression {
public: public:
Expression(char *expr); Expression(char* expr);
~Expression(); ~Expression();
status_t InitCheck(); status_t InitCheck();
const char *Position() const { return fPosition; } const char* Position() const { return fPosition; }
Term *Root() const { return fTerm; } Term* Root() const { return fTerm; }
protected: protected:
Term *ParseOr(char **expr); Term* ParseOr(char** expr);
Term *ParseAnd(char **expr); Term* ParseAnd(char** expr);
Term *ParseEquation(char **expr); Term* ParseEquation(char** expr);
bool IsOperator(char **expr,char op); bool IsOperator(char** expr, char op);
private: private:
Expression(const Expression &); Expression(const Expression& other);
Expression &operator=(const Expression &); Expression& operator=(const Expression& other);
// no implementation // no implementation
char *fPosition; char* fPosition;
Term *fTerm; Term* fTerm;
}; };
class Query { class Query : public SinglyLinkedListLinkImpl<Query> {
public: public:
Query(Volume *volume, Expression *expression, uint32 flags); Query(Volume* volume, Expression* expression,
uint32 flags);
~Query(); ~Query();
status_t Rewind(); status_t Rewind();
status_t GetNextEntry(struct dirent *, size_t size); status_t GetNextEntry(struct dirent* , size_t size);
void SetLiveMode(port_id port, int32 token); void SetLiveMode(port_id port, int32 token);
void LiveUpdate(Inode *inode, const char *attribute, int32 type, void LiveUpdate(Inode* inode, const char* attribute,
const uint8 *oldKey, size_t oldLength, const uint8 *newKey, size_t newLength); int32 type, const uint8* oldKey,
size_t oldLength, const uint8* newKey,
size_t newLength);
Expression *GetExpression() const { return fExpression; } Expression* GetExpression() const { return fExpression; }
private: private:
Volume *fVolume; Volume* fVolume;
Expression *fExpression; Expression* fExpression;
Equation *fCurrent; Equation* fCurrent;
TreeIterator *fIterator; TreeIterator* fIterator;
Index fIndex; Index fIndex;
Stack<Equation *> fStack; Stack<Equation*> fStack;
uint32 fFlags; uint32 fFlags;
port_id fPort; port_id fPort;
int32 fToken; int32 fToken;
private:
friend class Chain<Query>;
Query *fNext;
}; };
#endif /* QUERY_H */ #endif // QUERY_H
@@ -64,7 +64,7 @@ is_directory(int mode)
file, it will be converted to R_OK. file, it will be converted to R_OK.
*/ */
inline int inline int
openModeToAccess(int openMode) open_mode_to_access(int openMode)
{ {
openMode &= O_RWMASK; openMode &= O_RWMASK;
if (openMode == O_RDONLY) if (openMode == O_RDONLY)
@@ -526,8 +526,9 @@ Volume::UpdateLiveQueries(Inode* inode, const char* attribute, int32 type,
{ {
MutexLocker _(fQueryLock); MutexLocker _(fQueryLock);
Query* query = NULL; SinglyLinkedList<Query>::Iterator iterator = fQueries.GetIterator();
while ((query = fQueries.Next(query)) != NULL) { while (iterator.HasNext()) {
Query* query = iterator.Next();
query->LiveUpdate(inode, attribute, type, oldKey, oldLength, newKey, query->LiveUpdate(inode, attribute, type, oldKey, oldLength, newKey,
newLength); newLength);
} }
+1 -2
View File
@@ -10,7 +10,6 @@
#include "bfs.h" #include "bfs.h"
#include "BlockAllocator.h" #include "BlockAllocator.h"
#include "Chain.h"
class Journal; class Journal;
class Inode; class Inode;
@@ -129,7 +128,7 @@ class Volume {
vint32 fDirtyCachedBlocks; vint32 fDirtyCachedBlocks;
mutex fQueryLock; mutex fQueryLock;
Chain<Query> fQueries; SinglyLinkedList<Query> fQueries;
int32 fUniqueID; int32 fUniqueID;
uint32 fFlags; uint32 fFlags;
@@ -1107,7 +1107,7 @@ bfs_open(fs_volume *_volume, fs_vnode *_node, int openMode, void **_cookie)
//return B_IS_A_DIRECTORY; //return B_IS_A_DIRECTORY;
} }
status_t status = inode->CheckPermissions(openModeToAccess(openMode) status_t status = inode->CheckPermissions(open_mode_to_access(openMode)
| (openMode & O_TRUNC ? W_OK : 0)); | (openMode & O_TRUNC ? W_OK : 0));
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);