* 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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user