xref: /aosp_15_r20/external/lzma/CPP/Common/MyMap.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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