* Changed the query code again to send B_ENTRY_REMOVED/B_ENTRY_CREATED

notifications if an inode in a query result was moved/renamed - this time all
  the information is correct, though.
* While I did not introduce B_ENTRY_MOVED for queries yet, this should make
  adding it very simple (left as an excercise for the reader ;-))


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34317 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-11-27 16:36:52 +00:00
parent dc28a50219
commit 4ea6fb8bd4
5 changed files with 57 additions and 0 deletions
@@ -1661,3 +1661,31 @@ Query::LiveUpdate(Inode* inode, const char* attribute, int32 type,
} }
} }
void
Query::LiveUpdateRenameMove(Inode* inode, ino_t oldDirectoryID,
const char* oldName, size_t oldLength, ino_t newDirectoryID,
const char* newName, size_t newLength)
{
if (fPort < 0 || fExpression == NULL)
return;
// TODO: check if the attribute is part of the query at all...
status_t oldStatus = fExpression->Root()->Match(inode, "name",
B_STRING_TYPE, (const uint8*)oldName, oldLength);
status_t newStatus = fExpression->Root()->Match(inode, "name",
B_STRING_TYPE, (const uint8*)newName, newLength);
if (oldStatus != MATCH_OK || oldStatus != newStatus)
return;
// The entry stays in the query, notify query listeners about the rename
// or move
notify_query_entry_removed(fPort, fToken, fVolume->ID(),
oldDirectoryID, oldName, inode->ID());
notify_query_entry_created(fPort, fToken, fVolume->ID(),
newDirectoryID, newName, inode->ID());
}
@@ -56,6 +56,10 @@ public:
int32 type, const uint8* oldKey, int32 type, const uint8* oldKey,
size_t oldLength, const uint8* newKey, size_t oldLength, const uint8* newKey,
size_t newLength); size_t newLength);
void LiveUpdateRenameMove(Inode* inode,
ino_t oldDirectoryID, const char* oldName,
size_t oldLength, ino_t newDirectoryID,
const char* newName, size_t newLength);
Expression* GetExpression() const { return fExpression; } Expression* GetExpression() const { return fExpression; }
@@ -535,6 +535,24 @@ Volume::UpdateLiveQueries(Inode* inode, const char* attribute, int32 type,
} }
void
Volume::UpdateLiveQueriesRenameMove(Inode* inode, ino_t oldDirectoryID,
const char* oldName, ino_t newDirectoryID, const char* newName)
{
MutexLocker _(fQueryLock);
size_t oldLength = strlen(oldName);
size_t newLength = strlen(newName);
SinglyLinkedList<Query>::Iterator iterator = fQueries.GetIterator();
while (iterator.HasNext()) {
Query* query = iterator.Next();
query->LiveUpdateRenameMove(inode, oldDirectoryID, oldName, oldLength,
newDirectoryID, newName, newLength);
}
}
/*! Checks if there is a live query whose results depend on the presence /*! Checks if there is a live query whose results depend on the presence
or value of the specified attribute. or value of the specified attribute.
Don't use it if you already have all the data together to evaluate Don't use it if you already have all the data together to evaluate
@@ -117,6 +117,10 @@ public:
const char* attribute, int32 type, const char* attribute, int32 type,
const uint8* oldKey, size_t oldLength, const uint8* oldKey, size_t oldLength,
const uint8* newKey, size_t newLength); const uint8* newKey, size_t newLength);
void UpdateLiveQueriesRenameMove(Inode* inode,
ino_t oldDirectoryID, const char* oldName,
ino_t newDirectoryID, const char* newName);
bool CheckForLiveQuery(const char* attribute); bool CheckForLiveQuery(const char* attribute);
void AddQuery(Query* query); void AddQuery(Query* query);
void RemoveQuery(Query* query); void RemoveQuery(Query* query);
@@ -1156,6 +1156,9 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
inode->WriteLockInTransaction(transaction); inode->WriteLockInTransaction(transaction);
volume->UpdateLiveQueriesRenameMove(inode, oldDirectory->ID(), oldName,
newDirectory->ID(), newName);
// update the name only when they differ // update the name only when they differ
bool nameUpdated = false; bool nameUpdated = false;
if (strcmp(oldName, newName)) { if (strcmp(oldName, newName)) {