~CPack() {};
};
-class CPack::PatternZZZZ : public DictionaryCompressor::Pattern
+class CPack::PatternZZZZ : public MaskedValuePattern<0, 0xFFFFFFFF>
{
public:
PatternZZZZ(const DictionaryEntry bytes, const int match_location)
- : Pattern(ZZZZ, 0x0, 2, 0, 0, false) {}
-
- static bool isPattern(const DictionaryEntry& bytes,
- const DictionaryEntry& dict_bytes,
- const int match_location)
+ : MaskedValuePattern<0, 0xFFFFFFFF>(ZZZZ, 0x0, 2, match_location,
+ bytes)
{
- return (bytes[3] == 0) && (bytes[2] == 0) && (bytes[1] == 0) &&
- (bytes[0] == 0);
- }
-
- DictionaryEntry
- decompress(const DictionaryEntry dict_bytes) const override
- {
- return {0, 0, 0, 0};
}
};
}
};
-class CPack::PatternZZZX : public DictionaryCompressor::Pattern
+class CPack::PatternZZZX : public MaskedValuePattern<0, 0xFFFFFF00>
{
- private:
- /**
- * A copy of the unmatched byte.
- */
- const uint8_t byte;
-
public:
PatternZZZX(const DictionaryEntry bytes, const int match_location)
- : Pattern(ZZZX, 0xD, 4, 1, 0, false), byte(bytes[0]) {}
-
- static bool isPattern(const DictionaryEntry& bytes,
- const DictionaryEntry& dict_bytes,
- const int match_location)
- {
- return (bytes[3] == 0) && (bytes[2] == 0) && (bytes[1] == 0) &&
- (bytes[0] != 0);
- }
-
- DictionaryEntry
- decompress(const DictionaryEntry dict_bytes) const override
+ : MaskedValuePattern<0, 0xFFFFFF00>(ZZZX, 0xD, 4, match_location,
+ bytes)
{
- return {byte, 0, 0, 0};
}
};
class UncompressedPattern;
template <T mask>
class MaskedPattern;
+ template <T value, T mask>
+ class MaskedValuePattern;
/**
* Create a factory to determine if input matches a pattern. The if else
}
};
+/**
+ * A pattern that compares masked values to a masked portion of a fixed value.
+ * If all the masked bits match the provided non-dictionary value, there is a
+ * pattern match.
+ *
+ * For example, assume the mask is 0xFF00 (that is, this pattern matches the
+ * MSB), and we are searching for data containing only ones (i.e., the fixed
+ * value is 0xFFFF).
+ * If the value (V) 0xFF20 is being compressed, this is a match (V & mask ==
+ * 0xFF00 == 0xFFFF & mask), and 0x20 is added to the list of unmatched bits.
+ * If the value (V2) 0x0120 is being compressed, this is not a match
+ * ((V2 & mask == 0x0100) != (0xFF00 == 0xFFFF & mask).
+ *
+ * @tparam value The value that is being matched against.
+ * @tparam mask A mask containing the bits that must match the given value.
+ */
+template <class T>
+template <T value, T mask>
+class DictionaryCompressor<T>::MaskedValuePattern
+ : public MaskedPattern<mask>
+{
+ private:
+ static_assert(mask != 0, "The pattern's value mask must not be zero.");
+
+ public:
+ MaskedValuePattern(const int number,
+ const uint64_t code,
+ const uint64_t metadata_length,
+ const int match_location,
+ const DictionaryEntry bytes,
+ const bool allocate = false)
+ : MaskedPattern<mask>(number, code, metadata_length, match_location,
+ bytes, allocate)
+ {
+ }
+
+ static bool
+ isPattern(const DictionaryEntry& bytes, const DictionaryEntry& dict_bytes,
+ const int match_location)
+ {
+ // Compare the masked fixed value to the value being checked for
+ // patterns. Since the dictionary is not being used the match_location
+ // is irrelevant.
+ const T masked_bytes =
+ DictionaryCompressor<T>::fromDictionaryEntry(bytes) & mask;
+ return ((value & mask) == masked_bytes);
+ }
+
+ DictionaryEntry
+ decompress(const DictionaryEntry dict_bytes) const override
+ {
+ return MaskedPattern<mask>::decompress(
+ DictionaryCompressor<T>::toDictionaryEntry(value));
+ }
+};
+
#endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_HH__