rubyidentity-map

Ruby implementations of the identity map pattern


I am planning to implement an identity map for a small project which is not using any ORM tool.

The standard implementation in most examples I have seen is just a hash by object id, however it is obvious that the hash will grow without limits. I was thinking in using memcahed or redis with a cache expiration, but that also means that some objects will expire in the cache and their data will be fetched once time again from the database under a new and different object (same entity under different objects in memory).

Considering that most ORMs do not require a running memcached/redis. How do they solve this problem? Do they actually solve it? is it not a concern having an entity represented by repeated instances?

The only solution I know of is in languages supporting smart pointers and storing weak references within the hash. It does not look to me that such approach could be taken with Ruby, so I am wondering how is this pattern normally implemented by Ruby ORMs.


Solution

  • I think they do use a Hash, certainly appears that DataMapper uses a hash. My presumption is that the identity map is per 'session', which is probably flushed after each request (also ensures transactions are flushed by the end of request boundary). Thus it can grow unbounded but has a fixed horizon that clears it. If the intention is to have a session that lasts longer and needs periodic cleaning then WeakRef might be useful. I would be cautious about maintaining an identity map for an extended period however, particularly if concurrency is involved and there are any expectations for consistent transactional changes. I know ActiveRecord considered adding an IdentityMap and then abandoned that effort. Depending on how rows are fetched there may be duplication, but it's probably less then you would think, OR the query should be re-thought.