我实际场景中没有用到缓存,所有结果都保存在内存中的,所以没有研究。
缓存优化代码直接使用微软官方的,逻辑我没有改动,只是把c++变成vba。
在从数据库中查询巨量数据集时,或者结果需要非常耗时的运算时,可以使用缓存。
以下为缓存处理的微软原文:
优化缓存
当显示区域的内容发生更改时,虚拟列表视图控件会发送 [color=var(--theme-hyperlink)]LVN_ODCACHEHINT 通知消息。 该消息包含有关要缓存的项范围的信息。 收到通知消息后,应用程序必须准备好使用所请求范围的项信息加载缓存,以便发送 [color=var(--theme-hyperlink)]LVN_GETDISPINFO 通知消息时,该信息将随时可用。 在以下 C++ 代码示例中,应用程序定义的函数接受虚拟列表视图控件发送的缓存的项范围。 它执行验证以确定请求的项目范围尚未缓存,然后分配所需的全局内存,并在必要时填充缓存。 - void PrepCache(int iFrom, int iTo)
- {
- /* Global Variables
- * g_priCache[ ]: the main cache.
- * g_iCache: the index of the first item in the main cache.
- * g_cCache: the count of items in the main cache.
- *
- * g_priEndCache[ ]: the cache of items at the end of the list.
- * g_iEndCache: the index of the first item in the end cache.
- * g_cEndCache: the count of items in the end cache.
- */
-
- // Local Variables
- int i;
- BOOL fOLFrom = FALSE;
- BOOL fOLTo = FALSE;
- // Check to see if this is the end cache.
- if ((iTo == g_cCache - 1) && ((iTo - iFrom) < 30)) // 30 entries wide.
- {
- // Check to see if this is a portion of the current end cache.
- if ((g_cCache) && (iFrom >= g_iEndCache) && (iFrom < g_iEndCache+g_cEndCache))
- return;
- // If it is a part of current end cache, no loading is necessary.
- // This is a new end cache. Free the old memory.
- if ( g_priEndCache )
- GlobalFree( g_priEndCache );
-
- // Set the index and count values for the new end cache,
- // and then retrieve the memory.
- g_iEndCache = iFrom;
- g_cEndCache = (iTo - iFrom + 1);
- g_priEndCache = (RndItem *)GlobalAlloc(GPTR, sizeof(RndItem) * g_cEndCache);
- if (! g_priEndCache)
- {
- // TODO: Out of memory. Perform error handling.
- }
- // Loop to fill the cache with the recommended items.
- for (i=0; i<g_cEndCache; i++)
- {
- // TODO: Call a function that accesses item information and
- // fills a cache element.
- }
- }
- else
- {
- // It is not a member of the current end cache.
- // Try the primary cache instead.
- // Check to see if iFrom is within the primary cache.
- if ((g_cCache) && (iFrom >= g_iCache) && (iFrom < g_iCache+g_cCache))
- fOLFrom = TRUE;
- // Check to see if iTo is within the primary cache.
- if ((g_cCache) && (iTo >= g_iCache) && (iTo <= g_iCache+g_cCache))
- fOLTo = TRUE;
- // do nothing if both iFrom and iTo are within the current cache.
- if (fOLFrom && fOLTo)
- return;
- // Enlarge the cache size rather than make it specific to this hint.
- if (fOLFrom)
- iFrom = g_iCache;
- else if (fOLTo)
- iTo = g_iCache + g_cCache;
- // A new primary cache is needed. Free the old primary cache.
- if ( g_priCache )
- GlobalFree( g_priCache );
- // Set the index and count values for the new primary cache,
- // and then retrieve the memory.
- g_iCache = iFrom;
- g_cCache = (iTo - iFrom + 1);
- g_priCache = (RndItem *)GlobalAlloc( GPTR, sizeof( RndItem ) * g_cCache );
- if (!g_priCache)
- {
- // TODO: Out of memory. Do error handling.
- }
- // Loop to fill the cache with the recommended items.
- for (i=0; i<g_cCache; i++)
- {
- // TODO: Call a function that accesses item information
- // and fills a cache element.
- }
- }
- }
复制代码
从缓存中检索项
此示例函数接受两个参数、应用程序定义的结构的地址和一个表示列表中项索引的整数值。 它会检查索引值,以发现是否缓存了所需的项。 如果是,则传递给函数的指针将设置为缓存中的某个位置。 如果该项不在主缓存或结束缓存中,则必须手动定位项信息。 - void RetrieveItem( RndItem * prndItem, int index )
- {
- // Global Variables
- // g_priCache[ ]: the main cache.
- // g_iCache: the index of the first item in the main cache.
- // c_cCache: the count of items in the main cache.
- //
- // g_priEndCache[ ]: the cache of items at the end of the list.
- // g_iEndCache: the index of the first item in the end cache.
- // g_cEndCache: the count of items in the end cache.
- //
- // Check to see if the item is in the main cache.
- if ((index >= g_iCache) && (index < g_iCache + g_cCache))
- *prndItem = g_priCache[index-g_iCache];
- // If it is not in the main cache, then check to see if
- // the item is in the end area cache.
- else if ((index >= g_iEndCache) && (index < g_iEndCache + g_cEndCache))
- *prndItem = g_priEndCache[index-g_iEndCache];
- else
- {
- // The item is not in either cache.
- // Therefore, retrieve the item information manually.
- }
- }
复制代码
|