From 3ffd0be53af0c5338e6fdc77d240e976aeb10451 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 26 Oct 2012 20:03:33 -0700
Subject: [PATCH] SH-3405 WIP convert existing stats to lltrace system fixed
 llpredicate so that values and rules work uniformly with predicate logic
 and/or/negate works in parallel with set/clear

---
 indra/llcommon/llinitparam.cpp |   2 +-
 indra/llcommon/llinitparam.h   |  64 +++++------
 indra/llcommon/llpredicate.cpp |  22 ++--
 indra/llcommon/llpredicate.h   | 199 +++++++++++++++++++++------------
 4 files changed, 166 insertions(+), 121 deletions(-)

diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index 69f97e87c4b..c66659a6963 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -190,7 +190,7 @@ namespace LLInitParam
 		bool serialized = false;
 		if (!isProvided())
 		{
-			if ((~predicate_rule_t(PROVIDED) && predicate_rule).isTriviallyFalse())
+			if (predicate_rule_t(~ll_predicate(PROVIDED) && predicate_rule).isTriviallyFalse())
 			{
 				return false;
 			}
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 9530e562f6d..b52ac809e06 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -545,7 +545,7 @@ namespace LLInitParam
 		}
 
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
-		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(), const BaseBlock* diff_block = NULL) const;
+		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(ll_predicate(PROVIDED) && ll_predicate(NON_DEFAULT)), const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
 		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -912,17 +912,17 @@ namespace LLInitParam
 			const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
 
 			LLPredicate::Value<ESerializePredicates> predicate;
-			if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
+			predicate.set(NON_DEFAULT, !diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()));
+
+			if (typed_param.isValid())
 			{
-				predicate.add(NON_DEFAULT);
+				predicate.set(VALID, true);
+				predicate.set(PROVIDED, typed_param.anyProvided());
 			}
-			if (typed_param.isValid())
+			else
 			{
-				predicate.add(VALID);
-				if (typed_param.anyProvided())
-				{
-					predicate.add(PROVIDED);
-				}
+				predicate.set(VALID, false);
+				predicate.set(PROVIDED, false);
 			}
 
 			if (!predicate_rule.check(predicate)) return false;
@@ -1076,11 +1076,13 @@ namespace LLInitParam
 
 			if (typed_param.isValid())
 			{
-				predicate.add(VALID);
-				if (typed_param.anyProvided())
-				{
-					predicate.add(PROVIDED);
-				}
+				predicate.set(VALID, true);
+				predicate.set(PROVIDED, typed_param.anyProvided());
+			}
+			else
+			{
+				predicate.set(VALID, false);
+				predicate.set(PROVIDED, false);
 			}
 
 			if (!predicate_rule.check(predicate)) return false;
@@ -1270,19 +1272,18 @@ namespace LLInitParam
 			
 			LLPredicate::Value<ESerializePredicates> predicate;
 
-			if (typed_param.mMinCount > 0)
-			{
-				predicate.add(REQUIRED);
-			}
+			predicate.set(REQUIRED, typed_param.mMinCount > 0);
 
 			if (typed_param.isValid())
 			{
-				predicate.add(VALID);
-				if (typed_param.anyProvided())
-				{
-					predicate.add(PROVIDED);
-				}
+				predicate.set(VALID, true);
+				predicate.set(PROVIDED, typed_param.anyProvided());
 			}
+			else
+			{
+				predicate.set(VALID, false);
+				predicate.set(PROVIDED, false);
+			}			
 
 			if (!predicate_rule.check(predicate)) return false;
 
@@ -1531,19 +1532,18 @@ namespace LLInitParam
 
 			LLPredicate::Value<ESerializePredicates> predicate;
 
-			if (typed_param.mMinCount > 0)
-			{
-				predicate.add(REQUIRED);
-			}
+			predicate.set(REQUIRED, typed_param.mMinCount > 0);
 
 			if (typed_param.isValid())
 			{
-				predicate.add(VALID);
-				if (typed_param.anyProvided())
-				{
-					predicate.add(PROVIDED);
-				}
+				predicate.set(VALID, true);
+				predicate.set(PROVIDED, typed_param.anyProvided());
 			}
+			else
+			{
+				predicate.set(VALID, false);
+				predicate.set(PROVIDED, false);
+			}	
 
 			if (!predicate_rule.check(predicate)) return false;
 
