Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZ/Patricia/Pat.h, revision 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>