5b75942013-09-21Henrik Grubbström (Grubba) //! A RAM-based storage manager. //! //! This storage manager provides the means to save data to memory. //! In this manager I'll add reference documentation as comments to //! interfaces. It will be organized later in a more comprehensive format //! //! Settings will be added later. //! //! @thanks
0ab1892013-10-05Henrik Grubbström (Grubba) //! Thanks to Francesco Chemolli <kinkie@@roxen.com> for the contribution.
2fe7462000-07-02Francesco Chemolli 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
5b75942013-09-21Henrik Grubbström (Grubba) //!
2fe7462000-07-02Francesco Chemolli class Data { inherit Cache.Data;
3524712015-05-26Martin Nilsson 
2fe7462000-07-02Francesco Chemolli  int _size=0; mixed _data=0;
8b8c2f2001-01-01Francesco Chemolli  multiset(string) _deps;
3524712015-05-26Martin Nilsson 
66b2442019-04-16Henrik Grubbström (Grubba)  protected void create(void|mixed value, void|int abs_expire_time, void|float preciousness, void|multiset(string) dependants) {
2fe7462000-07-02Francesco Chemolli  _data=value; atime=ctime=time(1); if (abs_expire_time) etime=abs_expire_time; if (preciousness) cost=preciousness;
8b8c2f2001-01-01Francesco Chemolli  if (dependants) _deps=dependants;
2fe7462000-07-02Francesco Chemolli  }
3524712015-05-26Martin Nilsson 
2fe7462000-07-02Francesco Chemolli  int size() { if (_size) return _size; return (_size=recursive_low_size(_data)); }
3524712015-05-26Martin Nilsson 
2fe7462000-07-02Francesco Chemolli  mixed data() { return _data; }
3524712015-05-26Martin Nilsson 
2fe7462000-07-02Francesco Chemolli } inherit Cache.Storage.Base; private mapping(string:mixed) data=([]); /* * First an iterator over the contents. * Since accesses to the data are not serialized to increase efficiency * there are a few guidelines that must be followed in order to maintain * consistency. * * First off, only one entity must be using the iterator at one time. * That's not as bad as it seems, as the only entity needing to enumerate * the entries in cache is the expiration policy manager, and there can * be only one for each storage manager. * * The enumerator over the cache is initialized by a call to first(). * Subsequent calls to next() return following entries in the cache.
3524712015-05-26Martin Nilsson  * While it is guarranteed that each and all entries in the cache
2fe7462000-07-02Francesco Chemolli  * will be iterated upon by the enumerator, their order is NOT guarranteed * to remain consistent across calls. */ // these are used by the enumerator. While entries might be deleted while // enumerating, it won't bite us. private array(string) iter=0; private int current=0; int(0..0)|string first() { iter=indices(data); current=0; return next(); } int(0..0)|string next() {
8b8c2f2001-01-01Francesco Chemolli  if (iter && current < sizeof(iter) && data[iter[current]])
2fe7462000-07-02Francesco Chemolli  return iter[current++]; iter=0; return 0; } /* * Guess what these do? * I leave the data-object creation here, so that the storage manager * can choose whatever data-class it pleases */ void set(string key, mixed value,
3524712015-05-26Martin Nilsson  void|int absolute_expire,
8b8c2f2001-01-01Francesco Chemolli  void|float preciousness, void|multiset(string) dependants) { data[key]=Data(value,absolute_expire,preciousness,dependants);
2fe7462000-07-02Francesco Chemolli }
5b75942013-09-21Henrik Grubbström (Grubba) //! Fetches some data from the cache. If notouch is set, don't touch the //! data from the cache (meant to be used by the storage manager only)
2fe7462000-07-02Francesco Chemolli int(0..0)|Cache.Data get(string key, void|int notouch) { mixed tmp; tmp=data[key]; if (!notouch && tmp) tmp->touch(); return tmp; }
3524712015-05-26Martin Nilsson void aget(string key,
2fe7462000-07-02Francesco Chemolli  function(string,int(0..0)|Cache.Data:void) callback) { mixed rv=get(key); callback(key,rv); }
d53e232000-07-05Francesco Chemolli void delete(string key, void|int(0..1) hard) {
2fe7462000-07-02Francesco Chemolli  object(Cache.Data) rv=data[key];
8b8c2f2001-01-01Francesco Chemolli  if (!rv) return; multiset deps=rv->_deps;
3524712015-05-26Martin Nilsson 
8b8c2f2001-01-01Francesco Chemolli  //need to destruct this first, or we might infinite-loop recursing //through the dependants (think of a bug listing a value depending //on itself, or even worse, circularly.
2fe7462000-07-02Francesco Chemolli  if (hard) { destruct(rv->value()); } m_delete(data,key);
8b8c2f2001-01-01Francesco Chemolli  if (deps) { foreach((array)(deps), string dep) { delete(dep,hard); } }
d53e232000-07-05Francesco Chemolli  return 0;
2fe7462000-07-02Francesco Chemolli }