public IReadOnlyList <TItem> GetOrAdd(TKey key, Func <TKey, IEnumerable <TItem> > getFunc) { int index = Primary.GetOrAdd(key, k => { var rawList = getFunc(k); lock (Primary) { int[] itemListByIndex = rawList.Select(item => { if (!ItemDict.TryGetValue(item, out int itemIndex)) { itemIndex = ItemList.Count; ItemList.Add(item); ItemDict[item] = itemIndex; } return(itemIndex); }).ToArray(); var intArray = new IntArray(itemListByIndex); if (!ListDict.TryGetValue(intArray, out int listIndex)) { lock (ListList) { listIndex = ListList.Count; ListList.Add(itemListByIndex.Select(ii => ItemList[ii]).ToArray()); } ListDict[intArray] = listIndex; } return(listIndex); }