1*f6dc9357SAndroid Build Coastguard Worker // MyMap.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "MyMap.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumBitsMax = sizeof(UInt32) * 8;
8*f6dc9357SAndroid Build Coastguard Worker
GetSubBits(UInt32 value,unsigned startPos,unsigned numBits)9*f6dc9357SAndroid Build Coastguard Worker static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) throw()
10*f6dc9357SAndroid Build Coastguard Worker {
11*f6dc9357SAndroid Build Coastguard Worker if (startPos == sizeof(value) * 8)
12*f6dc9357SAndroid Build Coastguard Worker return 0;
13*f6dc9357SAndroid Build Coastguard Worker value >>= startPos;
14*f6dc9357SAndroid Build Coastguard Worker if (numBits == sizeof(value) * 8)
15*f6dc9357SAndroid Build Coastguard Worker return value;
16*f6dc9357SAndroid Build Coastguard Worker return value & (((UInt32)1 << numBits) - 1);
17*f6dc9357SAndroid Build Coastguard Worker }
18*f6dc9357SAndroid Build Coastguard Worker
GetSubBit(UInt32 v,unsigned n)19*f6dc9357SAndroid Build Coastguard Worker static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; }
20*f6dc9357SAndroid Build Coastguard Worker
Find(UInt32 key,UInt32 & valueRes) const21*f6dc9357SAndroid Build Coastguard Worker bool CMap32::Find(UInt32 key, UInt32 &valueRes) const throw()
22*f6dc9357SAndroid Build Coastguard Worker {
23*f6dc9357SAndroid Build Coastguard Worker valueRes = (UInt32)(Int32)-1;
24*f6dc9357SAndroid Build Coastguard Worker if (Nodes.Size() == 0)
25*f6dc9357SAndroid Build Coastguard Worker return false;
26*f6dc9357SAndroid Build Coastguard Worker if (Nodes.Size() == 1)
27*f6dc9357SAndroid Build Coastguard Worker {
28*f6dc9357SAndroid Build Coastguard Worker const CNode &n = Nodes[0];
29*f6dc9357SAndroid Build Coastguard Worker if (n.Len == kNumBitsMax)
30*f6dc9357SAndroid Build Coastguard Worker {
31*f6dc9357SAndroid Build Coastguard Worker valueRes = n.Values[0];
32*f6dc9357SAndroid Build Coastguard Worker return (key == n.Key);
33*f6dc9357SAndroid Build Coastguard Worker }
34*f6dc9357SAndroid Build Coastguard Worker }
35*f6dc9357SAndroid Build Coastguard Worker
36*f6dc9357SAndroid Build Coastguard Worker unsigned cur = 0;
37*f6dc9357SAndroid Build Coastguard Worker unsigned bitPos = kNumBitsMax;
38*f6dc9357SAndroid Build Coastguard Worker for (;;)
39*f6dc9357SAndroid Build Coastguard Worker {
40*f6dc9357SAndroid Build Coastguard Worker const CNode &n = Nodes[cur];
41*f6dc9357SAndroid Build Coastguard Worker bitPos -= n.Len;
42*f6dc9357SAndroid Build Coastguard Worker if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len))
43*f6dc9357SAndroid Build Coastguard Worker return false;
44*f6dc9357SAndroid Build Coastguard Worker unsigned bit = GetSubBit(key, --bitPos);
45*f6dc9357SAndroid Build Coastguard Worker if (n.IsLeaf[bit])
46*f6dc9357SAndroid Build Coastguard Worker {
47*f6dc9357SAndroid Build Coastguard Worker valueRes = n.Values[bit];
48*f6dc9357SAndroid Build Coastguard Worker return (key == n.Keys[bit]);
49*f6dc9357SAndroid Build Coastguard Worker }
50*f6dc9357SAndroid Build Coastguard Worker cur = (unsigned)n.Keys[bit];
51*f6dc9357SAndroid Build Coastguard Worker }
52*f6dc9357SAndroid Build Coastguard Worker }
53*f6dc9357SAndroid Build Coastguard Worker
Set(UInt32 key,UInt32 value)54*f6dc9357SAndroid Build Coastguard Worker bool CMap32::Set(UInt32 key, UInt32 value)
55*f6dc9357SAndroid Build Coastguard Worker {
56*f6dc9357SAndroid Build Coastguard Worker if (Nodes.Size() == 0)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker CNode n;
59*f6dc9357SAndroid Build Coastguard Worker n.Key = n.Keys[0] = n.Keys[1] = key;
60*f6dc9357SAndroid Build Coastguard Worker n.Values[0] = n.Values[1] = value;
61*f6dc9357SAndroid Build Coastguard Worker n.IsLeaf[0] = n.IsLeaf[1] = 1;
62*f6dc9357SAndroid Build Coastguard Worker n.Len = kNumBitsMax;
63*f6dc9357SAndroid Build Coastguard Worker Nodes.Add(n);
64*f6dc9357SAndroid Build Coastguard Worker return false;
65*f6dc9357SAndroid Build Coastguard Worker }
66*f6dc9357SAndroid Build Coastguard Worker if (Nodes.Size() == 1)
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker CNode &n = Nodes[0];
69*f6dc9357SAndroid Build Coastguard Worker if (n.Len == kNumBitsMax)
70*f6dc9357SAndroid Build Coastguard Worker {
71*f6dc9357SAndroid Build Coastguard Worker if (key == n.Key)
72*f6dc9357SAndroid Build Coastguard Worker {
73*f6dc9357SAndroid Build Coastguard Worker n.Values[0] = n.Values[1] = value;
74*f6dc9357SAndroid Build Coastguard Worker return true;
75*f6dc9357SAndroid Build Coastguard Worker }
76*f6dc9357SAndroid Build Coastguard Worker unsigned i = kNumBitsMax - 1;
77*f6dc9357SAndroid Build Coastguard Worker for (; GetSubBit(key, i) == GetSubBit(n.Key, i); i--);
78*f6dc9357SAndroid Build Coastguard Worker n.Len = (UInt16)(kNumBitsMax - (1 + i));
79*f6dc9357SAndroid Build Coastguard Worker const unsigned newBit = GetSubBit(key, i);
80*f6dc9357SAndroid Build Coastguard Worker n.Values[newBit] = value;
81*f6dc9357SAndroid Build Coastguard Worker n.Keys[newBit] = key;
82*f6dc9357SAndroid Build Coastguard Worker return false;
83*f6dc9357SAndroid Build Coastguard Worker }
84*f6dc9357SAndroid Build Coastguard Worker }
85*f6dc9357SAndroid Build Coastguard Worker
86*f6dc9357SAndroid Build Coastguard Worker unsigned cur = 0;
87*f6dc9357SAndroid Build Coastguard Worker unsigned bitPos = kNumBitsMax;
88*f6dc9357SAndroid Build Coastguard Worker for (;;)
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker CNode &n = Nodes[cur];
91*f6dc9357SAndroid Build Coastguard Worker bitPos -= n.Len;
92*f6dc9357SAndroid Build Coastguard Worker if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len))
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker unsigned i = (unsigned)n.Len - 1;
95*f6dc9357SAndroid Build Coastguard Worker for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--);
96*f6dc9357SAndroid Build Coastguard Worker
97*f6dc9357SAndroid Build Coastguard Worker CNode e2(n);
98*f6dc9357SAndroid Build Coastguard Worker e2.Len = (UInt16)i;
99*f6dc9357SAndroid Build Coastguard Worker
100*f6dc9357SAndroid Build Coastguard Worker n.Len = (UInt16)(n.Len - (1 + i));
101*f6dc9357SAndroid Build Coastguard Worker unsigned newBit = GetSubBit(key, bitPos + i);
102*f6dc9357SAndroid Build Coastguard Worker n.Values[newBit] = value;
103*f6dc9357SAndroid Build Coastguard Worker n.IsLeaf[newBit] = 1;
104*f6dc9357SAndroid Build Coastguard Worker n.IsLeaf[1 - newBit] = 0;
105*f6dc9357SAndroid Build Coastguard Worker n.Keys[newBit] = key;
106*f6dc9357SAndroid Build Coastguard Worker n.Keys[1 - newBit] = (UInt32)Nodes.Size();
107*f6dc9357SAndroid Build Coastguard Worker Nodes.Add(e2);
108*f6dc9357SAndroid Build Coastguard Worker return false;
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker const unsigned bit = GetSubBit(key, --bitPos);
111*f6dc9357SAndroid Build Coastguard Worker
112*f6dc9357SAndroid Build Coastguard Worker if (n.IsLeaf[bit])
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker if (key == n.Keys[bit])
115*f6dc9357SAndroid Build Coastguard Worker {
116*f6dc9357SAndroid Build Coastguard Worker n.Values[bit] = value;
117*f6dc9357SAndroid Build Coastguard Worker return true;
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker unsigned i = bitPos - 1;
120*f6dc9357SAndroid Build Coastguard Worker for (; GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--);
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker CNode e2;
123*f6dc9357SAndroid Build Coastguard Worker
124*f6dc9357SAndroid Build Coastguard Worker const unsigned newBit = GetSubBit(key, i);
125*f6dc9357SAndroid Build Coastguard Worker e2.Values[newBit] = value;
126*f6dc9357SAndroid Build Coastguard Worker e2.Values[1 - newBit] = n.Values[bit];
127*f6dc9357SAndroid Build Coastguard Worker e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1;
128*f6dc9357SAndroid Build Coastguard Worker e2.Keys[newBit] = key;
129*f6dc9357SAndroid Build Coastguard Worker e2.Keys[1 - newBit] = e2.Key = n.Keys[bit];
130*f6dc9357SAndroid Build Coastguard Worker e2.Len = (UInt16)(bitPos - (1 + i));
131*f6dc9357SAndroid Build Coastguard Worker
132*f6dc9357SAndroid Build Coastguard Worker n.IsLeaf[bit] = 0;
133*f6dc9357SAndroid Build Coastguard Worker n.Keys[bit] = (UInt32)Nodes.Size();
134*f6dc9357SAndroid Build Coastguard Worker
135*f6dc9357SAndroid Build Coastguard Worker Nodes.Add(e2);
136*f6dc9357SAndroid Build Coastguard Worker return false;
137*f6dc9357SAndroid Build Coastguard Worker }
138*f6dc9357SAndroid Build Coastguard Worker cur = (unsigned)n.Keys[bit];
139*f6dc9357SAndroid Build Coastguard Worker }
140*f6dc9357SAndroid Build Coastguard Worker }
141