Skip to content

Commit

Permalink
Done with Group for now.
Browse files Browse the repository at this point in the history
I think that's a wrap for the first release of the docs.
  • Loading branch information
dotsdl committed Mar 22, 2016
1 parent a51e0c6 commit fa91e45
Showing 1 changed file with 45 additions and 37 deletions.
82 changes: 45 additions & 37 deletions docs/groups.rst
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
====================================
Leveraging Groups for aggregate data
====================================
A **Group** is a special type of Treant that can keep track of any number of
Treants it counts as members. Just as a normal Treant can be used to manage
data obtained from a single study, a Group is useful for managing data obtained
==============================
Persistent Bundles with Groups
==============================
A **Group** is a Treant that can keep track of any number of Treants it counts
as members. It can be thought of as having a persistent Bundle attached to it,
with that Bundle's membership information stored inside the Group's state file.
Since Groups are themselves Treants, they are useful for managing data obtained
from a collection of Treants in aggregate.

.. note:: Since Groups are Treants, everything that applies to Treants applies
to Groups as well. They have their own tags, categories, and
directory trees, independent of those of their members.

As with a normal Treant, to generate a Group from scratch, we need only give it
a name ::

>>> from datreant.core import Group
>>> g = Group('gruffy')
>>> g = Group('forest')
>>> g
<Group: 'gruffy'>
<Group: 'forest'>

We can also give any number of existing Treants to add them as
members, including other Groups ::

>>> members=[s1, s2, s3, g4, g5])
<Group: 'gruffy' | 5 Members>
>>> g.members.add('sequoia', 'maple', 'oak', 'elm')
>>> g
<Group: 'forest' | 4 Members>

This will create a directory ``gruffy`` that contains a single file
(``Group.<uuid>.json``). That file is a persistent representation of the Group
on disk. We can access its members with ::
We can access its members directly with::

>>> g.members
<MemberBundle(['marklar', 'scruffy', 'fluffy', 'buffy', 'gorp'])>
>>> g.members[2]
<Treant: 'fluffy'>
<MemberBundle([<Treant: 'sequoia'>, <Treant: 'maple'>, <Treant: 'oak'>, <Treant: 'elm'>])>

and we can slice, too ::
which yields a **MemberBundle**. This object works exactly the same as a
Bundle, with the only difference that the order and contents of its membership
are stored within the Group's state file. Obtaining subsets of the
MemberBundle, such as by slicing, indexing, filtering on tags, etc., will
always yield a Bundle::

>>> g.members[2:]
[<Treant: 'fluffy'>, <Group: 'buffy'>, <Group: 'gorp'>]
>>>> g.members[2:]
<Bundle([<Treant: 'oak'>, <Treant: 'elm'>])>

.. note:: Members are generated from their state files on disk upon access.
This means that for a Group with hundreds of members, there will
Expand All @@ -43,30 +49,32 @@ A Group can even be a member of itself ::

>>> g.members.add(g)
>>> g
<Group: 'gruffy' | 6 Members: 3 Treant, 3 Group>
<Group: 'forest' | 5 Members>
>>> g.members[-1]
<Group: 'gruffy' | 6 Members: 3 Treant, 3 Group>
>>> g.members[-1].members[-1]
<Group: 'gruffy' | 6 Members: 3 Treant, 3 Group>

As an aside, note that a Group returned as a member of itself is not the same
object in memory as the Group that returned it. They are two different
instances of the same Group ::

>>> g2 = g.members[-1]
>>> g2 is g
False
<Group: 'forest' | 5 Members>

But since they pull their state from the same file on disk, they will reflect
the same stored information at all times ::
>>> g.tags.add('oaks')
>>> g2.tags
<Tags(['oaks'])>

Groups find their members when they go missing
==============================================
For each member Treant, a Group stores the Treant's type ('Treant', 'Group'),
its uuid, and last known absolute and relative locations. Since Treants are
directories in the filesystem, they can very well be moved. What happens
when we load up an old Group whose members may no longer be where they once
were?

Upon access to its MemberBundle, a Group will try its best to track down its
members. It will first check the last known locations for each member, and
for those it has yet to find it will begin a downward search starting from its
own tree, then its parent tree, etc. It will continue this process until it
either finds all its members, hits the root of the filesystem, or its search
times out.

If the Group you are using fails to find some of its members before timing out,
you can set the maximum search time to a longer timeout, in seconds::

>>> g.members.searchtime = 60

Otherwise, you will need to remove the missing members or find them yourself.


API Reference: Group
Expand Down

0 comments on commit fa91e45

Please sign in to comment.