1/*
2******************************************************************************
3* Copyright (C) 2014, International Business Machines Corporation and
4* others. All Rights Reserved.
5******************************************************************************
6*
7* File LRUCACHE.H
8******************************************************************************
9*/
10
11#ifndef __LRU_CACHE_H__
12#define __LRU_CACHE_H__
13
14#include "unicode/uobject.h"
15#include "sharedobject.h"
16
17struct UHashtable;
18
19U_NAMESPACE_BEGIN
20
21/**
22 * LRUCache keyed by locale ID.
23 */
24
25class U_COMMON_API LRUCache : public UObject {
26public:
27    template<typename T>
28    void get(const char *localeId, const T *&ptr, UErrorCode &status) {
29        const T *value = (const T *) _get(localeId, status);
30        if (U_FAILURE(status)) {
31            return;
32        }
33        SharedObject::copyPtr(value, ptr);
34    }
35    UBool contains(const char *localeId) const;
36    virtual ~LRUCache();
37protected:
38    virtual SharedObject *create(const char *localeId, UErrorCode &status)=0;
39    LRUCache(int32_t maxSize, UErrorCode &status);
40private:
41    class CacheEntry : public UMemory {
42    public:
43        CacheEntry *moreRecent;
44        CacheEntry *lessRecent;
45        char *localeId;
46        const SharedObject *cachedData;
47        UErrorCode status;  // This is the error if any from creating
48                            // cachedData.
49        CacheEntry();
50        ~CacheEntry();
51
52        void unlink();
53        void reset();
54        void init(
55               char *adoptedLocId, SharedObject *dataToAdopt, UErrorCode err);
56    private:
57        CacheEntry(const CacheEntry& other);
58        CacheEntry &operator=(const CacheEntry& other);
59    };
60    LRUCache();
61    LRUCache(const LRUCache &other);
62    LRUCache &operator=(const LRUCache &other);
63
64    // TODO (Travis Keep): Consider replacing both of these end nodes with a
65    // single sentinel.
66    CacheEntry *mostRecentlyUsedMarker;
67    CacheEntry *leastRecentlyUsedMarker;
68    UHashtable *localeIdToEntries;
69    int32_t maxSize;
70
71    void moveToMostRecent(CacheEntry *cacheEntry);
72    void init(char *localeId, CacheEntry *cacheEntry);
73    const SharedObject *_get(const char *localeId, UErrorCode &status);
74};
75
76typedef SharedObject *CreateFunc(const char *localeId, UErrorCode &status);
77
78class U_COMMON_API SimpleLRUCache : public LRUCache {
79public:
80    SimpleLRUCache(
81        int32_t maxSize,
82        CreateFunc cf,
83        UErrorCode &status) :
84            LRUCache(maxSize, status), createFunc(cf) {
85    }
86    virtual ~SimpleLRUCache();
87protected:
88    virtual SharedObject *create(const char *localeId, UErrorCode &status);
89private:
90    CreateFunc *createFunc;
91};
92
93U_NAMESPACE_END
94
95#endif
96