Blender V4.3
Cache.hpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Benoit Bolsee
2 *
3 * SPDX-License-Identifier: LGPL-2.1-or-later */
4
9#ifndef CACHE_HPP_
10#define CACHE_HPP_
11
12#include <map>
13
14namespace iTaSC {
15
16#define CACHE_LOOKUP_TABLE_SIZE 128
17#define CACHE_DEFAULT_BUFFER_SIZE 32768
18#define CACHE_CHANNEL_EXTEND_SIZE 10
19#define CACHE_MAX_ITEM_SIZE 0x3FFF0
20
21/* macro to get the alignment gap after an item header */
22#define CACHE_ITEM_GAPB(item) (unsigned int)(((size_t)item+sizeof(CacheItem))&(sizeof(void*)-1))
23/* macro to get item data position, item=CacheItem pointer */
24#define CACHE_ITEM_DATA_POINTER(item) (void*)((unsigned char*)item+sizeof(CacheItem)+CACHE_ITEM_GAPB(item))
25/* macro to get item size in 32bit words from item address and length, item=CacheItem pointer */
26#define CACHE_ITEM_SIZEW(item,length) (unsigned int)((sizeof(CacheItem)+CACHE_ITEM_GAPB(item)+(((length)+3)&~0x3))>>2)
27/* macto to move from one item to the next, item=CacheItem pointer, updated by the macro */
28#define CACHE_NEXT_ITEM(item) ((item)+(item)->m_sizeW)
29#define CACHE_BLOCK_ITEM_ADDR(chan,buf,block) (&(buf)->m_firstItem+(((unsigned int)(block)<<chan->m_positionToBlockShiftW)+(buf)->lookup[block].m_offsetW))
30#define CACHE_ITEM_ADDR(buf,pos) (&(buf)->m_firstItem+(pos))
31#define CACHE_ITEM_POSITIONW(buf,item) (unsigned int)(item-&buf->m_firstItem)
32
33typedef unsigned int CacheTS;
34
35struct Timestamp
36{
40 unsigned int numstep:8;
41 unsigned int substep:1;
42 unsigned int reiterate:1;
43 unsigned int cache:1;
44 unsigned int update:1;
45 unsigned int interpolate:1;
46 unsigned int dummy:19;
47
48 Timestamp() { memset(this, 0, sizeof(Timestamp)); }
49};
50
51/* utility function to return second timestamp to millisecond */
52inline void setCacheTimestamp(Timestamp& timestamp)
53{
54 if (timestamp.realTimestamp < 0.0 || timestamp.realTimestamp > 4294967.295)
55 timestamp.cacheTimestamp = 0;
56 else
57 timestamp.cacheTimestamp = (CacheTS)(timestamp.realTimestamp*1000.0+0.5);
58}
59
60
61/*
62class Cache:
63Top level class, only one instance of this class should exists.
64A device (=constraint, object) uses this class to create a cache entry for its data.
65A cache entry is divided into cache channels, each providing a separate buffer for cache items.
66The cache channels must be declared by the devices before they can be used.
67The device must specify the largest cache item (limited to 256Kb) so that the cache
68buffer can be organized optimally.
69Cache channels are identified by small number (starting from 0) allocated by the cache system.
70Cache items are inserted into cache channels ordered by timestamp. Writing is always done
71at the end of the cache buffer: writing an item automatically clears all items with
72higher timestamp.
73A cache item is an array of bytes provided by the device; the format of the cache item is left
74to the device.
75The device can retrieve a cache item associated with a certain timestamp. The cache system
76returns a pointer that points directly in the cache buffer to avoid unnecessary copy.
77The pointer is guaranteed to be pointer aligned so that direct mapping to C structure is possible
78(=32 bit aligned on 32 systems and 64 bit aligned on 64 bits system).
79
80Timestamp = rounded time in millisecond.
81*/
82
83struct CacheEntry;
84struct CacheBuffer;
85struct CacheItem;
86struct CacheChannel;
87
88class Cache
89{
90private:
91 /* map between device and cache entry.
92 Dynamically updated when more devices create cache channels */
93 typedef std::map<const void *, struct CacheEntry*> CacheMap;
94 CacheMap m_cache;
95 const CacheItem *getCurrentCacheItemInternal(const void *device, int channel, CacheTS timestamp);
96
97public:
98 Cache();
99 ~Cache();
100 /* add a cache channel, maxItemSize must be < 256k.
101 name : channel name, truncated at 31 characters
102 msxItemSize : maximum size of item in bytes, items of larger size will be rejected
103 return value >= 0: channel id, -1: error */
104 int addChannel(const void *device, const char *name, unsigned int maxItemSize);
105
106 /* delete a cache channel (and all associated buffers and items) */
107 int deleteChannel(const void *device, int channel);
108 /* delete all channels of a device and remove the device from the map */
109 int deleteDevice(const void *device);
110 /* removes all cache items, leaving the special item at timestamp=0.
111 if device=NULL, apply to all devices. */
112 void clearCacheFrom(const void *device, CacheTS timestamp);
113
114 /* add a new cache item
115 channel: the cache channel (as returned by AddChannel
116 data, length: the cache item and length in bytes
117 If data is NULL, the memory is allocated in the cache but not writen
118 return: error: NULL, success: pointer to item in cache */
119 void *addCacheItem(const void *device, int channel, CacheTS timestamp, void *data, unsigned int length);
120
121 /* specialized function to add a vector of double in the cache
122 It will first check if a vector exist already in the cache for the same timestamp
123 and compared the cached vector with the new values.
124 If all values are within threshold, the vector is updated but the cache is not deleted
125 for the future timestamps. */
126 double *addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold);
127
128 /* returns the cache item with timestamp that is just before the given timestamp.
129 returns the data pointer or NULL if there is no cache item before timestamp.
130 On return, timestamp is updated with the actual timestamp of the item being returned.
131 Note that the length of the item is not returned, it is up to the device to organize
132 the data so that length can be retrieved from the data if needed.
133 Device can NULL, it will then just look the first channel available, useful to
134 test the status of the cache. */
135 const void *getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp);
136
137 /* returns the cache item with the timestamp that is exactly equal to the given timestamp
138 If there is no cache item for this timestamp, returns NULL.*/
139 const void *getCurrentCacheItem(const void *device, int channel, CacheTS timestamp);
140
141};
142
143/* the following structures are not internal use only, they should not be used directly */
144
146{
147 CacheChannel *m_channelArray; // array of channels, automatically resized if more channels are created
148 unsigned int m_count; // number of channel in channelArray
150 ~CacheEntry();
151};
152
154{
155 CacheItem* initItem; // item corresponding to timestamp=0
156 struct CacheBuffer *m_firstBuffer; // first buffer of list
157 struct CacheBuffer *m_lastBuffer; // last buffer of list to which an item was written
158 char m_name[32]; // channel name
159 unsigned char m_busy; // =0 if channel is free, !=0 when channel is in use
160 unsigned char m_positionToBlockShiftW; // number of bits to shift a position in word to get the block number
161 unsigned short m_positionToOffsetMaskW; // bit mask to apply on a position in word to get offset in a block
162 unsigned int m_maxItemSizeB; // maximum item size in bytes
163 unsigned int m_bufferSizeW; // size of item buffer in word to allocate when a new buffer must be created
164 unsigned int m_blockSizeW; // block size in words of the lookup table
165 unsigned int m_lastTimestamp; // timestamp of the last item that was written
166 unsigned int m_lastItemPositionW; // position in words in lastBuffer of the last item written
167 void clear();
169 CacheItem* findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer);
170 CacheItem* findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer);
171 // Internal function: finds an item in a buffer that is < timeOffset
172 // timeOffset must be a valid offset for the buffer and the buffer must not be empty
173 // on return highBlock contains the block with items above or equal to timeOffset
174 CacheItem *_findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *highBlock);
175};
176
178 unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
179 unsigned short m_offsetW; // position in words of item relative to start of block
180};
181
182/* CacheItem is the header of each item in the buffer, must be 32bit
183 Items are always 32 bits aligned and size is the number of 32 bit words until the
184 next item header, including an eventual pre and post padding gap for pointer alignment */
186{
187 unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
188 unsigned short m_sizeW; // size of item in 32 bit words
189 // item data follows header immediately or after a gap if position is not pointer aligned
190};
191
192// Buffer header
193// Defined in a macro to avoid sizeof() potential problem.
194// next for linked list. = NULL for last buffer
195// m_firstTimestamp timestamp of first item in this buffer
196// m_lastTimestamp timestamp of last item in this buffer
197// m_lastTimestamp must be < m_firstTimestamp+65536
198// m_lastItemPositionW position in word of last item written
199// m_firstFreePositionW position in word where a new item can be written, 0 if buffer is empty
200// lookup lookup table for fast access to item by timestamp
201// The buffer is divided in blocks of 2**n bytes with n chosen so that
202// there are no more than CACHE_LOOKUP_TABLE_SIZE blocks and that each
203// block will contain at least one item.
204// Each element of the lookup table gives the timestamp and offset
205// of the last cache item occupying (=starting in) the corresponding block.
206#define CACHE_HEADER \
207 struct CacheBuffer *m_next; \
208 unsigned int m_firstTimestamp; \
209 unsigned int m_lastTimestamp; \
210 \
211 unsigned int m_lastItemPositionW; \
212 unsigned int m_firstFreePositionW;\
213 struct CacheBlock lookup[CACHE_LOOKUP_TABLE_SIZE]
214
218#define CACHE_BUFFER_HEADER_SIZE (sizeof(struct CacheBufferHeader))
220{
222 struct CacheItem m_firstItem; // the address of this field marks the start of the buffer
223};
224
225
226}
227
228#endif /* CACHE_HPP_ */
const void * getCurrentCacheItem(const void *device, int channel, CacheTS timestamp)
Definition Cache.cpp:596
void clearCacheFrom(const void *device, CacheTS timestamp)
Definition Cache.cpp:324
int deleteChannel(const void *device, int channel)
Definition Cache.cpp:292
int addChannel(const void *device, const char *name, unsigned int maxItemSize)
Definition Cache.cpp:202
int deleteDevice(const void *device)
Definition Cache.cpp:309
void * addCacheItem(const void *device, int channel, CacheTS timestamp, void *data, unsigned int length)
Definition Cache.cpp:406
double * addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold)
Definition Cache.cpp:602
const void * getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp)
Definition Cache.cpp:546
#define NULL
void setCacheTimestamp(Timestamp &timestamp)
Definition Cache.hpp:52
unsigned int CacheTS
Definition Cache.hpp:33
unsigned short m_offsetW
Definition Cache.hpp:179
unsigned short m_timeOffset
Definition Cache.hpp:178
struct CacheItem m_firstItem
Definition Cache.hpp:222
CacheItem * _findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *highBlock)
Definition Cache.cpp:25
struct CacheBuffer * m_firstBuffer
Definition Cache.hpp:156
unsigned int m_maxItemSizeB
Definition Cache.hpp:162
unsigned int m_blockSizeW
Definition Cache.hpp:164
CacheItem * initItem
Definition Cache.hpp:155
struct CacheBuffer * m_lastBuffer
Definition Cache.hpp:157
CacheBuffer * allocBuffer()
Definition Cache.cpp:88
unsigned char m_positionToBlockShiftW
Definition Cache.hpp:160
unsigned int m_lastItemPositionW
Definition Cache.hpp:166
unsigned int m_bufferSizeW
Definition Cache.hpp:163
unsigned char m_busy
Definition Cache.hpp:159
CacheItem * findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer)
Definition Cache.cpp:137
unsigned short m_positionToOffsetMaskW
Definition Cache.hpp:161
CacheItem * findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer)
Definition Cache.cpp:100
unsigned int m_lastTimestamp
Definition Cache.hpp:165
unsigned int m_count
Definition Cache.hpp:148
CacheChannel * m_channelArray
Definition Cache.hpp:147
unsigned short m_timeOffset
Definition Cache.hpp:187
unsigned short m_sizeW
Definition Cache.hpp:188
unsigned int interpolate
Definition Cache.hpp:45
double realTimestep
Definition Cache.hpp:38
unsigned int cache
Definition Cache.hpp:43
CacheTS cacheTimestamp
Definition Cache.hpp:39
double realTimestamp
Definition Cache.hpp:37
unsigned int reiterate
Definition Cache.hpp:42
unsigned int dummy
Definition Cache.hpp:46
unsigned int substep
Definition Cache.hpp:41
unsigned int numstep
Definition Cache.hpp:40
unsigned int update
Definition Cache.hpp:44