-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapping.cpp
151 lines (125 loc) · 3.21 KB
/
mapping.cpp
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
// mapping.cpp
// FireFly server 'mapping' data type
#include "mapping.h"
#include "database.h"
#include "any_impl.h"
// Public interface
void mapping_t::Append(mappingp mpValue)
{
// Add the keys in a mapping to the mapping
const std_map& src = mpValue->m_mpValues;
for (map_const_it it = src.begin(); it != src.end(); ++it) {
Assign(it->first, it->second);
}
}
const any_t& mapping_t::Lookup( const any_t& mKey )
{
// Retrieve the value in an existing key
map_it it = m_mpValues.find(mKey);
if (it != m_mpValues.end()) {
// Replace deleted refs in the mapping with null.
if (it->second.IsDeleted()) it->second.AssignNull();
// Return the value for this key.
return it->second;
}
// Key not present, return null.
return g_null;
}
bool mapping_t::Exists( const any_t& mKey )
{
// Retrieve the value in an existing key
map_it it = m_mpValues.find(mKey);
if (it != m_mpValues.end()) {
// Replace deleted refs in the mapping with null.
if (it->second.IsDeleted()) it->second.AssignNull();
// Key is present.
return true;
}
// Key not present.
return false;
}
void mapping_t::Assign(const any_t& mKey, const any_t& mValue)
{
// Assign a new value for a key
map_it it = m_mpValues.find(mKey);
if (it != m_mpValues.end()) {
// Replace the value for this key
it->second.Assign(mValue); // new ref
} else {
// Add a new key-value pair
mKey.AddRef(); // new ref
mValue.AddRef(); // new ref
m_mpValues.insert(map_val(mKey, mValue));
}
}
arrayp mapping_t::ListKeys() const
{
arrayp result = new array_t;
const std_map& src = m_mpValues;
for (map_const_it it = src.begin(); it != src.end(); ++it) {
result->AppendItem(it->first); // new ref
}
return result;
}
arrayp mapping_t::ListValues() const
{
arrayp result = new array_t;
const std_map& src = m_mpValues;
for (map_const_it it = src.begin(); it != src.end(); ++it) {
result->AppendItem(it->second); // new ref
}
return result;
}
bool mapping_t::Remove(const any_t& mKey)
{
map_it it = m_mpValues.find(mKey);
if (it != m_mpValues.end()) {
it->first.Release();
it->second.Release();
m_mpValues.erase(it);
return true;
}
return false;
}
// Construction, Destruction
mapping_t::~mapping_t()
{
#ifdef DEBUG_REF
printf( "[mapping %08x destroy: %d refs]\n", this, m_nRef );
#endif
g_oIdxMapping.Remove( this );
// Release each key and value in the mapping
const std_map& src = m_mpValues;
for (map_const_it it = src.begin(); it != src.end(); ++it) {
it->first.Release();
it->second.Release();
}
}
// Persistent storage management
void mapping_t::Persist() const
{
// Write the reference count
g_oDatabase.WriteLong( m_nRef );
// Write the mapping size
g_oDatabase.WriteLong( (uint32)m_mpValues.size() );
// Write the mapping elements
const std_map& src = m_mpValues;
for (map_const_it it = src.begin(); it != src.end(); ++it) {
it->first.Persist();
it->second.Persist();
}
}
void mapping_t::Restore()
{
// Read the reference count
m_nRef = g_oDatabase.ReadLong();
// Read the mapping size
uint32 nSize = g_oDatabase.ReadLong();
// Read the mapping elements
for( uint32 i = 0; i < nSize; i++ ) {
any_t mKey, mValue;
mKey.Restore();
mValue.Restore();
m_mpValues.insert(map_val(mKey, mValue)); // no change
}
}