Re: Нашел задание для проверки возможностей ИИ
От: Lepsik Гондурас https://www.kirdyk.club/
Дата: 16.01.25 07:05
Оценка: 6 (1)
mistral

Для реализации методов retrieveItems и getItemFromCache в классе ObjectDdCacheManager, нам нужно учитывать все условия, описанные в задаче. Давайте начнем с реализации этих методов.
Реализация метода retrieveItems

FetchDataPolicy:
never: Возвращаем данные из кеша (или ничего).
onEmptyCache: Делаем запрос к API только если в кеше нет данных.
always: Всегда делаем запрос к API и обновляем данные кеша.

CacheUpdateMode:
entities: Заменяем сущности.
box: Удаляем старую коробку целиком со всеми объектами.

Filter:
Если установлен, то запрос к базе делаем через getBeyKey (вид фильтра entityKey) или select (вид range).
Фильтр применяем и для удаления сущностей в режиме entities.

useMemoryCache:
Если установлен, то используем дополнительно кеш в памяти _memoryCache.

Реализация метода getItemFromCache

useMemoryCache:
Если установлен, то сначала проверяем кеш в памяти _memoryCache.
Если данных нет в _memoryCache, то проверяем базу данных.

  code
class ObjectDdCacheManager<TApiObject, TDataEntity extends DataEntity, TModel>
    extends CacheManager<TApiObject, TDataEntity, TModel> {
  ObjectDdCacheManager(
      {required super.fetchFromApi,
      required super.transformToDataEntities,
      required super.transformToModel,
      required super.boxName});

  @override
  Future<ResultOrError<List<TModel>>> retrieveItems(
      {FetchDataPolicy fetchDataPolicy = FetchDataPolicy.onEmptyCache,
      CacheUpdateMode cacheUpdateMode = CacheUpdateMode.entities,
      Filter? filter}) async {
    final box = ObjectDdMock<TDataEntity>();
    List<TDataEntity> cachedEntities = [];

    // Check memory cache first if useMemoryCache is true
    if (useMemoryCache && _memoryCache.containsKey(boxName)) {
      cachedEntities = _memoryCache[boxName]!.values.cast<TDataEntity>().toList();
    } else {
      // Check database cache
      if (filter != null) {
        if (filter.kind == FilterKind.entityKey && filter is FilterByKey) {
          final entity = box.getBeyKey(filter.key);
          if (entity != null) {
            cachedEntities = [entity];
          }
        } else if (filter.kind == FilterKind.range && filter is FilterByRange) {
          cachedEntities = box.select(filter.startKey, filter.endKey);
        }
      } else {
        cachedEntities = box.getAll();
      }
    }

    // Determine if we need to fetch from API
    bool needToFetch = false;
    if (fetchDataPolicy == FetchDataPolicy.always) {
      needToFetch = true;
    } else if (fetchDataPolicy == FetchDataPolicy.onEmptyCache && cachedEntities.isEmpty) {
      needToFetch = true;
    }

    if (needToFetch) {
      final apiResult = await fetchFromApi();
      if (apiResult.isSuccess) {
        final newEntities = transformToDataEntities(apiResult.result!);

        if (cacheUpdateMode == CacheUpdateMode.box) {
          box.deleteBox();
          if (useMemoryCache) {
            _memoryCache.remove(boxName);
          }
        } else if (cacheUpdateMode == CacheUpdateMode.entities) {
          if (filter != null) {
            List<TDataEntity> entitiesToDelete = [];
            if (filter.kind == FilterKind.entityKey && filter is FilterByKey) {
              final entity = box.getBeyKey(filter.key);
              if (entity != null) {
                entitiesToDelete.add(entity);
              }
            } else if (filter.kind == FilterKind.range && filter is FilterByRange) {
              entitiesToDelete = box.select(filter.startKey, filter.endKey);
            }
            box.deleteEntities(entitiesToDelete);
            if (useMemoryCache) {
              for (final entity in entitiesToDelete) {
                _memoryCache[boxName]?.remove(entity.key);
              }
            }
          }
        }

        box.putAll(newEntities);
        if (useMemoryCache) {
          if (!_memoryCache.containsKey(boxName)) {
            _memoryCache[boxName] = {};
          }
          for (final entity in newEntities) {
            _memoryCache[boxName]![entity.key] = entity;
          }
        }

        cachedEntities = newEntities;
      } else {
        return ResultOrError.fromError(apiResult.error!);
      }
    }

    final models = cachedEntities.map(transformToModel).toList();
    return ResultOrError.fromResult(models);
  }

  @override
  Future<TModel?> getItemFromCache(String key) async {
    if (useMemoryCache && _memoryCache.containsKey(boxName)) {
      final entity = _memoryCache[boxName]![key] as TDataEntity?;
      if (entity != null) {
        return transformToModel(entity);
      }
    }

    final box = ObjectDdMock<TDataEntity>();
    final entity = box.getBeyKey(key);
    if (entity != null) {
      return transformToModel(entity);
    }

    return null;
  }
}

void main() async {
  final cacheManager = ObjectDdCacheManager(
      fetchFromApi: () async {
        return ResultOrError.fromResult(ApiObject1());
      },
      transformToDataEntities: (apiObject) {
        return apiObject.items.keys
            .map((k) => DataEntity1(k, apiObject.items[k]!))
            .toList();
      },
      transformToModel: (dataEntity) {
        return Model1(dataEntity.value);
      },
      boxName: 'box1');

  final items = await cacheManager.retrieveItems();

  print(items.result!.length);
}
Отредактировано 16.01.2025 7:06 Петя Ковальчук . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.