Thanks for the clear example. However, maybe the idioms are confusing me, but many-to-many tells me that I should be able to do something like:<br><br>(setf (friends-of person1) person2)<br>(setf (friends-of person1) person3)<br>

(setf (friends-of person1) person4)<br>
(setf (friends-of person1) person5)<br>
<br>(setf (friends-of person2) person3)<br><br>such that:<br><br>(friends-of person1) => (person2 person3 person4 person5)<br>(friends-of person2) => (person1 person3)<br>(friends-of person3) => (person1 person2)<br>
(friends-of person4) => person1<br>(friends-of person5) => person1<br><br>Would that be the expected behavior?<br><br>Best regards,<br>JD<br><br><div class="gmail_quote">On Tue, Jan 27, 2009 at 3:22 PM, Ian Eslick <span dir="ltr"><<a href="mailto:eslick@media.mit.edu">eslick@media.mit.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Slot associations appear to work reflexively, by the way.<br>
<br>
(defpclass self-assoc ()<br>
            ((friends-of :accessor friends-of<br>
                         :associate (self-assoc friended-me)<br>
                         :many-to-many t)<br>
             (friended-me :accessor friended-me<br>
                       :associate (self-assoc friends-of)<br>
                       :many-to-many t)))<br>
<br>
This simply says I have an association among self-assoc instances.<br>
Any (setf (friends-of person1) person2) says that person2 is a friend-<br>
of person1.  Automatically, you get the inverse mapping which is that<br>
person1 friended person2 (assuming these associations are directional).<br>
<br>
If they are not directional, then you can do this:<br>
(defpclass person ()<br>
   ((friends :accessor friends-of<br>
        :associate (person friends) :many-to-many t)))<br>
<br>
Now if you (setf (friends-of person1) person2), you will get:<br>
<br>
(friends-of person1) => person2<br>
(friends-of person2) => person1<br>
<br>
This is a non-directional relationship between two entities so there's<br>
no need for two slots.<br>
<br>
This all seems to work well in the current Alpha 2.<br>
<font color="#888888"><br>
Ian<br>
</font><div><div></div><div class="Wj3C7c"><br>
On Jan 27, 2009, at 1:32 PM, Ian Eslick wrote:<br>
<br>
><br>
> On Jan 27, 2009, at 11:00 AM, John wrote:<br>
>><br>
>> 1) Every read/write of pclass slots is done directly from/to the<br>
>> database, so no in-memory "copy" exists (unless some sort of<br>
>> transient cache slot model is used). This is good. However, is<br>
>> Elephant "intelligent" enough so that if you attempt to setf a slot<br>
>> value with the same value stored in the slot, Elephant will "avoid"<br>
>> the writing to the database, since the value hasn't really changed?<br>
>> If that's not the out-of-the-box behavior, I pressume that it would<br>
>> be relatively easy to add this functionality using MOP. I also<br>
>> assume that doing this will require another read before the write in<br>
>> order to compare the value to be written, but then again, Elephant<br>
>> claims that reads are much cheaper than writes.<br>
>><br>
><br>
> Such a thing would be possible, but you would need to have a local<br>
> copy of the value in memory and this could create more problems than<br>
> it solves.  It's also unclear to me how common this case.  I don't<br>
> write the same value to the same slot very often!<br>
><br>
>> 2) According to Oracle: "Berkeley DB includes support for building<br>
>> highly available applications based on replication..." (<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/ref/rep/intro.html" target="_blank">http://www.oracle.com/technology/documentation/berkeley-db/db/ref/rep/intro.html</a><br>

