* Add AttributeIndex class.
* Each attribute does now have an attribute index cookie. The new
attribute index service methods Node::IndexAttribute() and
IndexCookieForAttribute() create+set/retrieve the cookie. The cookie
is actually the attribute index's tree node.
* Add OldNodeAttribute::IndexCookieForAttribute() so the cookie is
available when the node changes.
* Move tree node operations to a subpolicy TreePolicy.
* Add a GenericIndexIteratorTreePolicy templatized over the policy,
implementing the tree policy for the standard indices.
* AVLTreeMap::_GetKey(): Change return type from const Key& to Key, so
the strategy can do that as well and doesn't have have a Key object in
the node.
* Fix the Auto strategy: It was using the undefined _GetKey() instead
of GetKey().
Add NodeChangeBegin()/NodeChangeEnd() methods that can be used by the
index when the respective node attribute has changed. They make sure
that the iterator doesn't move with the node, should it be inserted into
the index at a different position.
Use TwoKeyAVLTree::FindFirstClosest() instead of FindFirst(), so, if the
value isn't in the index, we find the closest greater value. That's the
semantics Index::InternalFind() is expected to have.
* Add interface OldNodeAttributes an instance of which is passed to
NodeListener::NodeChanged() to provide the old attribute values
(currently only modification time and file size).
* Also extend PackageLinksListener::PackageLinkNodeChanged() with a
OldNodeAttributes parameter.
* Add OldNodeAttributes implementations for PackageLinkSymlink (inner
class OldAttributes) and UnpackingNode (OldUnpackageNodeAttributes).
Add the node listener directly after calling the base class Init().
Otherwise, on error, the we could try to remove the listener although it
wasn't added in the first place.
* Remove Current() and Previous() and add a HasNext() instead.
* Reimplement NameIndexIterator. It directly works with tree nodes
instead of using an iterator, now.
Extended policy by IndexIteratorSuspend() and IndexIteratorResume()
methods that are invoked for the index iterator by Query::GetNextEntry()
after entering respectively before exiting.
both:
* Add Previous()/Next().
* Add Insert() version that returns a Node* instead of an Iterator.
* Add Remove() version that takes a Node* instead of a key.
TwoKeyAVLTree:
* Add GetIterator() version that takes an additional Node*, i.e.
initializing an iterator to point to the node.
* Add Iterator::CurrentNode().
This is a tree implementation with elements with primary and secondary
key. The code is a cleaned up version of ramfs's implementation. ramfs
doesn't use this version yet.
The modules code uses gBootDevice as an indicator that modules can be
loaded from the boot volume. This is not the case until packagefs has
been mounted, though, so we postpone setting gBootDevice.
* Don't only look up the entry attribute when the entry is implicit.
Look it up, when it is a directory instead. This aligns it the logic
with _UpdateCheckEntryCollisions().
* When the entry attribute exits and the entry is not implicit, add file
attributes, but not stat data. This also aligns the logic with
_UpdateCheckEntryCollisions(), which removes colliding attributes, but
keeps stat data.