Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZ/Patricia/Pat.h, revision 1.1.1.1

1.1       misho       1: // Pat.h
                      2: 
                      3: // #ifndef __PATRICIA__H
                      4: // #define __PATRICIA__H
                      5: 
                      6: #include "../../../../Common/MyCom.h"
                      7: #include "../../../../Common/Types.h"
                      8: #include "../LZInWindow.h"
                      9: 
                     10: namespace PAT_NAMESPACE {
                     11: 
                     12: struct CNode;
                     13: 
                     14: typedef CNode *CNodePointer;
                     15: 
                     16: // #define __AUTO_REMOVE
                     17: 
                     18: // #define __NODE_4_BITS
                     19: // #define __NODE_3_BITS
                     20: // #define __NODE_2_BITS
                     21: // #define __NODE_2_BITS_PADDING
                     22: 
                     23: // #define __HASH_3
                     24: 
                     25: 
                     26: typedef UInt32 CIndex;
                     27: 
                     28: #ifdef __NODE_4_BITS
                     29:   typedef UInt32 CIndex2;
                     30:   typedef UInt32 CSameBitsType;
                     31: #else
                     32: #ifdef __NODE_3_BITS
                     33:   typedef UInt32 CIndex2;
                     34:   typedef UInt32 CSameBitsType;
                     35: #else
                     36: 
                     37:   typedef UInt32 CIndex;
                     38:   typedef UInt32 CSameBitsType;
                     39: 
                     40:   typedef CIndex CIndex2;
                     41: #endif
                     42: #endif
                     43: 
                     44: const UInt32 kNumBitsInIndex = sizeof(CIndex) * 8;
                     45: const UInt32 kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1);
                     46: // don't change kMatchStartValue definition, since it is used in 
                     47: // PatMain.h: 
                     48: 
                     49: typedef CIndex CMatchPointer;
                     50: 
                     51: const UInt32 kDescendantEmptyValue = kMatchStartValue - 1;
                     52: 
                     53: union CDescendant 
                     54: {
                     55:   CIndex NodePointer;
                     56:   CMatchPointer MatchPointer;
                     57:   bool IsEmpty() const { return NodePointer == kDescendantEmptyValue; }
                     58:   bool IsNode() const { return NodePointer < kDescendantEmptyValue; }
                     59:   bool IsMatch() const { return NodePointer > kDescendantEmptyValue; }
                     60:   void MakeEmpty() { NodePointer = kDescendantEmptyValue; }
                     61: };
                     62: 
                     63: #undef MY_BYTE_SIZE
                     64: 
                     65: #ifdef __NODE_4_BITS
                     66:   #define MY_BYTE_SIZE 8
                     67:   const UInt32 kNumSubBits = 4;
                     68: #else
                     69: #ifdef __NODE_3_BITS
                     70:   #define MY_BYTE_SIZE 9
                     71:   const UInt32 kNumSubBits = 3;
                     72: #else
                     73:   #define MY_BYTE_SIZE 8
                     74:   #ifdef __NODE_2_BITS
                     75:     const UInt32 kNumSubBits = 2;
                     76:   #else
                     77:     const UInt32 kNumSubBits = 1;
                     78:   #endif
                     79: #endif
                     80: #endif
                     81: 
                     82: const UInt32 kNumSubNodes = 1 << kNumSubBits;
                     83: const UInt32 kSubNodesMask = kNumSubNodes - 1;
                     84: 
                     85: struct CNode
                     86: {
                     87:   CIndex2 LastMatch;
                     88:   CSameBitsType NumSameBits;
                     89:   union
                     90:   {
                     91:     CDescendant  Descendants[kNumSubNodes];
                     92:     UInt32 NextFreeNode;
                     93:   };
                     94:   #ifdef __NODE_2_BITS
                     95:   #ifdef __NODE_2_BITS_PADDING
                     96:   UInt32 Padding[2];
                     97:   #endif
                     98:   #endif
                     99: };
                    100: 
                    101: #undef kIDNumBitsByte
                    102: #undef kIDNumBitsString
                    103: 
                    104: #ifdef __NODE_4_BITS
                    105:   #define kIDNumBitsByte 0x30
                    106:   #define kIDNumBitsString TEXT("4")
                    107: #else
                    108: #ifdef __NODE_3_BITS
                    109:   #define kIDNumBitsByte 0x20
                    110:   #define kIDNumBitsString TEXT("3")
                    111: #else
                    112: #ifdef __NODE_2_BITS
                    113:   #define kIDNumBitsByte 0x10
                    114:   #define kIDNumBitsString TEXT("2")
                    115: #else
                    116:   #define kIDNumBitsByte 0x00
                    117:   #define kIDNumBitsString TEXT("1")
                    118: #endif
                    119: #endif
                    120: #endif
                    121: 
                    122: #undef kIDManualRemoveByte
                    123: #undef kIDManualRemoveString
                    124: 
                    125: #ifdef __AUTO_REMOVE
                    126:   #define kIDManualRemoveByte 0x00
                    127:   #define kIDManualRemoveString TEXT("")
                    128: #else
                    129:   #define kIDManualRemoveByte 0x08
                    130:   #define kIDManualRemoveString TEXT("R")
                    131: #endif
                    132: 
                    133: #undef kIDHash3Byte
                    134: #undef kIDHash3String
                    135: 
                    136: #ifdef __HASH_3
                    137:   #define kIDHash3Byte 0x04
                    138:   #define kIDHash3String TEXT("H")
                    139: #else
                    140:   #define kIDHash3Byte 0x00
                    141:   #define kIDHash3String TEXT("")
                    142: #endif
                    143: 
                    144: #undef kIDUse3BytesByte
                    145: #undef kIDUse3BytesString
                    146: 
                    147: #define kIDUse3BytesByte 0x00
                    148: #define kIDUse3BytesString TEXT("")
                    149: 
                    150: #undef kIDPaddingByte
                    151: #undef kIDPaddingString
                    152: 
                    153: #ifdef __NODE_2_BITS_PADDING
                    154:   #define kIDPaddingByte 0x01
                    155:   #define kIDPaddingString TEXT("P")
                    156: #else
                    157:   #define kIDPaddingByte 0x00
                    158:   #define kIDPaddingString TEXT("")
                    159: #endif
                    160: 
                    161: 
                    162: // #undef kIDString
                    163: // #define kIDString TEXT("Compress.MatchFinderPat") kIDNumBitsString kIDManualRemoveString kIDUse3BytesString kIDPaddingString kIDHash3String
                    164: 
                    165: // {23170F69-40C1-278C-01XX-0000000000}
                    166: 
                    167: DEFINE_GUID(PAT_CLSID, 
                    168: 0x23170F69, 0x40C1, 0x278C, 0x01, 
                    169: kIDNumBitsByte | 
                    170: kIDManualRemoveByte | kIDHash3Byte | kIDUse3BytesByte | kIDPaddingByte, 
                    171: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
                    172: 
                    173: // III(PAT_NAMESPACE)
                    174: 
                    175: class CPatricia: 
                    176:   public IMatchFinder,
                    177:   public IMatchFinderSetCallback,
                    178:   public CMyUnknownImp,
                    179:   CLZInWindow
                    180: { 
                    181:   MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
                    182: 
                    183:   STDMETHOD(Init)(ISequentialInStream *aStream);
                    184:   STDMETHOD_(void, ReleaseStream)();
                    185:   STDMETHOD(MovePos)();
                    186:   STDMETHOD_(Byte, GetIndexByte)(Int32 index);
                    187:   STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
                    188:   STDMETHOD_(UInt32, GetNumAvailableBytes)();
                    189:   STDMETHOD(Create)(UInt32 historySize, 
                    190:       UInt32 keepAddBufferBefore, UInt32 matchMaxLen, 
                    191:       UInt32 keepAddBufferAfter);
                    192:   STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
                    193:   STDMETHOD_(void, DummyLongestMatch)();
                    194:   STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
                    195: 
                    196:   void FreeMemory();
                    197: public:
                    198:   CPatricia();
                    199:   ~CPatricia();
                    200: 
                    201:   UInt32 _sizeHistory;
                    202:   UInt32 _matchMaxLen;
                    203: 
                    204:   CDescendant *m_HashDescendants;
                    205:   #ifdef __HASH_3
                    206:   CDescendant *m_Hash2Descendants;
                    207:   #endif
                    208: 
                    209:   CNode *m_Nodes;
                    210: 
                    211:   UInt32 m_FreeNode;
                    212:   UInt32 m_FreeNodeMax;
                    213: 
                    214:   #ifdef __AUTO_REMOVE
                    215:   UInt32 m_NumUsedNodes;
                    216:   UInt32 m_NumNodes;
                    217:   #else
                    218:   bool  m_SpecialRemoveMode;
                    219:   #endif
                    220: 
                    221:   bool  m_SpecialMode;
                    222:   UInt32 m_NumNotChangedCycles;
                    223:   UInt32 *m_TmpBacks;
                    224: 
                    225:   CMyComPtr<IMatchFinderCallback> m_Callback;
                    226: 
                    227:   virtual void BeforeMoveBlock();
                    228:   virtual void AfterMoveBlock();
                    229: 
                    230:   // IMatchFinderSetCallback
                    231:   STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
                    232: 
                    233:   void ChangeLastMatch(UInt32 hashValue);
                    234:   
                    235:   #ifdef __AUTO_REMOVE
                    236:   void TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos);
                    237:   void TestRemoveNodes();
                    238:   void RemoveNode(UInt32 index);
                    239:   void TestRemoveAndNormalizeDescendant(CDescendant &descendant, 
                    240:       UInt32 limitPos, UInt32 subValue);
                    241:   void TestRemoveNodesAndNormalize();
                    242:   #else
                    243:   void NormalizeDescendant(CDescendant &descendant, UInt32 subValue);
                    244:   void Normalize();
                    245:   void RemoveMatch();
                    246:   #endif
                    247: private:
                    248:   void AddInternalNode(CNodePointer aNode, CIndex *aNodePointerPointer, 
                    249:       Byte aByte, Byte aByteXOR, UInt32 aNumSameBits, UInt32 aPos)
                    250:   {
                    251:     while((aByteXOR & kSubNodesMask) == 0)
                    252:     {
                    253:       aByteXOR >>= kNumSubBits;
                    254:       aByte >>= kNumSubBits;
                    255:       aNumSameBits -= kNumSubBits;
                    256:     }
                    257:     // Insert New Node
                    258:     CNodePointer aNewNode = &m_Nodes[m_FreeNode];
                    259:     UInt32 aNodeIndex = *aNodePointerPointer;
                    260:     *aNodePointerPointer = m_FreeNode;
                    261:     m_FreeNode = aNewNode->NextFreeNode;
                    262:     #ifdef __AUTO_REMOVE
                    263:     m_NumUsedNodes++;
                    264:     #endif
                    265:     if (m_FreeNode > m_FreeNodeMax)
                    266:     {
                    267:       m_FreeNodeMax = m_FreeNode;
                    268:       m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
                    269:     }
                    270: 
                    271:     UInt32 aBitsNew = aByte & kSubNodesMask;
                    272:     UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
                    273:     for (UInt32 i = 0; i < kNumSubNodes; i++)
                    274:       aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
                    275:     aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
                    276:     aNewNode->Descendants[aBitsOld].NodePointer = aNodeIndex;
                    277:     aNewNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits);
                    278:     aNewNode->LastMatch = aPos;
                    279:     
                    280:     aNode->NumSameBits = CSameBitsType(aNumSameBits - kNumSubBits);
                    281:   }
                    282: 
                    283:   void AddLeafNode(CNodePointer aNode, Byte aByte, Byte aByteXOR, 
                    284:       UInt32 aNumSameBits, UInt32 aPos, UInt32 aDescendantIndex)
                    285:   {
                    286:     for(;(aByteXOR & kSubNodesMask) == 0; aNumSameBits += kNumSubBits)
                    287:     {
                    288:       aByte >>= kNumSubBits;
                    289:       aByteXOR >>= kNumSubBits;
                    290:     }
                    291:     UInt32 aNewNodeIndex = m_FreeNode;
                    292:     CNodePointer aNewNode = &m_Nodes[m_FreeNode];
                    293:     m_FreeNode = aNewNode->NextFreeNode;
                    294:     #ifdef __AUTO_REMOVE
                    295:     m_NumUsedNodes++;
                    296:     #endif
                    297:     if (m_FreeNode > m_FreeNodeMax)
                    298:     {
                    299:       m_FreeNodeMax = m_FreeNode;
                    300:       m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
                    301:     }
                    302: 
                    303:     UInt32 aBitsNew = (aByte & kSubNodesMask);
                    304:     UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
                    305:     for (UInt32 i = 0; i < kNumSubNodes; i++)
                    306:       aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
                    307:     aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
                    308:     aNewNode->Descendants[aBitsOld].MatchPointer = 
                    309:       aNode->Descendants[aDescendantIndex].MatchPointer;
                    310:     aNewNode->NumSameBits = CSameBitsType(aNumSameBits);
                    311:     aNewNode->LastMatch = aPos;
                    312:     aNode->Descendants[aDescendantIndex].NodePointer = aNewNodeIndex;
                    313:   }
                    314: };
                    315: 
                    316: }
                    317: 
                    318: // #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>