diff --git a/indra/llcommon/llpredicate.cpp b/indra/llcommon/llpredicate.cpp
index e3410ef3f62..1278948e247 100644
--- a/indra/llcommon/llpredicate.cpp
+++ b/indra/llcommon/llpredicate.cpp
@@ -29,19 +29,13 @@
 
 namespace LLPredicate
 {
-	EmptyRule make_rule() { return EmptyRule(); }
-
-	S32 predicateFlagsFromValue(S32 value)
+	const U32 cPredicateFlagsFromEnum[5] = 
 	{
-		llassert(value < 5);
-		static const S32 predicates[5] = 
-		{
-			0xAAAAaaaa, //  10101010101010101010101010101010
-			0xCCCCcccc, //  11001100110011001100110011001100
-			0xF0F0F0F0, //  11110000111100001111000011110000
-			0xFF00FF00, //  11111111000000001111111100000000
-			0xFFFF0000  //  11111111111111110000000000000000 
-		};
-		return predicates[value];
-	}
+		0xAAAAaaaa, // 10101010101010101010101010101010
+		0xCCCCcccc, // 11001100110011001100110011001100
+		0xF0F0F0F0, // 11110000111100001111000011110000
+		0xFF00FF00, // 11111111000000001111111100000000
+		0xFFFF0000  // 11111111111111110000000000000000 
+	};
 }
