用于缓存具有复合唯一id的对象的最佳数据结构
本文关键字:对象 最佳 数据结构 id 唯一 缓存 复合 用于 | 更新日期: 2023-09-27 18:28:11
我有一个速度较慢的函数,它需要花费高昂的代价才能访问服务器来检索RecordHdr对象。这些对象先按rid排序,然后按aid排序。然后将它们分5批退回。
| rid | aid |
-------------->
| 1 | 1 | >
| 1 | 3 | >
| 1 | 5 | > BATCH of 5 returned
| 1 | 6 | >
| 2 | 2 | >
-------------->
| 2 | 3 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 5 |
| 3 | 6 |
| 4 | 1 |
| 4 | 2 |
| 4 | 5 |
| 4 | 6 |
检索对象后,我必须将它们包装在另一个名为WrappedRecordHdr的类中我想知道什么是我能用来维护WrappedRecordHdr对象缓存的最佳数据结构,这样,如果rid和aid要求我提供一个对象,我就会为它返回一个特定的对象。此外,如果要求我提供rid,我应该返回所有具有该rid的对象
到目前为止,我已经为每个场景创建了两个结构(这可能不是最好的方法,但这是我现在使用的):
// key: (rid, aid)
private CacheMap<int, int, WrappedRecordHdr> m_ridAidCache =
new CacheMap<int, int, WrappedRecordHdr>();
// key: (rid)
private CacheMap<int, WrappedRecordHdr[]> m_ridCache =
new CacheMap<int, WrappedRecordHdr[]>();
此外,我想知道是否有一种方法可以重写它以提高效率现在我必须获得一些需要包装在另一个对象中的记录。然后,我需要根据id在字典中对它们进行分组,这样,如果我被要求某个rid,我就可以返回所有具有相同rid的对象。记录已经排序,所以我希望GroupBy不要试图提前对它们进行排序。
RecordHdr[] records = server.GetRecordHdrs(sessId, BATCH_SIZE) // expensive call to server.
// After all RecordHdr objects are retrieved, we loop through the received objects. For each RecordHdr object a WrappedRecordHdr object has to be created.
WrappedRecordHdr[] wrappedRecords = new WrappedRecordHdr[records.Length];
for (int i = 0; i < wrappedRecords.Length; i++)
{
if (records[i] == null || records[i].aid == 0 || records[i].rid == 0) continue; // skip invalid results.
wrappedRecords[i] = new WrappedRecordHdr(AccessorManager, records[i], projectId);
}
// Group all records found in a dictionary of rid => array of WrappedRecordHdrs, so all records with the same
// rid are returned.
objects associated to a particular rid.
Dictionary<int, WrappedRecordHdr[]> dict = wrappedRecords.GroupBy(obj => obj.rid).ToDictionary(gdc => gdc.Key, gdc => gdc.ToArray());
m_ridCache = dict;
关于数据结构,我认为这里确实有两个不同的问题:
- 使用什么结构
- 是否应该有一个或两个缓存
在我看来,你想要一个缓存,键入为MemoryCache。键将是RID,值将是Dictionary,其中键是AID,值是标头。
这具有以下优点:
- WrappedRecordHdrs只存储一次
- MemoryCache已经实现了所有的缓存逻辑,所以不需要重写
- 当只提供一个RID时,您知道每个WrappedRecordHdr的AID(在最初的文章中,您没有得到数组的AID)
这些东西总是妥协的,所以这当然也有缺点:
- 缓存访问(get或set)需要每次构造一个字符串
- RID+AID查找需要索引两次(而不是编写一些快速哈希函数,该函数接受RID和AID并将单个密钥返回到缓存中,但这需要您有两个缓存(仅一个RID,一个RID+AID),或者每个AID存储两次相同的WrappedRecordHdr(一次用于RID+AID,一次用于null+AID)