forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDictionaryStorage.cs
More file actions
163 lines (134 loc) · 5.85 KB
/
DictionaryStorage.cs
File metadata and controls
163 lines (134 loc) · 5.85 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Scripting;
using Microsoft.Scripting.Runtime;
namespace IronPython.Runtime {
/// <summary>
/// Abstract base class for all PythonDictionary storage.
/// </summary>
/// <remarks>
/// Defined as a class instead of an interface for performance reasons. Also not
/// using IDictionary* for keeping a simple interface.
///
/// Full locking is defined as being on the DictionaryStorage object itself,
/// not an internal member. This enables subclasses to provide their own locking
/// around large operations and call lock free functions.
/// </remarks>
[Serializable]
internal abstract class DictionaryStorage {
public abstract void Add(ref DictionaryStorage storage, object? key, object? value);
public virtual void AddNoLock(ref DictionaryStorage storage, object? key, object? value) {
Add(ref storage, key, value);
}
public abstract bool Remove(ref DictionaryStorage storage, object? key);
public virtual bool TryRemoveValue(ref DictionaryStorage storage, object? key, out object? value) {
if (TryGetValue(key, out value)) {
return Remove(ref storage, key);
}
return false;
}
/// <summary>
/// Convert the storage instance to a mutable type.
/// </summary>
/// <remarks>
/// It has the same effect on the storage as <see cref="Add(ref DictionaryStorage, object?, object?)"/>
/// or <see cref="Remove(ref DictionaryStorage, object?)"/> except that the contents of the storage
/// is not modified.
/// </remarks>
/// <param name="storage">
/// Reference to the variable holding the object on which this method is invoked.
/// </param>
/// <returns>
/// <c>this</c> object if it was alreday mutable. Otherwise a reference to a cloned
/// mutable instance, in which case <paramref name="storage"/> is also updated.
/// </returns>
/// <exception cref="InvalidOperationException">The storage is read-only.</exception>
public abstract DictionaryStorage AsMutable(ref DictionaryStorage storage);
public abstract void Clear(ref DictionaryStorage storage);
/// <summary>
/// Adds items from this dictionary into the other dictionary
/// </summary>
public virtual void CopyTo(ref DictionaryStorage/*!*/ into) {
Debug.Assert(into != null);
foreach (KeyValuePair<object?, object?> kvp in GetItems()) {
into!.Add(ref into, kvp.Key, kvp.Value);
}
}
public abstract bool Contains(object? key);
public abstract bool TryGetValue(object? key, out object? value);
public abstract int Count { get; }
#if DEBUG
public bool IsMutable {
get {
try {
DictionaryStorage testing = this;
return ReferenceEquals(this, testing.AsMutable(ref testing));
} catch (InvalidOperationException) {
return false;
}
}
}
#endif
public virtual bool HasNonStringAttributes() {
foreach (KeyValuePair<object?, object?> o in GetItems()) {
if (o.Key is not string && o.Key is not Extensible<string>) {
return true;
}
}
return false;
}
public abstract List<KeyValuePair<object?, object?>> GetItems();
public virtual IEnumerable<object?>/*!*/ GetKeys() {
foreach (var o in GetItems()) {
yield return o.Key;
}
}
public virtual DictionaryStorage Clone() {
CommonDictionaryStorage storage = new CommonDictionaryStorage();
foreach (KeyValuePair<object?, object?> kvp in GetItems()) {
storage.Add(kvp.Key, kvp.Value);
}
return storage;
}
public virtual void EnsureCapacityNoLock(int size) {
}
public virtual IEnumerator<KeyValuePair<object?, object?>> GetEnumerator() {
return GetItems().GetEnumerator();
}
/// <summary>
/// Provides fast access to the __path__ attribute if the dictionary storage supports caching it.
/// </summary>
public virtual bool TryGetPath(out object? value) {
return TryGetValue("__path__", out value);
}
/// <summary>
/// Provides fast access to the __package__ attribute if the dictionary storage supports caching it.
/// </summary>
public virtual bool TryGetPackage(out object? value) {
return TryGetValue("__package__", out value);
}
/// <summary>
/// Provides fast access to the __builtins__ attribute if the dictionary storage supports caching it.
/// </summary>
public virtual bool TryGetBuiltins(out object? value) {
return TryGetValue("__builtins__", out value);
}
/// <summary>
/// Provides fast access to the __name__ attribute if the dictionary storage supports caching it.
/// </summary>
public virtual bool TryGetName(out object? value) {
return TryGetValue("__name__", out value);
}
/// <summary>
/// Provides fast access to the __import__ attribute if the dictionary storage supports caching it.
/// </summary>
public virtual bool TryGetImport(out object? value) {
return TryGetValue("__import__", out value);
}
}
}