Ptex
|
LRU Cache Implementation. More...
#include "PtexPlatform.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <iostream>
#include <ctype.h>
#include "Ptexture.h"
#include "PtexReader.h"
#include "PtexCache.h"
Go to the source code of this file.
Classes | |
class | PtexReaderCache |
Cache for reading Ptex texture files. More... | |
LRU Cache Implementation.
Ownership. The cache owns all files and data. If an object is in use, the cache will not delete it. When it is no longer in use, it may be kept or may be deleted to keep resource usage under the set limits. Deletions are done in lru order.
Resource Tracking. All objects are created as part of the cache and have a ptr back to the cache. Each object updates the cache's resource total when it is created or deleted. Unused objects are kept in an lru list in the cache. Only objects in the lru list can be deleted.
Reference Counting. Every object has a ref count to track whether it is being used. But objects don't generally ref their parent or children (otherwise nothing would get freed).
A data handle must hold onto (and ref) all the objects it is using or may need in the future. E.g. For a non-tiled face, this is just the single face data block. For a tiled face, the file, the tiled face, and the current tile must all be ref'd.
Parents, Children, and Orphans. Every object must be reachable by some other object, generally the object that created it, i.e. it's parent. Even though the parent doesn't own it's children (the cache does), it must still track them. Parentless objects (i.e. orphans) are not reachable and are not retained in the cache.
When any object is deleted (file, tiled face, etc.), it must orphan its children. If an orphaned child is not in use, then it is immediately deleted. Otherwise, the child's parent ptr is set to null and the child is deleted when it is no longer in use. A parent may also orphan a child that it no longer needs; the behavior is the same.
Each object stores a ptr to its own entry within its parent. When the object is deleted by the cache, it clears this pointer so that the parent no longer sees it.
Cache LifeTime. When a cache is released from its owner, it will delete itself but only after all objects it owns are no longer in use. To do this, a ref count on the cache is used. The owner holds 1 ref (only one owner allowed), and each object holds a ref (maintained internally).
Threading. To fully support multi-threading, the following data structures must be protected with a mutex: the cache lru lists, ref counts, and parent/child ptrs. This is done with a single mutex per cache. To avoid the need for recursive locks and to minimize the number of lock points, this mutex is locked and unlocked primarily at the external api boundary for methods that affect the cache state: (e.g. getMetaData, getData, getTile, release, purge, and purgeAll). Care must be taken to release the cache lock when calling any external api from within the library.
Also, in order to prevent thread starvation, the cache lock is released during file reads and significant computation such as generating an image data reduction. Additional mutexes are used to prevent contention in these cases:
Definition in file PtexCache.cpp.