+
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
index 5fd1d30295a..3f1bf1c8e6e 100644
--- a/indra/llcommon/llpredicate.h
+++ b/indra/llcommon/llpredicate.h
@@ -33,129 +33,180 @@ namespace LLPredicate
 {
 	template<typename ENUM> class Rule;
 
-	S32 predicateFlagsFromValue(S32 value);
+	extern const U32 cPredicateFlagsFromEnum[5];
 
 	template<typename ENUM>
-	struct Value
+	class Literal
 	{
 		friend Rule<ENUM>;
+
 	public:
-		Value(ENUM e)
-		:	mPredicateCombinationFlags(0xFFFFffff)
+		typedef U32 predicate_flag_t;
+		static const S32 cMaxEnum = 5;
+
+		Literal(ENUM e)
+		:	mPredicateFlags(cPredicateFlagsFromEnum[e])
 		{
-			add(e);
+			llassert(0 <= e && e < cMaxEnum);
 		}
 
-		Value()
-		:	mPredicateCombinationFlags(0xFFFFffff)
+		Literal()
+		:	mPredicateFlags(0xFFFFffff)
 		{}
 
-		void add(ENUM predicate)
+		Literal operator~()
 		{
-			llassert(predicate < 5);
-			S32 predicate_shift = 0x1 << (S32)predicate;
-			S32 flag_mask = predicateFlagsFromValue(predicate);
-			S32 flags_to_modify = mPredicateCombinationFlags & ~flag_mask;
-			// clear flags containing predicate to be removed
-			mPredicateCombinationFlags &= ~flag_mask;
-			// shift flags, in effect removing predicate
-			flags_to_modify <<= predicate_shift;
-			// put modified flags back
-			mPredicateCombinationFlags |= flags_to_modify;
+			Literal new_rule;
+			new_rule.mPredicateFlags = ~mPredicateFlags;
+			return new_rule;
 		}
 
-		void remove(ENUM predicate)
+		Literal operator &&(const Literal& other)
 		{
-			llassert(predicate < 5);
-			S32 predicate_shift = 0x1 << (S32)predicate;
-			S32 flag_mask = predicateFlagsFromValue(predicate);
-			S32 flags_to_modify = mPredicateCombinationFlags & flag_mask;
-			// clear flags containing predicate to be removed
-			mPredicateCombinationFlags &= ~flag_mask;
-			// shift flags, in effect removing predicate
-			flags_to_modify >>= predicate_shift;
-			// put modified flags back
-			mPredicateCombinationFlags |= flags_to_modify;
+			Literal new_rule;
+			new_rule.mPredicateFlags = mPredicateFlags & other.mPredicateFlags;
+			return new_rule;
 		}
 
-		void unknown(ENUM predicate)
+		Literal operator ||(const Literal& other)
 		{
-			add(predicate);
-			S32 flags_with_predicate = mPredicateCombinationFlags;
-			remove(predicate);
-			// unknown is result of adding and removing predicate at the same time!
-			mPredicateCombinationFlags |= flags_with_predicate;
+			Literal new_rule;
+			new_rule.mPredicateFlags = mPredicateFlags | other.mPredicateFlags;
+			return new_rule;
 		}
 
-		bool has(ENUM predicate)
+		void set(ENUM e, bool value)
 		{
-			S32 flag_mask = predicateFlagsFromValue(predicate);
-			return (mPredicateCombinationFlags & flag_mask) != 0;
+			llassert(0 <= e && e < cMaxEnum);
+			modifyPredicate(0x1 << (S32)e, cPredicateFlagsFromEnum[e], value);
+		}
+
+		void set(const Literal& other, bool value)
+		{
+			U32 predicate_flags = other.mPredicateFlags;
+			while(predicate_flags)
+			{
+				U32 next_flags = clearLSB(predicate_flags);
+				lsb_flag = predicate_flags ^ next_flags;
+				U32 mask = 0;
+				for (S32 i = 0; i < cMaxEnum; i++)
+				{
+					if (cPredicateFlagsFromEnum[i] & lsb_flag)
+					{
+						mask |= cPredicateFlagsFromEnum[i];
+					}
+				}
+
+				modifyPredicate(lsb_flag, mask, value);
+				
+				predicate_flags = next_flags;
+			} 
+		}
+
+		void forget(ENUM e)
+		{
+			set(e, true);
+			U32 flags_with_predicate = mPredicateFlags;
+			set(e, false);
+			// ambiguous value is result of adding and removing predicate at the same time!
+			mPredicateFlags |= flags_with_predicate;
+		}
+
+		void forget(const Literal& literal)
+		{
+			set(literal, true);
+			U32 flags_with_predicate = mPredicateFlags;
+			set(literal, false);
+			// ambiguous value is result of adding and removing predicate at the same time!
+			mPredicateFlags |= flags_with_predicate;
 		}
 
 	private:
-		S32 mPredicateCombinationFlags;
+
+		predicate_flag_t clearLSB(predicate_flag_t value)
+		{
+			return value & (value - 1);
+		}
+
+		void modifyPredicate(predicate_flag_t predicate_flag, predicate_flag_t mask, bool value)
+		{
+			llassert(clearLSB(predicate_flag) == 0);
+			predicate_flag_t flags_to_modify;
+
+			if (value)
+			{
+				flags_to_modify = (mPredicateFlags & ~mask);
+				// clear flags not containing predicate to be added
+				mPredicateFlags &= mask;
+				// shift flags, in effect adding predicate
+				flags_to_modify *= predicate_flag;
+			}
+			else
+			{
+				flags_to_modify = mPredicateFlags & mask;
+				// clear flags containing predicate to be removed
+				mPredicateFlags &= ~mask;
+				// shift flags, in effect removing predicate
+				flags_to_modify /= predicate_flag;
+			}
+			// put modified flags back
+			mPredicateFlags |= flags_to_modify;
+		}
+
+		predicate_flag_t mPredicateFlags;
 	};
 
-	struct EmptyRule {};
+	template<typename ENUM>
+	struct Value
+	:	public Literal<ENUM>
+	{
+	public:
+		Value(ENUM e)
+		:	Literal(e)
+		{}
+
+		Value()
+		{}
+	};
 
 	template<typename ENUM>
 	class Rule
+	:	public Literal<ENUM>
 	{
 	public:
 		Rule(ENUM value)
-		:	mPredicateRequirements(predicateFlagsFromValue(value))
+		:	Literal(value)
 		{}
 
-		Rule()
-		:	mPredicateRequirements(0x1)
+		Rule(const Literal other)
+		:	Literal(other)
 		{}
 
-		Rule operator~()
-		{
-			Rule new_rule;
-			new_rule.mPredicateRequirements = ~mPredicateRequirements;
-			return new_rule;
-		}
-
-		Rule operator &&(const Rule& other)
-		{
-			Rule new_rule;
-			new_rule.mPredicateRequirements = mPredicateRequirements & other.mPredicateRequirements;
-			return new_rule;
-		}
-
-		Rule operator ||(const Rule& other)
-		{
-			Rule new_rule;
-			new_rule.mPredicateRequirements = mPredicateRequirements | other.mPredicateRequirements;
-			return new_rule;
-		}
+		Rule()
+		{}
 
 		bool check(const Value<ENUM>& value) const
 		{
-			return ((value.mPredicateCombinationFlags | 0x1) & mPredicateRequirements) != 0;
+			return (value.mPredicateFlags & mPredicateFlags) != 0;
 		}
 
 		bool isTriviallyTrue() const
 		{
-			return mPredicateRequirements & 0x1;
+			return mPredicateFlags == 0xFFFFffff;
 		}
 
 		bool isTriviallyFalse() const
 		{
-			return mPredicateRequirements == 0;
+			return mPredicateFlags == 0;
 		}
-
-	private:
-		S32 mPredicateRequirements;
 	};
+}
 
-	template<typename ENUM>
-	Rule<ENUM> make_rule(ENUM e) { return Rule<ENUM>(e);}
+template<typename ENUM>
+LLPredicate::Literal<ENUM> ll_predicate(ENUM e)
+{
+	 return LLPredicate::Literal<ENUM>(e);
+}
 
-	// return generic empty rule class to avoid requiring template argument to create an empty rule
-	EmptyRule make_rule();
 
-}
 #endif // LL_LLPREDICATE_H
-- 
GitLab