예제 #1
0
파일: MemberMatcher.cs 프로젝트: yellis/Jil
        public static MethodInfo GetHashMethod(MemberMatcherMode mode)
        {
            switch (mode)
            {
            case MemberMatcherMode.One: return(Methods.MemberHash1);

            case MemberMatcherMode.Two: return(Methods.MemberHash2);

            case MemberMatcherMode.Four: return(Methods.MemberHash4);

            case MemberMatcherMode.Eight: return(Methods.MemberHash8);

            case MemberMatcherMode.Sixteen: return(Methods.MemberHash16);

            case MemberMatcherMode.ThirtyTwo: return(Methods.MemberHash32);

            case MemberMatcherMode.SixtyFour: return(Methods.MemberHash64);

            default: throw new Exception("Unexpected MemberMatcherMode: " + mode);
            }
        }
예제 #2
0
파일: MemberMatcher.cs 프로젝트: yellis/Jil
        static bool MakeMemberMatcher(out Dictionary <string, MemberInfo> memberLookup, out Dictionary <string, int> memberToBucket, out Dictionary <string, uint> memberToHash, out MemberMatcherMode bestMode)
        {
            var forType = typeof(ForType);

            var fields = forType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
            var props  = forType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public).Where(p => p.SetMethod != null);

            var members = fields.Cast <MemberInfo>().Concat(props.Cast <MemberInfo>());

            memberLookup = members.ToDictionary(m => m.GetSerializationName(), m => m);

            var memberNames = memberLookup.Keys;

            var allModes =
                Enum.GetValues(typeof(MemberMatcherMode))
                .Cast <MemberMatcherMode>()
                .Where(m => m != MemberMatcherMode.None)
                .OrderBy(o => (int)o)
                .ToList();

            foreach (var mode in allModes)
            {
                var mToH = new Dictionary <string, uint>();

                var method = GetHashMethod(mode);

                var buckets =
                    memberNames.GroupBy(
                        m =>
                {
                    using (var str = new StringReader("\"" + m.JsonEscape(jsonp: false) + "\""))
                    {
                        str.Read();             // skip "

                        var ps = new object[] { str, (int)-1, (uint)0 };
                        method.Invoke(null, ps);

                        var bucket = (int)ps[1];
                        var hash   = (uint)ps[2];

                        mToH[m] = hash;

                        return(bucket);
                    }
                }
                        );

                var collisions = buckets.Any(g => g.Count() > 1);

                if (collisions)
                {
                    continue;
                }

                memberToHash   = mToH;
                memberToBucket = buckets.ToDictionary(d => d.Single(), d => d.Key);
                bestMode       = mode;
                return(true);
            }


            memberToHash   = null;
            memberToBucket = null;
            bestMode       = MemberMatcherMode.None;
            return(false);
        }