<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Manatee.Json.Internal;

namespace Manatee.Json.Serialization.Internal.Serializers
{
	internal static class ReflectionCache
	{
		private class ReflectionInfo
		{
			public IEnumerable<SerializationInfo> ReadOnlyProperties { get; }
			public IEnumerable<SerializationInfo> ReadWriteProperties { get; }
			public IEnumerable<SerializationInfo> Fields { get; }

			public ReflectionInfo(IEnumerable<SerializationInfo> readOnlyProperties, IEnumerable<SerializationInfo> readWriteProperties, IEnumerable<SerializationInfo> fields)
			{
				ReadOnlyProperties = readOnlyProperties.ToList();
				ReadWriteProperties = readWriteProperties.ToList();
				Fields = fields.ToList();
			}
		}

		private static readonly Dictionary<Type, ReflectionInfo> _instanceCache;
		private static readonly Dictionary<Type, ReflectionInfo> _staticCache;

		static ReflectionCache()
		{
			_instanceCache = new Dictionary<Type, ReflectionInfo>();
			_staticCache = new Dictionary<Type, ReflectionInfo>();
		}

		public static IEnumerable<SerializationInfo> GetMembers(Type type, PropertySelectionStrategy propertyTypes, bool includeFields)
		{
			var info = _InitializeInstanceCache(type);
			var members = _GetProperties(info, propertyTypes);
			if (includeFields)
				members = members.Concat(_GetFields(info));
			return members;
		}
		public static IEnumerable<SerializationInfo> GetTypeMembers(Type type, PropertySelectionStrategy propertyTypes, bool includeFields)
		{
			var info = _InitializeStaticCache(type);
			var members = _GetProperties(info, propertyTypes);
			if (includeFields)
				members = members.Concat(_GetFields(info));
			return members;
		}

		private static IEnumerable<SerializationInfo> _GetProperties(ReflectionInfo info, PropertySelectionStrategy propertyTypes)
		{
			var properties = new List<SerializationInfo>();
			if (propertyTypes.HasFlag(PropertySelectionStrategy.ReadWriteOnly))
				properties.AddRange(info.ReadWriteProperties);
			if (propertyTypes.HasFlag(PropertySelectionStrategy.ReadOnly))
				properties.AddRange(info.ReadOnlyProperties);
			return properties;
		}
		private static IEnumerable<SerializationInfo> _GetFields(ReflectionInfo info)
		{
			var fields = new List<SerializationInfo>();
			fields.AddRange(info.Fields);
			return fields;<commit_msg>Remove LINQ from hot path of reflection cache<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Manatee.Json.Internal;

namespace Manatee.Json.Serialization.Internal.Serializers
{
	internal static class ReflectionCache
	{
		private class ReflectionInfo
		{
			public IEnumerable<SerializationInfo> ReadOnlyProperties { get; }
			public IEnumerable<SerializationInfo> ReadWriteProperties { get; }
			public IEnumerable<SerializationInfo> Fields { get; }

			public ReflectionInfo(IEnumerable<SerializationInfo> readOnlyProperties, IEnumerable<SerializationInfo> readWriteProperties, IEnumerable<SerializationInfo> fields)
			{
				ReadOnlyProperties = readOnlyProperties.ToList();
				ReadWriteProperties = readWriteProperties.ToList();
				Fields = fields.ToList();
			}
		}

		private static readonly Dictionary<Type, ReflectionInfo> _instanceCache;
		private static readonly Dictionary<Type, ReflectionInfo> _staticCache;

		static ReflectionCache()
		{
			_instanceCache = new Dictionary<Type, ReflectionInfo>();
			_staticCache = new Dictionary<Type, ReflectionInfo>();
		}

		public static IEnumerable<SerializationInfo> GetMembers(Type type, PropertySelectionStrategy propertyTypes, bool includeFields)
		{
			var info = _InitializeInstanceCache(type);
			var members = new List<SerializationInfo>();
			_GetProperties(info, propertyTypes, members);
			if (includeFields)
				_GetFields(info, members);
			return members;
		}
		public static IEnumerable<SerializationInfo> GetTypeMembers(Type type, PropertySelectionStrategy propertyTypes, bool includeFields)
		{
			var info = _InitializeStaticCache(type);
			var members = new List<SerializationInfo>();
			_GetProperties(info, propertyTypes, members);
			if (includeFields)
				_GetFields(info, members);
			return members;
		}

		private static IEnumerable<SerializationInfo> _GetProperties(ReflectionInfo info, PropertySelectionStrategy propertyTypes, List<SerializationInfo> properties)
		{
			if (propertyTypes.HasFlag(PropertySelectionStrategy.ReadWriteOnly))
				properties.AddRange(info.ReadWriteProperties);
			if (propertyTypes.HasFlag(PropertySelectionStrategy.ReadOnly))
				properties.AddRange(info.ReadOnlyProperties);
			return properties;
		}
		private static IEnumerable<SerializationInfo> _GetFields(ReflectionInfo info, List<SerializationInfo> fields)
		{
			fields.AddRange(info.Fields);
			return fields;
{'fraction_non_alphanumeric': 0.08188585607940446, 'fraction_numerical': 0.0, 'mean_word_length': 6.030523255813954, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '828858', 'n_tokens_mistral': 1404, 'n_tokens_neox': 1257, 'n_words': 290}