>> ) So, I assume that in the event that a single machine becomes<br>
>> unable to handle the load of a busy application, BDB supports<br>
>> replication to multiple machines with near-instant replication<br>
>> effects (performance is inversly proportional to replication speed).<br>
>> So, the question is, can Elephant accommodate to this model? If I<br>
>> read correctly, the manual states that elephant maintains a weak<br>
>> hash of persistent objects. So, if BDB is deployed in a distributed<br>
>> model and Elephant is running in each separate machine, we could in<br>
>> theory "trust" that the data read/written from/to disk will be all<br>
>> in sync across all machines (as long as database IO on same object/<br>
>> slot occurs at a frequency greater than the replication rate). The<br>
>> question I have is with the weak hash. If a write is made in one<br>
>> machine, the data on disk is updated across all machines. However,<br>
>> the weak hash remains stale in the machines were the data was only<br>
>> replicated to. Is this an actual problem or does Elephant use the<br>
>> weak hash "intelligently" to recover in the event that the weak hash<br>
>> becomes "unexpectedly" stale?<br>
><br>
> The weak hash is simply used to speed up the 'recreation' of a<br>
> persistent reference when it is deserialized from the underlying<br>
> storage medium (BDB in this case) so fits into this model.  I've<br>
> looked several times at building-in the support to enable a full<br>
> replication model for BDB, but it's a fair bit of work to deal with<br>
> the single-master requirement for replication and distributed<br>
> transactions for global coherence. The write performance and<br>
> contention performance may decline noticeably, but conflict-free read<br>
> performance should be the same as in the non-replicated case.  I don't<br>
> fully understand all these issues yet and am prioritizing a lisp-only<br>
> Prevalence style backend in my development roadmap.<br>
><br>
>> 3) I come from a RDBMS world, so I'm still learning the modalities<br>
>> of connected objects vs just related rows. So, reading the tutorials<br>
>> you describe a friends model using PSets. So, imagine a concept<br>
>> similar to Facebook in terms of a friends database. I have millions<br>
>> of people created in the system and they all create their list of<br>
>> friends. Some people may have "few" or no friends while others could<br>
>> have hundreds of thousands of friends (e.g. Pres. Obama). Are PSets<br>
>> the correct way to model this for larger number of objects or is<br>
>> there a more appropriate methodology recommended in Elephant?<br>
>> Obviously the idea behind this is so that you could perform<br>
>> manipulations on these "friends" relatively easy, such as add/remove<br>
>> friends or perform global queries as to list all friends of people<br>
>> who are friends of Pres. Obama. There are references on the list<br>
>> about a query system being worked on and some vanilla version being<br>
>> available, but independently of that, I think my question is more<br>
>> related to the object model implementation. Maybe I'm wrong.<br>
><br>
> Psets today are a convenience API around the BTree that can be<br>
> overridden by data stores later for more efficient implementation<br>
> (e.g. hash vs. tree) as appropriate for that store.  BTrees are cheap<br>
> for BDB to create and use so use of them at any size is fine.  You<br>
> might want to wrap an abstraction around the BTree directly since the<br>
> pset API is an un-ordered set.  If you want to do range extraction or<br>
> set intersection you'll want the btree's support for ordered objects.<br>
><br>
> The query system currently doesn't support psets, although it should<br>
> eventually.<br>
><br>
> Slot-associations currently don't deal with reflexive references<br>
> (associations among instances of a single class), but that would also<br>
> address the 'friends-of' problem.<br>
><br>
> I hope you enjoy elephant!  If you want to add/implement or spec out<br>
> some of these changes you are thinking about, I'd be happy to support<br>
> you.<br>
><br>
> Cheers,<br>
> Ian<br>
><br>
>> Anyway, thank you for your help in advanced. Look forward to hearing<br>
>> back from anyone soon and keep learning more about Elephant.<br>
>><br>
>> Thanks,<br>
>> JD<br>
>> _______________________________________________<br>
>> elephant-devel site list<br>
>> <a href="mailto:elephant-devel@common-lisp.net">elephant-devel@common-lisp.net</a><br>
>> <a href="http://common-lisp.net/mailman/listinfo/elephant-devel" target="_blank">http://common-lisp.net/mailman/listinfo/elephant-devel</a><br>
><br>
><br>
> _______________________________________________<br>
> elephant-devel site list<br>
> <a href="mailto:elephant-devel@common-lisp.net">elephant-devel@common-lisp.net</a><br>
> <a href="http://common-lisp.net/mailman/listinfo/elephant-devel" target="_blank">http://common-lisp.net/mailman/listinfo/elephant-devel</a><br>
<br>
<br>
_______________________________________________<br>
elephant-devel site list<br>
<a href="mailto:elephant-devel@common-lisp.net">elephant-devel@common-lisp.net</a><br>
<a href="http://common-lisp.net/mailman/listinfo/elephant-devel" target="_blank">http://common-lisp.net/mailman/listinfo/elephant-devel</a><br>
</div></div></blockquote></div><br>