File: SpanIndex.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (129 lines) | stat: -rw-r--r-- 4,305 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//---------------------------------------------------------------------
// <copyright file="SpanIndex.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner Microsoft
// @backupowner Microsoft
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Common;
using System.Data.Common.Utils;
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees;

namespace System.Data.Objects.Internal
{
    /// <summary>
    /// An index containing information about how the query was spanned
    /// This helps to determine how to materialize the query result
    /// </summary>
    internal sealed class SpanIndex
    {
        #region Nested types

        /// <summary>
        /// Helper class to compare two RowTypes using EdmEquals instead of reference equality.
        /// </summary>
        sealed private class RowTypeEqualityComparer : IEqualityComparer<RowType>
        {
            private RowTypeEqualityComparer() { }
            internal static readonly RowTypeEqualityComparer Instance = new RowTypeEqualityComparer();

            #region IEqualityComparer<RowType> Members

            public bool Equals(RowType x, RowType y)
            {
                if (x == null || y == null)
                {
                    return false;
                }

                return x.EdmEquals(y);
            }

            public int GetHashCode(RowType obj)
            {
                return obj.Identity.GetHashCode();
            }

            #endregion
        }
        #endregion

        // When a query is spanned, the result is always a RowType
        // The _spanMap index maps RowTypes that are a span result to a map between
        // column ordinal and end member metadata of the type that is spanned
        private Dictionary<RowType, Dictionary<int, AssociationEndMember>> _spanMap;

        // A map from a spanned RowType (or parent RowType) to the original TypeUsage prior
        // to the query being rewritten
        private Dictionary<RowType, TypeUsage> _rowMap;

        internal SpanIndex()
        {
        }

        internal void AddSpannedRowType(RowType spannedRowType, TypeUsage originalRowType)
        {
            Debug.Assert(spannedRowType != null, "Spanned RowType cannot be null");
            Debug.Assert(originalRowType != null, "Original RowType cannot be null");
            Debug.Assert(originalRowType.EdmType.BuiltInTypeKind == BuiltInTypeKind.RowType, "Original RowType must be a RowType");

            if (null == _rowMap)
            {
                _rowMap = new Dictionary<RowType, TypeUsage>(RowTypeEqualityComparer.Instance);
            }

            _rowMap[spannedRowType] = originalRowType;
        }

        internal TypeUsage GetSpannedRowType(RowType spannedRowType)
        {
            TypeUsage retType;
            if (_rowMap != null && _rowMap.TryGetValue(spannedRowType, out retType))
            {
                return retType;
            }
            return null;
        }

        internal bool HasSpanMap(RowType spanRowType)
        {
            Debug.Assert(spanRowType != null, "Span RowType cannot be null");
            if (null == _spanMap)
            {
                return false;
            }

            return _spanMap.ContainsKey(spanRowType);
        }

        internal void AddSpanMap(RowType rowType, Dictionary<int, AssociationEndMember> columnMap)
        {
            Debug.Assert(rowType != null, "Span row type cannot be null");
            Debug.Assert(columnMap != null, "Span column map cannot be null");

            if (null == _spanMap)
            {
                _spanMap = new Dictionary<RowType, Dictionary<int, AssociationEndMember>>(RowTypeEqualityComparer.Instance);
            }

            _spanMap[rowType] = columnMap;
        }

        internal Dictionary<int, AssociationEndMember> GetSpanMap(RowType rowType)
        {
            Dictionary<int, AssociationEndMember> retMap = null;
            if (_spanMap != null && _spanMap.TryGetValue(rowType, out retMap))
            {
                return retMap;
            }

            return null;
        }
    }
}