Parallel Full Hash Join

Started by Thomas Munroover 6 years ago41 messages
#1Thomas Munro
thomas.munro@gmail.com
1 attachment(s)

Hello,

While thinking about looping hash joins (an alternative strategy for
limiting hash join memory usage currently being investigated by
Melanie Plageman in a nearby thread[1]/messages/by-id/CA+hUKGKWWmf=WELLG=aUGbcugRaSQbtm0tKYiBut-B2rVKX63g@mail.gmail.com), the topic of parallel query
deadlock hazards came back to haunt me. I wanted to illustrate the
problems I'm aware of with the concrete code where I ran into this
stuff, so here is a new-but-still-broken implementation of $SUBJECT.
This was removed from the original PHJ submission when I got stuck and
ran out of time in the release cycle for 11. Since the original
discussion is buried in long threads and some of it was also a bit
confused, here's a fresh description of the problems as I see them.
Hopefully these thoughts might help Melanie's project move forward,
because it's closely related, but I didn't want to dump another patch
into that other thread. Hence this new thread.

I haven't succeeded in actually observing a deadlock with the attached
patch (though I did last year, very rarely), but I also haven't tried
very hard. The patch seems to produce the right answers and is pretty
scalable, so it's really frustrating not to be able to get it over the
line.

Tuple queue deadlock hazard:

If the leader process is executing the subplan itself and waiting for
all processes to arrive in ExecParallelHashEndProbe() (in this patch)
while another process has filled up its tuple queue and is waiting for
the leader to read some tuples an unblock it, they will deadlock
forever. That can't happen in the the committed version of PHJ,
because it never waits for barriers after it has begun emitting
tuples.

Some possible ways to fix this:

1. You could probably make it so that the PHJ_BATCH_SCAN_INNER phase
in this patch (the scan for unmatched tuples) is executed by only one
process, using the "detach-and-see-if-you-were-last" trick. Melanie
proposed that for an equivalent problem in the looping hash join. I
think it probably works, but it gives up a lot of parallelism and thus
won't scale as nicely as the attached patch.

2. You could probably make it so that only the leader process drops
out of executing the inner unmatched scan, and then I think you
wouldn't have this very specific problem at the cost of losing some
(but not all) parallelism (ie the leader), but there might be other
variants of the problem. For example, a GatherMerge leader process
might be blocked waiting for the next tuple for a tuple from P1, while
P2 is try to write to a full queue, and P1 waits for P2.

3. You could introduce some kind of overflow for tuple queues, so
that tuple queues can never block because they're full (until you run
out of extra memory buffers or disk and error out). I haven't
seriously looked into this but I'm starting to suspect it's the
industrial strength general solution to the problem and variants of it
that show up in other parallelism projects (Parallel Repartition). As
Robert mentioned last time I talked about this[2]/messages/by-id/CA+TgmoY4LogYcg1y5JPtto_fL-DBUqvxRiZRndDC70iFiVsVFQ@mail.gmail.com, you'd probably only
want to allow spooling (rather than waiting) when the leader is
actually waiting for other processes; I'm not sure how exactly to
control that.

4. <thinking-really-big>Goetz Graefe's writing about parallel sorting
comes close to this topic, which he calls flow control deadlocks. He
mentions the possibility of infinite spooling like (3) as a solution.
He's describing a world where producers and consumers are running
concurrently, and the consumer doesn't just decide to start running
the subplan (what we call "leader participation"), so he doesn't
actually have a problem like Gather deadlock. He describes
planner-enforced rules that allow deadlock free execution even with
fixed-size tuple queue flow control by careful controlling where
order-forcing operators are allowed to appear, so he doesn't have a
problem like Gather Merge deadlock. I'm not proposing we should
create a whole bunch of producer and consumer processes to run
different plan fragments, but I think you can virtualise the general
idea in an async executor with "streams", and that also solves other
problems when you start working with partitions in a world where it's
not even sure how many workers will show up. I see this as a long
term architectural goal requiring vast amounts of energy to achieve,
hence my new interest in (3) for now.</thinking-really-big>

Hypothetical inter-node deadlock hazard:

Right now I think it is the case the whenever any node begins pulling
tuples from a subplan, it continues to do so until either the query
ends early or the subplan runs out of tuples. For example, Append
processes its subplans one at a time until they're done -- it doesn't
jump back and forth. Parallel Append doesn't necessarily run them in
the order that they appear in the plan, but it still runs each one to
completion before picking another one. If we ever had a node that
didn't adhere to that rule, then two Parallel Full Hash Join nodes
could dead lock, if some of the workers were stuck waiting in one
while some were stuck waiting in the other.

If we were happy to decree that that is a rule of the current
PostgreSQL executor, then this hypothetical problem would go away.
For example, consider the old patch I recently rebased[3]/messages/by-id/CA+hUKGLBRyu0rHrDCMC4=Rn3252gogyp1SjOgG8SEKKZv=FwfQ@mail.gmail.com to allow
Append over a bunch of FDWs representing remote shards to return
tuples as soon as they're ready, not necessarily sequentially (and I
think several others have worked on similar patches). To be
committable under such a rule that applies globally to the whole
executor, that patch would only be allowed to *start* them in any
order, but once it's started pulling tuples from a given subplan it'd
have to pull them all to completion before considering another node.

(Again, that problem goes away in an async model like (4), which will
also be able to do much more interesting things with FDWs, and it's
the FDW thing that I think generates more interest in async execution
than my rambling about abstract parallel query problems.)

Some other notes on the patch:

Aside from the deadlock problem, there are some minor details to tidy
up (handling of late starters probably not quite right, rescans not
yet considered). There is a fun hard-coded parameter that controls
the parallel step size in terms of cache lines for the unmatched scan;
I found that 8 was a lot faster than 4, but no slower than 128 on my
laptop, so I set it to 8. More thoughts along those micro-optimistic
lines: instead of match bit in the header, you could tag the pointer
and sometimes avoid having to follow it, and you could prefetch next
non-matching tuple's cacheline by looking a head a bit.

[1]: /messages/by-id/CA+hUKGKWWmf=WELLG=aUGbcugRaSQbtm0tKYiBut-B2rVKX63g@mail.gmail.com
[2]: /messages/by-id/CA+TgmoY4LogYcg1y5JPtto_fL-DBUqvxRiZRndDC70iFiVsVFQ@mail.gmail.com
[3]: /messages/by-id/CA+hUKGLBRyu0rHrDCMC4=Rn3252gogyp1SjOgG8SEKKZv=FwfQ@mail.gmail.com

--
Thomas Munro
https://enterprisedb.com

Attachments:

0001-WIP-Add-support-for-Parallel-Full-Hash-Join.patchapplication/octet-stream; name=0001-WIP-Add-support-for-Parallel-Full-Hash-Join.patchDownload
From 549bd36fc39282503d2ab83f7827437ddf6f3e1b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 12 Sep 2019 00:30:49 +1200
Subject: [PATCH] WIP:  Add support for Parallel Full Hash Join.

This has an unsolved problem: it's dangerous to run BarrierArriveAndWait()
when you're in a phase that has emitted tuples, because some process P
might be blocked writing to a full tuple queue, while the leader process,
which should be reading it, is also running the subplan and is waiting
for P!
---
 src/backend/executor/nodeHash.c         | 90 +++++++++++++++++++++++--
 src/backend/executor/nodeHashjoin.c     | 35 ++++++++--
 src/backend/optimizer/path/joinpath.c   |  9 +--
 src/backend/postmaster/pgstat.c         |  3 +
 src/backend/storage/ipc/barrier.c       |  1 -
 src/include/executor/hashjoin.h         |  5 +-
 src/include/executor/nodeHash.h         |  2 +
 src/include/nodes/execnodes.h           |  2 +
 src/include/pgstat.h                    |  1 +
 src/test/regress/expected/join_hash.out | 56 ++++++++++++++-
 src/test/regress/sql/join_hash.sql      | 23 ++++++-
 11 files changed, 204 insertions(+), 23 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 224cbb32ba..c366a523c6 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2050,6 +2050,7 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
 }
 
 /*
@@ -2126,6 +2127,87 @@ ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 	return false;
 }
 
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+
+	for (;;)
+	{
+		/*
+		 * hj_CurTuple is the address of the tuple last returned from the
+		 * current bucket, or NULL if it's time to start scanning a new
+		 * bucket.
+		 */
+		if (hashTuple != NULL)
+			hashTuple = ExecParallelHashNextTuple(hashtable, hashTuple);
+		else if (hjstate->hj_CurBucketNo < hjstate->hj_AllocatedBucketRange)
+			hashTuple = ExecParallelHashFirstTuple(hashtable,
+												   hjstate->hj_CurBucketNo++);
+		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		{
+			/*
+			 * Allocate a few cachelines' worth of buckets and loop around.
+			 * Testing shows that 8 is a good factor.
+			 */
+			int step = (PG_CACHE_LINE_SIZE * 8) / sizeof(dsa_pointer_atomic);
+
+			hjstate->hj_CurBucketNo =
+				pg_atomic_fetch_add_u32(&hashtable->batches[hashtable->curbatch].shared->bucket,
+										step);
+			hjstate->hj_AllocatedBucketRange =
+				Min(hjstate->hj_CurBucketNo + step, hashtable->nbuckets);
+		}
+		else
+			break;				/* finished all buckets */
+
+		while (hashTuple != NULL)
+		{
+			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+			{
+				TupleTableSlot *inntuple;
+
+				/* insert hashtable's tuple into exec slot */
+				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+												 hjstate->hj_HashTupleSlot,
+												 false);	/* do not pfree */
+				econtext->ecxt_innertuple = inntuple;
+
+				/*
+				 * Reset temp memory each time; although this function doesn't
+				 * do any qual eval, the caller will, so let's keep it
+				 * parallel to ExecScanHashBucket.
+				 */
+				ResetExprContext(econtext);
+
+				hjstate->hj_CurTuple = hashTuple;
+				return true;
+			}
+
+			hashTuple = ExecParallelHashNextTuple(hashtable, hashTuple);
+		}
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+
 /*
  * ExecHashTableReset
  *
@@ -2937,6 +3019,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		 * up the Barrier.
 		 */
 		BarrierInit(&shared->batch_barrier, 0);
+		pg_atomic_init_u32(&shared->bucket, 0);
 		if (i == 0)
 		{
 			/* Batch 0 doesn't need to be loaded. */
@@ -3097,13 +3180,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index ec37558c12..1c9a40dcff 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,6 +82,7 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
+ *  PHJ_BATCH_SCAN_INNER     -- scan unmatched inner tuples
  *  PHJ_BATCH_DONE           -- end
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -97,9 +98,9 @@
  * all other backends attached to it are actively executing the node or have
  * already arrived.  Practically, that means that we never return a tuple
  * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * state.
+ *
+ * TODO: WIP: That's now not true, because of PHJ_SCAN_INNER.
  *
  *-------------------------------------------------------------------------
  */
@@ -144,6 +145,7 @@ static TupleTableSlot *ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
 												 uint32 *hashvalue,
 												 TupleTableSlot *tupleSlot);
 static bool ExecHashJoinNewBatch(HashJoinState *hjstate);
+static void ExecParallelHashEndProbe(HashJoinState *hjstate);
 static bool ExecParallelHashJoinNewBatch(HashJoinState *hjstate);
 static void ExecParallelHashJoinPartitionOuter(HashJoinState *node);
 
@@ -358,6 +360,9 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				if (TupIsNull(outerTupleSlot))
 				{
 					/* end of batch, or maybe whole join */
+					if (parallel)
+						ExecParallelHashEndProbe(node);
+
 					if (HJ_FILL_INNER(node))
 					{
 						/* set up to scan for unmatched inner tuples */
@@ -512,7 +517,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+							   : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -723,6 +729,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
 
 	hjstate->hj_OuterHashKeys = ExecInitExprList(node->hashkeys,
 												 (PlanState *) hjstate);
@@ -1060,6 +1067,18 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
 	return true;
 }
 
+static void
+ExecParallelHashEndProbe(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	Barrier *batch_barrier =
+		&hashtable->batches[hashtable->curbatch].shared->batch_barrier;
+
+	Assert(BarrierPhase(batch_barrier) == PHJ_BATCH_PROBING);
+	BarrierArriveAndWait(batch_barrier, WAIT_EVENT_HASH_BATCH_PROBING);
+	Assert(BarrierPhase(batch_barrier) == PHJ_BATCH_SCAN_INNER);
+}
+
 /*
  * Choose a batch to work on, and attach to it.  Returns true if successful,
  * false if there are no more batches.
@@ -1155,13 +1174,16 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * BarrierArriveAndDetach() so that the next phase can be
+					 * reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
+				case PHJ_BATCH_SCAN_INNER:
+					/* TODO -- not right */
+
 				case PHJ_BATCH_DONE:
 
 					/*
@@ -1335,6 +1357,7 @@ ExecReScanHashJoin(HashJoinState *node)
 	node->hj_CurBucketNo = 0;
 	node->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	node->hj_CurTuple = NULL;
+	node->hj_AllocatedBucketRange = 0;
 
 	node->hj_MatchedOuter = false;
 	node->hj_FirstOuterTupleSlot = NULL;
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index dc28b56e74..ef613d7696 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1853,8 +1853,6 @@ hash_inner_and_outer(PlannerInfo *root,
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1888,9 +1886,12 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * at all because no one process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 011076c3e3..d64cb976db 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3774,6 +3774,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BATCH_LOADING:
 			event_name = "Hash/Batch/Loading";
 			break;
+		case WAIT_EVENT_HASH_BATCH_PROBING:
+			event_name = "Hash/Batch/Probing";
+			break;
 		case WAIT_EVENT_HASH_BUILD_ALLOCATING:
 			event_name = "Hash/Build/Allocating";
 			break;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 83cbe33107..170d002444 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -221,7 +221,6 @@ BarrierAttach(Barrier *barrier)
 	++barrier->participants;
 	phase = barrier->phase;
 	SpinLockRelease(&barrier->mutex);
-
 	return phase;
 }
 
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 2c94b926d3..f68f4568df 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -160,6 +160,8 @@ typedef struct ParallelHashJoinBatch
 	size_t		old_ntuples;	/* number of tuples before repartitioning */
 	bool		space_exhausted;
 
+	pg_atomic_uint32 bucket;	/* bucket allocator for unmatched inner scan */
+
 	/*
 	 * Variable-sized SharedTuplestore objects follow this struct in memory.
 	 * See the accessor macros below.
@@ -265,7 +267,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_SCAN_INNER			4
+#define PHJ_BATCH_DONE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index fc80f03aa8..94b0be380a 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -58,6 +58,8 @@ extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econ
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index b593d22c48..bdf58cd2ee 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1913,6 +1913,7 @@ typedef struct MergeJoinState
  *								tuple, or NULL if starting search
  *								(hj_CurXXX variables are undefined if
  *								OuterTupleSlot is empty!)
+ *		hj_AllocatedBucketRange	range allocated for parallel unmatched scan
  *		hj_OuterTupleSlot		tuple slot for outer tuples
  *		hj_HashTupleSlot		tuple slot for inner (hashed) tuples
  *		hj_NullOuterTupleSlot	prepared null tuple for right/full outer joins
@@ -1939,6 +1940,7 @@ typedef struct HashJoinState
 	uint32		hj_CurHashValue;
 	int			hj_CurBucketNo;
 	int			hj_CurSkewBucketNo;
+	int			hj_AllocatedBucketRange;
 	HashJoinTuple hj_CurTuple;
 	TupleTableSlot *hj_OuterTupleSlot;
 	TupleTableSlot *hj_HashTupleSlot;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index fe076d823d..ef2fbe39ca 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -827,6 +827,7 @@ typedef enum
 	WAIT_EVENT_HASH_BATCH_ALLOCATING,
 	WAIT_EVENT_HASH_BATCH_ELECTING,
 	WAIT_EVENT_HASH_BATCH_LOADING,
+	WAIT_EVENT_HASH_BATCH_PROBING,
 	WAIT_EVENT_HASH_BUILD_ALLOCATING,
 	WAIT_EVENT_HASH_BUILD_ELECTING,
 	WAIT_EVENT_HASH_BUILD_HASHING_INNER,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.22.0

#2Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#1)
2 attachment(s)
Re: Parallel Full Hash Join

On Wed, Sep 11, 2019 at 11:23 PM Thomas Munro <thomas.munro@gmail.com>
wrote:

While thinking about looping hash joins (an alternative strategy for
limiting hash join memory usage currently being investigated by
Melanie Plageman in a nearby thread[1]), the topic of parallel query
deadlock hazards came back to haunt me. I wanted to illustrate the
problems I'm aware of with the concrete code where I ran into this
stuff, so here is a new-but-still-broken implementation of $SUBJECT.
This was removed from the original PHJ submission when I got stuck and
ran out of time in the release cycle for 11. Since the original
discussion is buried in long threads and some of it was also a bit
confused, here's a fresh description of the problems as I see them.
Hopefully these thoughts might help Melanie's project move forward,
because it's closely related, but I didn't want to dump another patch
into that other thread. Hence this new thread.

I haven't succeeded in actually observing a deadlock with the attached
patch (though I did last year, very rarely), but I also haven't tried
very hard. The patch seems to produce the right answers and is pretty
scalable, so it's really frustrating not to be able to get it over the
line.

Tuple queue deadlock hazard:

If the leader process is executing the subplan itself and waiting for
all processes to arrive in ExecParallelHashEndProbe() (in this patch)
while another process has filled up its tuple queue and is waiting for
the leader to read some tuples an unblock it, they will deadlock
forever. That can't happen in the the committed version of PHJ,
because it never waits for barriers after it has begun emitting
tuples.

Some possible ways to fix this:

1. You could probably make it so that the PHJ_BATCH_SCAN_INNER phase
in this patch (the scan for unmatched tuples) is executed by only one
process, using the "detach-and-see-if-you-were-last" trick. Melanie
proposed that for an equivalent problem in the looping hash join. I
think it probably works, but it gives up a lot of parallelism and thus
won't scale as nicely as the attached patch.

I have attached a patch which implements this
(v1-0001-Parallel-FOJ-ROJ-single-worker-scan-buckets.patch).

For starters, in order to support parallel FOJ and ROJ, I re-enabled
setting the match bit for the tuples in the hashtable which
3e4818e9dd5be294d97c disabled. I did so using the code suggested in [1]/messages/by-id/0F44E799048C4849BAE4B91012DB910462E9897A@SHSMSX103.ccr.corp.intel.com,
reading the match bit to see if it is already set before setting it.

Then, workers except for the last worker detach after exhausting the
outer side of a batch, leaving one worker to proceed to HJ_FILL_INNER
and do the scan of the hash table and emit unmatched inner tuples.

I have also attached a variant on this patch which I am proposing to
replace it (v1-0001-Parallel-FOJ-ROJ-single-worker-scan-chunks.patch)
which has a new ExecParallelScanHashTableForUnmatched() in which the
single worker doing the unmatched scan scans one HashMemoryChunk at a
time and then frees them as it goes. I thought this might perform better
than the version which uses the buckets because 1) it should do a bit
less pointer chasing and 2) it frees each chunk of the hash table as it
scans it which (maybe) would save a bit of time during
ExecHashTableDetachBatch() when it goes through and frees the hash
table, but, my preliminary tests showed a negligible difference between
this and the version using buckets. I will do a bit more testing,
though.

I tried a few other variants of these patches, including one in which
the workers detach from the batch inside of the batch loading and
probing phase machine, ExecParallelHashJoinNewBatch(). This meant that
all workers transition to HJ_FILL_INNER and then HJ_NEED_NEW_BATCH in
order to detach in the batch phase machine. This, however, involved
adding a lot of new variables to distinguish whether or or not the
unmatched outer scan was already done, whether or not the current worker
was the worker elected to do the scan, etc. Overall, it is probably
incorrect to use the HJ_NEED_NEW_BATCH state in this way. I had
originally tried this to avoid operating on the batch_barrier in the
main hash join state machine. I've found that the more different places
we add code attaching and detaching to the batch_barrier (and other PHJ
barriers, for that matter), the harder it is to debug the code, however,
I think in this case it is required.

2. You could probably make it so that only the leader process drops
out of executing the inner unmatched scan, and then I think you
wouldn't have this very specific problem at the cost of losing some
(but not all) parallelism (ie the leader), but there might be other
variants of the problem. For example, a GatherMerge leader process
might be blocked waiting for the next tuple for a tuple from P1, while
P2 is try to write to a full queue, and P1 waits for P2.

3. You could introduce some kind of overflow for tuple queues, so
that tuple queues can never block because they're full (until you run
out of extra memory buffers or disk and error out). I haven't
seriously looked into this but I'm starting to suspect it's the
industrial strength general solution to the problem and variants of it
that show up in other parallelism projects (Parallel Repartition). As
Robert mentioned last time I talked about this[2], you'd probably only
want to allow spooling (rather than waiting) when the leader is
actually waiting for other processes; I'm not sure how exactly to
control that.

4. <thinking-really-big>Goetz Graefe's writing about parallel sorting
comes close to this topic, which he calls flow control deadlocks. He
mentions the possibility of infinite spooling like (3) as a solution.
He's describing a world where producers and consumers are running
concurrently, and the consumer doesn't just decide to start running
the subplan (what we call "leader participation"), so he doesn't
actually have a problem like Gather deadlock. He describes
planner-enforced rules that allow deadlock free execution even with
fixed-size tuple queue flow control by careful controlling where
order-forcing operators are allowed to appear, so he doesn't have a
problem like Gather Merge deadlock. I'm not proposing we should
create a whole bunch of producer and consumer processes to run
different plan fragments, but I think you can virtualise the general
idea in an async executor with "streams", and that also solves other
problems when you start working with partitions in a world where it's
not even sure how many workers will show up. I see this as a long
term architectural goal requiring vast amounts of energy to achieve,
hence my new interest in (3) for now.</thinking-really-big>

Hypothetical inter-node deadlock hazard:

Right now I think it is the case the whenever any node begins pulling
tuples from a subplan, it continues to do so until either the query
ends early or the subplan runs out of tuples. For example, Append
processes its subplans one at a time until they're done -- it doesn't
jump back and forth. Parallel Append doesn't necessarily run them in
the order that they appear in the plan, but it still runs each one to
completion before picking another one. If we ever had a node that
didn't adhere to that rule, then two Parallel Full Hash Join nodes
could dead lock, if some of the workers were stuck waiting in one
while some were stuck waiting in the other.

If we were happy to decree that that is a rule of the current
PostgreSQL executor, then this hypothetical problem would go away.
For example, consider the old patch I recently rebased[3] to allow
Append over a bunch of FDWs representing remote shards to return
tuples as soon as they're ready, not necessarily sequentially (and I
think several others have worked on similar patches). To be
committable under such a rule that applies globally to the whole
executor, that patch would only be allowed to *start* them in any
order, but once it's started pulling tuples from a given subplan it'd
have to pull them all to completion before considering another node.

(Again, that problem goes away in an async model like (4), which will
also be able to do much more interesting things with FDWs, and it's
the FDW thing that I think generates more interest in async execution
than my rambling about abstract parallel query problems.)

The leader exclusion tactics and the spooling idea don't solve the
execution order deadlock possibility, so, this "all except last detach
and last does unmatched inner scan" seems like the best way to solve
both types of deadlock.
There is another option that could maintain some parallelism for the
unmatched inner scan.

This method is exactly like the "all except last detach and last does
unmatched inner scan" method from the perspective of the main hash join
state machine. The difference is in ExecParallelHashJoinNewBatch(). In
the batch_barrier phase machine, workers loop around looking for batches
that are not done.

In this "detach for now" method, all workers except the last one detach
from a batch after exhausting the outer side. They will mark the batch
they were just working on as "provisionally done" (as opposed to
"done"). The last worker advances the batch_barrier from
PHJ_BATCH_PROBING to PHJ_BATCH_SCAN_INNER.

All detached workers then proceed to HJ_NEED_NEW_BATCH and try to find
another batch to work on. If there are no batches that are neither
"done" or "provisionally done", then the worker will re-attach to
batches that are "provisionally done" and attempt to join in conducting
the unmatched inner scan. Once it finishes its worker there, it will
return to HJ_NEED_NEW_BATCH, enter ExecParallelHashJoinNewBatch() and
mark the batch as "done".

Because the worker detached from the batch, this method solves the tuple
queue flow control deadlock issue--this worker could not be attempting
to emit a tuple while the leader waits at the barrier for it. There is
no waiting at the barrier.

However, it is unclear to me whether or not this method will be at risk
of inter-node deadlock/execution order deadlock. It seems like this is
not more at risk than the existing code is for this issue.

If a worker never returns to the HashJoin after leaving to emit a tuple,
in any of the methods (and in master), the query would not finish
correctly because the workers are attached to the batch_barrier while
emitting tuples and, though they may not wait at this barrier again, the
hashtable is cleaned up by the last participant to detach, and this
would not happen if it doesn't return to the batch phase machine. I'm
not sure if this exhibits the problematic behavior detailed above, but,
if it does, it is not unique to this method.

Some other notes on the patch:

Aside from the deadlock problem, there are some minor details to tidy
up (handling of late starters probably not quite right, rescans not
yet considered).

These would not be an issue with only one worker doing the scan but
would have to be handled in a potential new parallel-enabled solution
like I suggested above.

There is a fun hard-coded parameter that controls
the parallel step size in terms of cache lines for the unmatched scan;
I found that 8 was a lot faster than 4, but no slower than 128 on my
laptop, so I set it to 8.

I didn't add this cache line optimization to my chunk scanning method. I
could do so. Do you think it is more relevant, less relevant, or the
same if only one worker is doing the unmatched inner scan?

More thoughts along those micro-optimistic

lines: instead of match bit in the header, you could tag the pointer
and sometimes avoid having to follow it, and you could prefetch next
non-matching tuple's cacheline by looking a head a bit.

I would be happy to try doing this once we get the rest of the patch
ironed out so that seeing how much of a performance difference it makes
is more straightforward.

[1]
/messages/by-id/CA+hUKGKWWmf=WELLG=aUGbcugRaSQbtm0tKYiBut-B2rVKX63g@mail.gmail.com
[2]
/messages/by-id/CA+TgmoY4LogYcg1y5JPtto_fL-DBUqvxRiZRndDC70iFiVsVFQ@mail.gmail.com
[3]
/messages/by-id/CA+hUKGLBRyu0rHrDCMC4=Rn3252gogyp1SjOgG8SEKKZv=FwfQ@mail.gmail.com

[1]: /messages/by-id/0F44E799048C4849BAE4B91012DB910462E9897A@SHSMSX103.ccr.corp.intel.com
/messages/by-id/0F44E799048C4849BAE4B91012DB910462E9897A@SHSMSX103.ccr.corp.intel.com

-- Melanie

Attachments:

v1-0001-Parallel-FOJ-ROJ-single-worker-scan-chunks.patchapplication/octet-stream; name=v1-0001-Parallel-FOJ-ROJ-single-worker-scan-chunks.patchDownload
From e91ec07029df3422184e316d47e2b1e4b74835cc Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Thu, 17 Sep 2020 14:10:28 -0700
Subject: [PATCH v1] Support Parallel FOJ and ROJ

To support parallel FOJ and ROJ,
- re-enable setting match bit for tuples in the hash table
- a single worker preps for unmatched inner tuple scan in
  HJ_NEED_NEW_OUTER and transitions to HJ_FILL_INNER to avoid deadlock.
        ExecParallelScanHashTableForUnmatched() is no longer safe for
	multiple workers. A single worker will scan each HashMemoryChunk
	in the hash table, freeing it after finishing with it.
---
 src/backend/executor/nodeHash.c         | 116 ++++++++++++++++++++++--
 src/backend/executor/nodeHashjoin.c     |  60 ++++++------
 src/backend/optimizer/path/joinpath.c   |   9 +-
 src/backend/postmaster/pgstat.c         |   3 +
 src/backend/storage/ipc/barrier.c       |  23 ++++-
 src/include/executor/hashjoin.h         |   8 +-
 src/include/executor/nodeHash.h         |   3 +
 src/include/nodes/execnodes.h           |   2 +
 src/include/pgstat.h                    |   1 +
 src/include/storage/barrier.h           |   1 +
 src/test/regress/expected/join_hash.out |  56 +++++++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++++-
 12 files changed, 261 insertions(+), 44 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ea69eeb2a1..e6487cc35b 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2056,6 +2056,52 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
+}
+
+/*
+ * ExecPrepHashTableForUnmatched
+ *		set up for a series of ExecScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor  = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool last = false;
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
+	if (curbatch < 0)
+		return false;
+	last = BarrierDetachOrElect(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak,
+			    batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2132,6 +2178,65 @@ ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 	return false;
 }
 
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	dsa_pointer next;
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
+		{
+			HashJoinTuple hashTuple = (HashJoinTuple) (
+				HASH_CHUNK_DATA(accessor->current_chunk) + accessor->current_chunk_idx
+			);
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD + HJTUPLE_MINTUPLE(hashTuple)->t_len);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple), hjstate->hj_HashTupleSlot,false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't
+			 * do any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
+		}
+
+		next = accessor->current_chunk->next.shared;
+		dsa_free(hashtable->area, accessor->shared_chunk);
+		accessor->shared_chunk = next;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	accessor->shared->chunks = InvalidDsaPointer;
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
 /*
  * ExecHashTableReset
  *
@@ -2971,6 +3076,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		 * up the Barrier.
 		 */
 		BarrierInit(&shared->batch_barrier, 0);
+		pg_atomic_init_u32(&shared->bucket, 0);
 		if (i == 0)
 		{
 			/* Batch 0 doesn't need to be loaded. */
@@ -3131,13 +3237,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3271,6 +3370,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 5532b91a71..23e652d130 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,7 +82,9 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done
  *
  * Batch 0 is a special case, because it starts out in phase
  * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
@@ -238,6 +240,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * from the outer plan node.  If we succeed, we have to stash
 				 * it away for later consumption by ExecHashJoinOuterGetTuple.
 				 */
+				//volatile int mybp = 0; while (mybp == 0) {};
 				if (HJ_FILL_INNER(node))
 				{
 					/* no chance to not build the hash table */
@@ -360,9 +363,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +468,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node),
+					 * but we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +532,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+							   : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -742,6 +744,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
 
 	hjstate->hj_OuterHashKeys = ExecInitExprList(node->hashkeys,
 												 (PlanState *) hjstate);
@@ -1173,15 +1176,17 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase
+					 * so that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
-
 				case PHJ_BATCH_DONE:
+					/* Fall through. */
+
+				case PHJ_BATCH_FILL_INNER_DONE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1360,6 +1365,7 @@ ExecReScanHashJoin(HashJoinState *node)
 	node->hj_CurBucketNo = 0;
 	node->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	node->hj_CurTuple = NULL;
+	node->hj_AllocatedBucketRange = 0;
 
 	node->hj_MatchedOuter = false;
 	node->hj_FirstOuterTupleSlot = NULL;
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index db54a6ba2e..d30ea4d86d 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1852,8 +1852,6 @@ hash_inner_and_outer(PlannerInfo *root,
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1885,12 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * at all because no one process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index e6be2b7836..f6f242d806 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3782,6 +3782,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BATCH_LOAD:
 			event_name = "HashBatchLoad";
 			break;
+		case WAIT_EVENT_HASH_BATCH_PROBE:
+			event_name = "HashBatchProbe";
+			break;
 		case WAIT_EVENT_HASH_BUILD_ALLOCATE:
 			event_name = "HashBuildAllocate";
 			break;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3e200e02cc..5ebd18314f 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -204,6 +204,28 @@ BarrierArriveAndDetach(Barrier *barrier)
 {
 	return BarrierDetachImpl(barrier, true);
 }
+/*
+ * Upon arriving at the barrier, if this worker is not the last worker attached,
+ * detach from the barrier and return false. If this worker is the last worker,
+ * remain attached and advance the phase of the barrier, return true to indicate
+ * you are the last or "elected" worker who is still attached to the barrier.
+ * Another name I considered was BarrierUniqueify or BarrierSoloAssign
+ */
+bool
+BarrierDetachOrElect(Barrier *barrier)
+{
+	SpinLockAcquire(&barrier->mutex);
+	if (barrier->participants > 1)
+	{
+		--barrier->participants;
+		SpinLockRelease(&barrier->mutex);
+		return false;
+	}
+	Assert(barrier->participants == 1);
+	++barrier->phase;
+	SpinLockRelease(&barrier->mutex);
+	return true;
+}
 
 /*
  * Attach to a barrier.  All waiting participants will now wait for this
@@ -221,7 +243,6 @@ BarrierAttach(Barrier *barrier)
 	++barrier->participants;
 	phase = barrier->phase;
 	SpinLockRelease(&barrier->mutex);
-
 	return phase;
 }
 
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index eb5daba36b..8cf36cb6c5 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -160,6 +160,8 @@ typedef struct ParallelHashJoinBatch
 	size_t		old_ntuples;	/* number of tuples before repartitioning */
 	bool		space_exhausted;
 
+	pg_atomic_uint32 bucket;	/* bucket allocator for unmatched inner scan */
+
 	/*
 	 * Variable-sized SharedTuplestore objects follow this struct in memory.
 	 * See the accessor macros below.
@@ -205,6 +207,9 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+	dsa_pointer shared_chunk; /* current chunk in hashtable for scanning for unmatched inner tuples serially */
+	HashMemoryChunk current_chunk;
+	size_t current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -265,7 +270,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_DONE			        4
+#define PHJ_BATCH_FILL_INNER_DONE		5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 2db4e2f672..a642736d54 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a5ab1aed14..a6b2446958 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1921,6 +1921,7 @@ typedef struct MergeJoinState
  *								tuple, or NULL if starting search
  *								(hj_CurXXX variables are undefined if
  *								OuterTupleSlot is empty!)
+ *		hj_AllocatedBucketRange	range allocated for parallel unmatched scan
  *		hj_OuterTupleSlot		tuple slot for outer tuples
  *		hj_HashTupleSlot		tuple slot for inner (hashed) tuples
  *		hj_NullOuterTupleSlot	prepared null tuple for right/full outer joins
@@ -1947,6 +1948,7 @@ typedef struct HashJoinState
 	uint32		hj_CurHashValue;
 	int			hj_CurBucketNo;
 	int			hj_CurSkewBucketNo;
+	int			hj_AllocatedBucketRange;
 	HashJoinTuple hj_CurTuple;
 	TupleTableSlot *hj_OuterTupleSlot;
 	TupleTableSlot *hj_HashTupleSlot;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0dfbac46b4..62d5f1d16b 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -856,6 +856,7 @@ typedef enum
 	WAIT_EVENT_HASH_BATCH_ALLOCATE,
 	WAIT_EVENT_HASH_BATCH_ELECT,
 	WAIT_EVENT_HASH_BATCH_LOAD,
+	WAIT_EVENT_HASH_BATCH_PROBE,
 	WAIT_EVENT_HASH_BUILD_ALLOCATE,
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index d71927cc2f..8b563fa7e0 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -37,6 +37,7 @@ typedef struct Barrier
 extern void BarrierInit(Barrier *barrier, int num_workers);
 extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
 extern bool BarrierArriveAndDetach(Barrier *barrier);
+extern bool BarrierDetachOrElect(Barrier *barrier);
 extern int	BarrierAttach(Barrier *barrier);
 extern bool BarrierDetach(Barrier *barrier);
 extern int	BarrierPhase(Barrier *barrier);
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.20.1

v1-0001-Parallel-FOJ-ROJ-single-worker-scan-buckets.patchapplication/octet-stream; name=v1-0001-Parallel-FOJ-ROJ-single-worker-scan-buckets.patchDownload
From 02c63bd0fcdceb6cdf3026b706fe9aa6e54d3e26 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Thu, 17 Sep 2020 14:10:28 -0700
Subject: [PATCH v1] Support parallel FOJ and ROJ

To support parallel FOJ and ROJ,
- re-enable setting match bit for tuples in the hash table
- a single worker preps for unmatched inner tuple scan in
  HJ_NEED_NEW_OUTER and transitions to HJ_FILL_INNER to avoid deadlock.
	ExecParallelScanHashTableForUnmatched() is still safe for
	multiple workers, though only a single worker will run it
---
 src/backend/executor/nodeHash.c         | 128 ++++++++++++++++++++++--
 src/backend/executor/nodeHashjoin.c     |  55 +++++-----
 src/backend/optimizer/path/joinpath.c   |   9 +-
 src/backend/postmaster/pgstat.c         |   3 +
 src/backend/storage/ipc/barrier.c       |  23 ++++-
 src/include/executor/hashjoin.h         |   5 +-
 src/include/executor/nodeHash.h         |   3 +
 src/include/nodes/execnodes.h           |   2 +
 src/include/pgstat.h                    |   1 +
 src/include/storage/barrier.h           |   1 +
 src/test/regress/expected/join_hash.out |  56 ++++++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++++-
 12 files changed, 267 insertions(+), 42 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ea69eeb2a1..e049c8103d 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2056,6 +2056,45 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
+}
+
+/*
+ * ExecPrepHashTableForUnmatched
+ *		set up for a series of ExecScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int curbatch = hashtable->curbatch;
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool last = false;
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
+	if (curbatch < 0)
+		return false;
+	last = BarrierDetachOrElect(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak,
+			    batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	return last;
 }
 
 /*
@@ -2132,6 +2171,87 @@ ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 	return false;
 }
 
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+
+	for (;;)
+	{
+		/*
+		 * hj_CurTuple is the address of the tuple last returned from the
+		 * current bucket, or NULL if it's time to start scanning a new
+		 * bucket.
+		 */
+		if (hashTuple != NULL)
+			hashTuple = ExecParallelHashNextTuple(hashtable, hashTuple);
+		else if (hjstate->hj_CurBucketNo < hjstate->hj_AllocatedBucketRange)
+			hashTuple = ExecParallelHashFirstTuple(hashtable,
+												   hjstate->hj_CurBucketNo++);
+		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		{
+			/*
+			 * Allocate a few cachelines' worth of buckets and loop around.
+			 * Testing shows that 8 is a good factor.
+			 */
+			int step = (PG_CACHE_LINE_SIZE * 8) / sizeof(dsa_pointer_atomic);
+
+			hjstate->hj_CurBucketNo =
+				pg_atomic_fetch_add_u32(&hashtable->batches[hashtable->curbatch].shared->bucket,
+										step);
+			hjstate->hj_AllocatedBucketRange =
+				Min(hjstate->hj_CurBucketNo + step, hashtable->nbuckets);
+		}
+		else
+			break;				/* finished all buckets */
+
+		while (hashTuple != NULL)
+		{
+			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+			{
+				TupleTableSlot *inntuple;
+
+				/* insert hashtable's tuple into exec slot */
+				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+												 hjstate->hj_HashTupleSlot,
+												 false);	/* do not pfree */
+				econtext->ecxt_innertuple = inntuple;
+
+				/*
+				 * Reset temp memory each time; although this function doesn't
+				 * do any qual eval, the caller will, so let's keep it
+				 * parallel to ExecScanHashBucket.
+				 */
+				ResetExprContext(econtext);
+
+				hjstate->hj_CurTuple = hashTuple;
+				return true;
+			}
+
+			hashTuple = ExecParallelHashNextTuple(hashtable, hashTuple);
+		}
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+
 /*
  * ExecHashTableReset
  *
@@ -2971,6 +3091,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		 * up the Barrier.
 		 */
 		BarrierInit(&shared->batch_barrier, 0);
+		pg_atomic_init_u32(&shared->bucket, 0);
 		if (i == 0)
 		{
 			/* Batch 0 doesn't need to be loaded. */
@@ -3131,13 +3252,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 5532b91a71..d34e87d575 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,6 +82,8 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
+ *  PHJ_BATCH_SCAN_INNER     -- scan unmatched inner tuples
+
  *  PHJ_BATCH_DONE           -- end
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -360,9 +362,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +467,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node),
+					 * but we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +531,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+							   : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -742,6 +743,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	hjstate->hj_CurTuple = NULL;
+	hjstate->hj_AllocatedBucketRange = 0;
 
 	hjstate->hj_OuterHashKeys = ExecInitExprList(node->hashkeys,
 												 (PlanState *) hjstate);
@@ -1173,13 +1175,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase
+					 * so that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN_INNER:
+					/* Fall through. */
 
 				case PHJ_BATCH_DONE:
 
@@ -1360,6 +1364,7 @@ ExecReScanHashJoin(HashJoinState *node)
 	node->hj_CurBucketNo = 0;
 	node->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
 	node->hj_CurTuple = NULL;
+	node->hj_AllocatedBucketRange = 0;
 
 	node->hj_MatchedOuter = false;
 	node->hj_FirstOuterTupleSlot = NULL;
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index db54a6ba2e..d30ea4d86d 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1852,8 +1852,6 @@ hash_inner_and_outer(PlannerInfo *root,
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1885,12 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * at all because no one process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index e6be2b7836..f6f242d806 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3782,6 +3782,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BATCH_LOAD:
 			event_name = "HashBatchLoad";
 			break;
+		case WAIT_EVENT_HASH_BATCH_PROBE:
+			event_name = "HashBatchProbe";
+			break;
 		case WAIT_EVENT_HASH_BUILD_ALLOCATE:
 			event_name = "HashBuildAllocate";
 			break;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3e200e02cc..5ebd18314f 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -204,6 +204,28 @@ BarrierArriveAndDetach(Barrier *barrier)
 {
 	return BarrierDetachImpl(barrier, true);
 }
+/*
+ * Upon arriving at the barrier, if this worker is not the last worker attached,
+ * detach from the barrier and return false. If this worker is the last worker,
+ * remain attached and advance the phase of the barrier, return true to indicate
+ * you are the last or "elected" worker who is still attached to the barrier.
+ * Another name I considered was BarrierUniqueify or BarrierSoloAssign
+ */
+bool
+BarrierDetachOrElect(Barrier *barrier)
+{
+	SpinLockAcquire(&barrier->mutex);
+	if (barrier->participants > 1)
+	{
+		--barrier->participants;
+		SpinLockRelease(&barrier->mutex);
+		return false;
+	}
+	Assert(barrier->participants == 1);
+	++barrier->phase;
+	SpinLockRelease(&barrier->mutex);
+	return true;
+}
 
 /*
  * Attach to a barrier.  All waiting participants will now wait for this
@@ -221,7 +243,6 @@ BarrierAttach(Barrier *barrier)
 	++barrier->participants;
 	phase = barrier->phase;
 	SpinLockRelease(&barrier->mutex);
-
 	return phase;
 }
 
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index eb5daba36b..6299c9ce9f 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -160,6 +160,8 @@ typedef struct ParallelHashJoinBatch
 	size_t		old_ntuples;	/* number of tuples before repartitioning */
 	bool		space_exhausted;
 
+	pg_atomic_uint32 bucket;	/* bucket allocator for unmatched inner scan */
+
 	/*
 	 * Variable-sized SharedTuplestore objects follow this struct in memory.
 	 * See the accessor macros below.
@@ -265,7 +267,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_SCAN_INNER			4
+#define PHJ_BATCH_DONE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 2db4e2f672..a642736d54 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a5ab1aed14..a6b2446958 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1921,6 +1921,7 @@ typedef struct MergeJoinState
  *								tuple, or NULL if starting search
  *								(hj_CurXXX variables are undefined if
  *								OuterTupleSlot is empty!)
+ *		hj_AllocatedBucketRange	range allocated for parallel unmatched scan
  *		hj_OuterTupleSlot		tuple slot for outer tuples
  *		hj_HashTupleSlot		tuple slot for inner (hashed) tuples
  *		hj_NullOuterTupleSlot	prepared null tuple for right/full outer joins
@@ -1947,6 +1948,7 @@ typedef struct HashJoinState
 	uint32		hj_CurHashValue;
 	int			hj_CurBucketNo;
 	int			hj_CurSkewBucketNo;
+	int			hj_AllocatedBucketRange;
 	HashJoinTuple hj_CurTuple;
 	TupleTableSlot *hj_OuterTupleSlot;
 	TupleTableSlot *hj_HashTupleSlot;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0dfbac46b4..62d5f1d16b 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -856,6 +856,7 @@ typedef enum
 	WAIT_EVENT_HASH_BATCH_ALLOCATE,
 	WAIT_EVENT_HASH_BATCH_ELECT,
 	WAIT_EVENT_HASH_BATCH_LOAD,
+	WAIT_EVENT_HASH_BATCH_PROBE,
 	WAIT_EVENT_HASH_BUILD_ALLOCATE,
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index d71927cc2f..8b563fa7e0 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -37,6 +37,7 @@ typedef struct Barrier
 extern void BarrierInit(Barrier *barrier, int num_workers);
 extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
 extern bool BarrierArriveAndDetach(Barrier *barrier);
+extern bool BarrierDetachOrElect(Barrier *barrier);
 extern int	BarrierAttach(Barrier *barrier);
 extern bool BarrierDetach(Barrier *barrier);
 extern int	BarrierPhase(Barrier *barrier);
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.20.1

#3Thomas Munro
thomas.munro@gmail.com
In reply to: Melanie Plageman (#2)
Re: Parallel Full Hash Join

On Tue, Sep 22, 2020 at 8:49 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

On Wed, Sep 11, 2019 at 11:23 PM Thomas Munro <thomas.munro@gmail.com> wrote:

1. You could probably make it so that the PHJ_BATCH_SCAN_INNER phase
in this patch (the scan for unmatched tuples) is executed by only one
process, using the "detach-and-see-if-you-were-last" trick. Melanie
proposed that for an equivalent problem in the looping hash join. I
think it probably works, but it gives up a lot of parallelism and thus
won't scale as nicely as the attached patch.

I have attached a patch which implements this
(v1-0001-Parallel-FOJ-ROJ-single-worker-scan-buckets.patch).

Hi Melanie,

Thanks for working on this! I have a feeling this is going to be much
easier to land than the mighty hash loop patch. And it's good to get
one of our blocking design questions nailed down for both patches.

I took it for a very quick spin and saw simple cases working nicely,
but TPC-DS queries 51 and 97 (which contain full joins) couldn't be
convinced to use it. Hmm.

For starters, in order to support parallel FOJ and ROJ, I re-enabled
setting the match bit for the tuples in the hashtable which
3e4818e9dd5be294d97c disabled. I did so using the code suggested in [1],
reading the match bit to see if it is already set before setting it.

Cool. I'm quite keen to add a "fill_inner" parameter for
ExecHashJoinImpl() and have an N-dimensional lookup table of
ExecHashJoin variants, so that this and much other related branching
can be constant-folded out of existence by the compiler in common
cases, which is why I think this is all fine, but that's for another
day...

Then, workers except for the last worker detach after exhausting the
outer side of a batch, leaving one worker to proceed to HJ_FILL_INNER
and do the scan of the hash table and emit unmatched inner tuples.

+1

Doing better is pretty complicated within our current execution model,
and I think this is a good compromise for now.

Costing for uneven distribution is tricky; depending on your plan
shape, specifically whether there is something else to do afterwards
to pick up the slack, it might or might not affect the total run time
of the query. It seems like there's not much we can do about that.

I have also attached a variant on this patch which I am proposing to
replace it (v1-0001-Parallel-FOJ-ROJ-single-worker-scan-chunks.patch)
which has a new ExecParallelScanHashTableForUnmatched() in which the
single worker doing the unmatched scan scans one HashMemoryChunk at a
time and then frees them as it goes. I thought this might perform better
than the version which uses the buckets because 1) it should do a bit
less pointer chasing and 2) it frees each chunk of the hash table as it
scans it which (maybe) would save a bit of time during
ExecHashTableDetachBatch() when it goes through and frees the hash
table, but, my preliminary tests showed a negligible difference between
this and the version using buckets. I will do a bit more testing,
though.

+1

I agree that it's the better of those two options.

[stuff about deadlocks]

The leader exclusion tactics and the spooling idea don't solve the
execution order deadlock possibility, so, this "all except last detach
and last does unmatched inner scan" seems like the best way to solve
both types of deadlock.

Agreed (at least as long as our threads of query execution are made
out of C call stacks and OS processes that block).

Some other notes on the patch:

Aside from the deadlock problem, there are some minor details to tidy
up (handling of late starters probably not quite right, rescans not
yet considered).

These would not be an issue with only one worker doing the scan but
would have to be handled in a potential new parallel-enabled solution
like I suggested above.

Makes sense. Not sure why I thought anything special was needed for rescans.

There is a fun hard-coded parameter that controls
the parallel step size in terms of cache lines for the unmatched scan;
I found that 8 was a lot faster than 4, but no slower than 128 on my
laptop, so I set it to 8.

I didn't add this cache line optimization to my chunk scanning method. I
could do so. Do you think it is more relevant, less relevant, or the
same if only one worker is doing the unmatched inner scan?

Yeah it's irrelevant for a single process, and even more irrelevant if
we go with your chunk-based version.

More thoughts along those micro-optimistic
lines: instead of match bit in the header, you could tag the pointer
and sometimes avoid having to follow it, and you could prefetch next
non-matching tuple's cacheline by looking a head a bit.

I would be happy to try doing this once we get the rest of the patch
ironed out so that seeing how much of a performance difference it makes
is more straightforward.

Ignore that, I have no idea if the maintenance overhead for such an
every-tuple-in-this-chain-is-matched tag bit would be worth it, it was
just an idle thought. I think your chunk-scan plan seems sensible for
now.

From a quick peek:

+/*
+ * Upon arriving at the barrier, if this worker is not the last
worker attached,
+ * detach from the barrier and return false. If this worker is the last worker,
+ * remain attached and advance the phase of the barrier, return true
to indicate
+ * you are the last or "elected" worker who is still attached to the barrier.
+ * Another name I considered was BarrierUniqueify or BarrierSoloAssign
+ */
+bool
+BarrierDetachOrElect(Barrier *barrier)

I tried to find some existing naming in writing about
barriers/phasers, but nothing is jumping out at me. I think a lot of
this stuff comes from super computing where I guess "make all of the
threads give up except one" isn't a primitive they'd be too excited
about :-)

BarrierArriveAndElectOrDetach()... gah, no.

+ last = BarrierDetachOrElect(&batch->batch_barrier);

I'd be nice to add some assertions after that, in the 'last' path,
that there's only one participant and that the phase is as expected,
just to make it even clearer to the reader, and a comment in the other
path that we are no longer attached.

+    hjstate->hj_AllocatedBucketRange = 0;
...
+    pg_atomic_uint32 bucket;    /* bucket allocator for unmatched inner scan */
...
+                //volatile int mybp = 0; while (mybp == 0)

Some leftover fragments of the bucket-scan version and debugging stuff.

#4Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#3)
1 attachment(s)
Re: Parallel Full Hash Join

On Mon, Sep 21, 2020 at 8:34 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Sep 22, 2020 at 8:49 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

On Wed, Sep 11, 2019 at 11:23 PM Thomas Munro <thomas.munro@gmail.com>

wrote:

I took it for a very quick spin and saw simple cases working nicely,
but TPC-DS queries 51 and 97 (which contain full joins) couldn't be
convinced to use it. Hmm.

Thanks for taking a look, Thomas!

Both query 51 and query 97 have full outer joins of two CTEs, each of
which are aggregate queries.

During planning when constructing the joinrel and choosing paths, in
hash_inner_and_outer(), we don't consider parallel hash parallel hash
join paths because the outerrel and innerrel do not have
partial_pathlists.

This code

if (joinrel->consider_parallel &&
save_jointype != JOIN_UNIQUE_OUTER &&
outerrel->partial_pathlist != NIL &&
bms_is_empty(joinrel->lateral_relids))

gates the code to generate partial paths for hash join.

My understanding of this is that if the inner and outerrel don't have
partial paths, then they can't be executed in parallel, so the join
could not be executed in parallel.

For the two TPC-DS queries, even if they use parallel aggs, the finalize
agg will have to be done by a single worker, so I don't think they could
be joined with a parallel hash join.

I added some logging inside the "if" statement and ran join_hash.sql in
regress to see what nodes were typically in the pathlist and partial
pathlist. All of them had basically just sequential scans as the outer
and inner rel paths. regress examples are definitely meant to be
minimal, so this probably wasn't the best place to look for examples of
more complex rels that can be joined with a parallel hash join.

Some other notes on the patch:

From a quick peek:

+/*
+ * Upon arriving at the barrier, if this worker is not the last
worker attached,
+ * detach from the barrier and return false. If this worker is the last
worker,
+ * remain attached and advance the phase of the barrier, return true
to indicate
+ * you are the last or "elected" worker who is still attached to the
barrier.
+ * Another name I considered was BarrierUniqueify or BarrierSoloAssign
+ */
+bool
+BarrierDetachOrElect(Barrier *barrier)

I tried to find some existing naming in writing about
barriers/phasers, but nothing is jumping out at me. I think a lot of
this stuff comes from super computing where I guess "make all of the
threads give up except one" isn't a primitive they'd be too excited
about :-)

BarrierArriveAndElectOrDetach()... gah, no.

You're right that Arrive should be in there.
So, I went with BarrierArriveAndDetachExceptLast()
It's specific, if not clever.

+ last = BarrierDetachOrElect(&batch->batch_barrier);

I'd be nice to add some assertions after that, in the 'last' path,
that there's only one participant and that the phase is as expected,
just to make it even clearer to the reader, and a comment in the other
path that we are no longer attached.

Assert and comment added to the single worker path.
The other path is just back to HJ_NEED_NEW_BATCH and workers will detach
there as before, so I'm not sure where we could add the comment about
the other workers detaching.

+    hjstate->hj_AllocatedBucketRange = 0;
...
+    pg_atomic_uint32 bucket;    /* bucket allocator for unmatched inner
scan */
...
+                //volatile int mybp = 0; while (mybp == 0)

Some leftover fragments of the bucket-scan version and debugging stuff.

cleaned up (and rebased).

I also changed ExecScanHashTableForUnmatched() to scan HashMemoryChunks
in the hashtable instead of using the buckets to align parallel and
serial hash join code.

Originally, I had that code freeing the chunks of the hashtable after
finishing scanning them, however, I noticed this query from regress
failing:

select * from
(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys)
left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x
left join unnest(v1ys) as u1(u1y) on u1y = v2y;

It is because the hash join gets rescanned and because there is only one
batch, ExecReScanHashJoin reuses the same hashtable.

QUERY PLAN
-------------------------------------------------------------
Nested Loop Left Join
-> Values Scan on "*VALUES*"
-> Hash Right Join
Hash Cond: (u1.u1y = "*VALUES*_1".column2)
Filter: ("*VALUES*_1".column1 = "*VALUES*".column1)
-> Function Scan on unnest u1
-> Hash
-> Values Scan on "*VALUES*_1"

I was freeing the hashtable as I scanned each chunk, which clearly
doesn't work for a single batch hash join which gets rescanned.

I don't see anything specific to parallel hash join in ExecReScanHashJoin(),
so, it seems like the same rules apply to parallel hash join. So, I will
have to remove the logic that frees the hash table after scanning each
chunk from the parallel function as well.

In addition, I still need to go through the patch with a fine tooth comb
(refine the comments and variable names and such) but just wanted to
check that these changes were in line with what you were thinking first.

Regards,
Melanie (Microsoft)

Attachments:

v2-0001-Support-Parallel-FOJ-and-ROJ.patchtext/x-patch; charset=US-ASCII; name=v2-0001-Support-Parallel-FOJ-and-ROJ.patchDownload
From 6d34cbee84b06aa27d6c73426f29ef0d50dadb3a Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Tue, 29 Sep 2020 13:47:57 -0700
Subject: [PATCH v2] Support Parallel FOJ and ROJ

To support parallel FOJ and ROJ,
- re-enable setting match bit for tuples in the hash table
- a single worker preps for unmatched inner tuple scan in
  HJ_NEED_NEW_OUTER and transitions to HJ_FILL_INNER to avoid deadlock.
	ExecParallelScanHashTableForUnmatched() is no longer executed by
	multiple workers. A single worker will scan each HashMemoryChunk
	in the hash table, freeing it after finishing with it.

- To align parallel and serial hash join, change
  ExecScanHashTableForUnmatched() to also scan HashMemoryChunks for the
  unmatched tuple scan instead of using the buckets
---
 src/backend/executor/nodeHash.c         | 195 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  61 ++++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/backend/postmaster/pgstat.c         |   3 +
 src/backend/storage/ipc/barrier.c       |  22 ++-
 src/include/executor/hashjoin.h         |  13 +-
 src/include/executor/nodeHash.h         |   3 +
 src/include/pgstat.h                    |   1 +
 src/include/storage/barrier.h           |   1 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 11 files changed, 302 insertions(+), 90 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ea69eeb2a1..42cb8514d3 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -510,6 +510,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2053,9 +2054,56 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
 	 *----------
 	 */
+    HashJoinTable hashtable = hjstate->hj_HashTable;
+
+    hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecPrepHashTableForUnmatched
+ *		set up for a series of ExecScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor  = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool last = false;
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak,batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2069,63 +2117,118 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
-	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+	HashMemoryChunk next;
+	HashJoinTable   hashtable = hjstate->hj_HashTable;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
-		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple     = (HashJoinTuple) (
+				HASH_CHUNK_DATA(hashtable->current_chunk) +
+					hashtable->current_chunk_idx
+			);
+			MinimalTuple  tuple         = HJTUPLE_MINTUPLE(hashTuple);
+			int           hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+				                      hjstate->hj_HashTupleSlot,
+				                      false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't
+			 * do any qual eval, the caller will, so let's keep it
+			 * parallel to ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk     = next;
+		hashtable->current_chunk_idx = 0;
+
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	dsa_pointer next;
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function.
+	 * Since tuples have already been emitted, it is hazardous for workers
+	 * to wait at the batch_barrier again. Instead, all workers except the last
+	 * will detach and the last will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (
+				HASH_CHUNK_DATA(accessor->current_chunk) + accessor->current_chunk_idx
+			);
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD + HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(
+				HJTUPLE_MINTUPLE(hashTuple),
+				hjstate->hj_HashTupleSlot,false);
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/*
+			 * Reset temp memory each time; although this function doesn't
+			 * do any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		next = accessor->current_chunk->next.shared;
+		dsa_free(hashtable->area, accessor->shared_chunk);
+		accessor->shared_chunk = next;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
+	accessor->shared->chunks = InvalidDsaPointer;
 	/*
 	 * no more unmatched tuples
 	 */
@@ -3131,13 +3234,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3271,6 +3367,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 5532b91a71..7a2b5275bb 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,7 +82,9 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done
  *
  * Batch 0 is a special case, because it starts out in phase
  * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
@@ -99,7 +101,9 @@
  * while attached to a barrier, unless the barrier has reached its final
  * state.  In the slightly special case of the per-batch barrier, we return
  * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE or
+ * PHJ_BATCH_DONE_INNER, depending on whether or not the join requires
+ * a scan for unmatched inner tuples, without waiting.
  *
  *-------------------------------------------------------------------------
  */
@@ -360,9 +364,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +469,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node),
+					 * but we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +533,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+							   : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1173,15 +1176,17 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase
+					 * so that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
-
 				case PHJ_BATCH_DONE:
+					/* Fall through. */
+
+				case PHJ_BATCH_FILL_INNER_DONE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index db54a6ba2e..cbc8c2ad83 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1845,15 +1845,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1881,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one process
+			 * has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index e6be2b7836..f6f242d806 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3782,6 +3782,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BATCH_LOAD:
 			event_name = "HashBatchLoad";
 			break;
+		case WAIT_EVENT_HASH_BATCH_PROBE:
+			event_name = "HashBatchProbe";
+			break;
 		case WAIT_EVENT_HASH_BUILD_ALLOCATE:
 			event_name = "HashBuildAllocate";
 			break;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3e200e02cc..2e7b0687ef 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -204,6 +204,27 @@ BarrierArriveAndDetach(Barrier *barrier)
 {
 	return BarrierDetachImpl(barrier, true);
 }
+/*
+ * Upon arriving at the barrier, if this worker is not the last worker attached,
+ * detach from the barrier and return false. If this worker is the last worker,
+ * remain attached and advance the phase of the barrier, return true to indicate
+ * you are the last or "elected" worker who is still attached to the barrier.
+ */
+bool
+BarrierArriveAndDetachExceptLast(Barrier *barrier)
+{
+	SpinLockAcquire(&barrier->mutex);
+	if (barrier->participants > 1)
+	{
+		--barrier->participants;
+		SpinLockRelease(&barrier->mutex);
+		return false;
+	}
+	Assert(barrier->participants == 1);
+	++barrier->phase;
+	SpinLockRelease(&barrier->mutex);
+	return true;
+}
 
 /*
  * Attach to a barrier.  All waiting participants will now wait for this
@@ -221,7 +242,6 @@ BarrierAttach(Barrier *barrier)
 	++barrier->participants;
 	phase = barrier->phase;
 	SpinLockRelease(&barrier->mutex);
-
 	return phase;
 }
 
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index eb5daba36b..2af7228ef0 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,14 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable
+	 * so it can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -265,7 +273,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_DONE			        4
+#define PHJ_BATCH_FILL_INNER_DONE		5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
@@ -351,6 +360,8 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	size_t current_chunk_idx; /* index of tuple within current chunk for serial unmatched inner scan */
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 2db4e2f672..a642736d54 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0dfbac46b4..62d5f1d16b 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -856,6 +856,7 @@ typedef enum
 	WAIT_EVENT_HASH_BATCH_ALLOCATE,
 	WAIT_EVENT_HASH_BATCH_ELECT,
 	WAIT_EVENT_HASH_BATCH_LOAD,
+	WAIT_EVENT_HASH_BATCH_PROBE,
 	WAIT_EVENT_HASH_BUILD_ALLOCATE,
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index d71927cc2f..e0de24378b 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -37,6 +37,7 @@ typedef struct Barrier
 extern void BarrierInit(Barrier *barrier, int num_workers);
 extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
 extern bool BarrierArriveAndDetach(Barrier *barrier);
+extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier);
 extern int	BarrierAttach(Barrier *barrier);
 extern bool BarrierDetach(Barrier *barrier);
 extern int	BarrierPhase(Barrier *barrier);
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.25.1

#5Melanie Plageman
melanieplageman@gmail.com
In reply to: Melanie Plageman (#4)
1 attachment(s)
Re: Parallel Full Hash Join

I've attached a patch with the corrections I mentioned upthread.
I've gone ahead and run pgindent, though, I can't say that I'm very
happy with the result.

I'm still not quite happy with the name
BarrierArriveAndDetachExceptLast(). It's so literal. As you said, there
probably isn't a nice name for this concept, since it is a function with
the purpose of terminating parallelism.

Regards,
Melanie (Microsoft)

Attachments:

v3-0001-Support-Parallel-FOJ-and-ROJ.patchtext/x-patch; charset=US-ASCII; name=v3-0001-Support-Parallel-FOJ-and-ROJ.patchDownload
From 0b13b62a8aac071393ac65b19dc1ec86daa967f2 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v3] Support Parallel FOJ and ROJ

Previously, parallel full and right outer join were not supported due to
a potential deadlock hazard posed by allowing workers to wait on a
barrier after barrier participants have started emitting tuples. More
details on the deadlock hazard can be found in the thread [1].

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last worker to arrive at the barrier
preps for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.

To align parallel and serial hash join, change
ExecScanHashTableForUnmatched() to also scan HashMemoryChunks for the
unmatched tuple scan instead of accessing tuples through the hash table
buckets.

[1] https://www.postgresql.org/message-id/flat/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 190 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  61 ++++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/backend/postmaster/pgstat.c         |   3 +
 src/backend/storage/ipc/barrier.c       |  21 +++
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/include/pgstat.h                    |   1 +
 src/include/storage/barrier.h           |   1 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 11 files changed, 300 insertions(+), 88 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ea69eeb2a1..36cc752163 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -510,6 +510,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2053,9 +2054,58 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecPrepHashTableForUnmatched
+ *		set up for a series of ExecScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2069,60 +2119,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
-		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3131,13 +3231,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3271,6 +3364,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 5532b91a71..791c97e17d 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,7 +82,9 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done
  *
  * Batch 0 is a special case, because it starts out in phase
  * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
@@ -99,7 +101,9 @@
  * while attached to a barrier, unless the barrier has reached its final
  * state.  In the slightly special case of the per-batch barrier, we return
  * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE or
+ * PHJ_BATCH_DONE_INNER, depending on whether or not the join requires
+ * a scan for unmatched inner tuples, without waiting.
  *
  *-------------------------------------------------------------------------
  */
@@ -360,9 +364,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +469,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +533,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1173,15 +1176,17 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
-
 				case PHJ_BATCH_DONE:
+					/* Fall through. */
+
+				case PHJ_BATCH_FILL_INNER_DONE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 4a35903b29..8f495cc6c2 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1845,15 +1845,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1881,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index f1dca2f25b..1d7af3dd88 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3928,6 +3928,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BATCH_LOAD:
 			event_name = "HashBatchLoad";
 			break;
+		case WAIT_EVENT_HASH_BATCH_PROBE:
+			event_name = "HashBatchProbe";
+			break;
 		case WAIT_EVENT_HASH_BUILD_ALLOCATE:
 			event_name = "HashBuildAllocate";
 			break;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3e200e02cc..de901752c0 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -205,6 +205,27 @@ BarrierArriveAndDetach(Barrier *barrier)
 	return BarrierDetachImpl(barrier, true);
 }
 
+/*
+ * Upon arriving at the barrier, if the caller is not the last worker attached,
+ * detach from the barrier and return false. If this worker is the last worker,
+ * remain attached and advance the phase of the barrier, returning true.
+ */
+bool
+BarrierArriveAndDetachExceptLast(Barrier *barrier)
+{
+	SpinLockAcquire(&barrier->mutex);
+	if (barrier->participants > 1)
+	{
+		--barrier->participants;
+		SpinLockRelease(&barrier->mutex);
+		return false;
+	}
+	Assert(barrier->participants == 1);
+	++barrier->phase;
+	SpinLockRelease(&barrier->mutex);
+	return true;
+}
+
 /*
  * Attach to a barrier.  All waiting participants will now wait for this
  * participant to call BarrierArriveAndWait(), BarrierDetach() or
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index eb5daba36b..24ba311141 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -265,7 +274,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_DONE			        4
+#define PHJ_BATCH_FILL_INNER_DONE		5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
@@ -351,6 +361,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 2db4e2f672..a642736d54 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 257e515bfe..d9a0834e08 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -927,6 +927,7 @@ typedef enum
 	WAIT_EVENT_HASH_BATCH_ALLOCATE,
 	WAIT_EVENT_HASH_BATCH_ELECT,
 	WAIT_EVENT_HASH_BATCH_LOAD,
+	WAIT_EVENT_HASH_BATCH_PROBE,
 	WAIT_EVENT_HASH_BUILD_ALLOCATE,
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index d71927cc2f..e0de24378b 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -37,6 +37,7 @@ typedef struct Barrier
 extern void BarrierInit(Barrier *barrier, int num_workers);
 extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
 extern bool BarrierArriveAndDetach(Barrier *barrier);
+extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier);
 extern int	BarrierAttach(Barrier *barrier);
 extern bool BarrierDetach(Barrier *barrier);
 extern int	BarrierPhase(Barrier *barrier);
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.25.1

#6Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Melanie Plageman (#5)
Re: Parallel Full Hash Join

Hi Melanie,

On Thu, Nov 5, 2020 at 7:34 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I've attached a patch with the corrections I mentioned upthread.
I've gone ahead and run pgindent, though, I can't say that I'm very
happy with the result.

I'm still not quite happy with the name
BarrierArriveAndDetachExceptLast(). It's so literal. As you said, there
probably isn't a nice name for this concept, since it is a function with
the purpose of terminating parallelism.

You sent in your patch, v3-0001-Support-Parallel-FOJ-and-ROJ.patch to
pgsql-hackers on Nov 5, but you did not post it to the next
CommitFest[1]https://commitfest.postgresql.org/31/. If this was intentional, then you need to take no
action. However, if you want your patch to be reviewed as part of the
upcoming CommitFest, then you need to add it yourself before
2021-01-01 AOE[2]https://en.wikipedia.org/wiki/Anywhere_on_Earth. Also, rebasing to the current HEAD may be required
as almost two months passed since when this patch is submitted. Thanks
for your contributions.

Regards,

[1]: https://commitfest.postgresql.org/31/
[2]: https://en.wikipedia.org/wiki/Anywhere_on_Earth

Regards,

--
Masahiko Sawada
EnterpriseDB: https://www.enterprisedb.com/

#7Thomas Munro
thomas.munro@gmail.com
In reply to: Masahiko Sawada (#6)
1 attachment(s)
Re: Parallel Full Hash Join

On Mon, Dec 28, 2020 at 9:49 PM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Nov 5, 2020 at 7:34 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I've attached a patch with the corrections I mentioned upthread.
I've gone ahead and run pgindent, though, I can't say that I'm very
happy with the result.

I'm still not quite happy with the name
BarrierArriveAndDetachExceptLast(). It's so literal. As you said, there
probably isn't a nice name for this concept, since it is a function with
the purpose of terminating parallelism.

You sent in your patch, v3-0001-Support-Parallel-FOJ-and-ROJ.patch to
pgsql-hackers on Nov 5, but you did not post it to the next
CommitFest[1]. If this was intentional, then you need to take no
action. However, if you want your patch to be reviewed as part of the
upcoming CommitFest, then you need to add it yourself before
2021-01-01 AOE[2]. Also, rebasing to the current HEAD may be required
as almost two months passed since when this patch is submitted. Thanks
for your contributions.

Thanks for this reminder Sawada-san. I had some feedback I meant to
post in November but didn't get around to:

+bool
+BarrierArriveAndDetachExceptLast(Barrier *barrier)

I committed this part (7888b099). I've attached a rebase of the rest
of Melanie's v3 patch.

+ WAIT_EVENT_HASH_BATCH_PROBE,

That new wait event isn't needed (we can't and don't wait).

  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done

Would it be better/tidier to keep _DONE as the final phase? That is,
to switch around these two final phases. Or does that make it too
hard to coordinate the detach-and-cleanup logic?

+/*
+ * ExecPrepHashTableForUnmatched
+ *             set up for a series of ExecScanHashTableForUnmatched calls
+ *             return true if this worker is elected to do the
unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)

Comment name doesn't match function name.

Attachments:

v4-0001-Parallel-Hash-Full-Right-Join.patchtext/x-patch; charset=US-ASCII; name=v4-0001-Parallel-Hash-Full-Right-Join.patchDownload
From 9199bfcfa84acbcfeb9a8d3c21962096c7ff645c Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 5 Nov 2020 16:20:24 +1300
Subject: [PATCH v4 1/2] Parallel Hash Full/Right Join.

Previously we allowed PHJ only for inner and left outer joins.
Share the hash table match bits between backends, so we can also also
handle full and right joins.  In order to do that without introducing
any deadlock risks, for now we drop down to a single process for the
unmatched scan at the end of each batch.  Other processes detach and
look for another batch to help with.  If there aren't any more batches,
they'll finish the hash join early, making work distribution suboptimal.
Improving that might require bigger executor changes.

Also switch the unmatched tuple scan to work in memory-chunk order,
rather than bucket order.  This prepares for potential later
improvements that would use chunks as parallel grain, and seems to be a
little cache-friendlier than the bucket-scan scheme scheme in the
meantime.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 190 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  61 ++++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 274 insertions(+), 88 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ea69eeb2a1..36cc752163 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -510,6 +510,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2053,9 +2054,58 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecPrepHashTableForUnmatched
+ *		set up for a series of ExecScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2069,60 +2119,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
-		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3131,13 +3231,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3271,6 +3364,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 5532b91a71..791c97e17d 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,7 +82,9 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done
  *
  * Batch 0 is a special case, because it starts out in phase
  * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
@@ -99,7 +101,9 @@
  * while attached to a barrier, unless the barrier has reached its final
  * state.  In the slightly special case of the per-batch barrier, we return
  * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE or
+ * PHJ_BATCH_DONE_INNER, depending on whether or not the join requires
+ * a scan for unmatched inner tuples, without waiting.
  *
  *-------------------------------------------------------------------------
  */
@@ -360,9 +364,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +469,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +533,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1173,15 +1176,17 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
-
 				case PHJ_BATCH_DONE:
+					/* Fall through. */
+
+				case PHJ_BATCH_FILL_INNER_DONE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 4a35903b29..8f495cc6c2 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1845,15 +1845,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1881,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index eb5daba36b..24ba311141 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -265,7 +274,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_DONE			        4
+#define PHJ_BATCH_FILL_INNER_DONE		5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
@@ -351,6 +361,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 2db4e2f672..a642736d54 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.20.1

#8Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#7)
1 attachment(s)
Re: Parallel Full Hash Join

On Tue, Dec 29, 2020 at 03:28:12PM +1300, Thomas Munro wrote:

I had some feedback I meant to
post in November but didn't get around to:

*  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+
+ *  PHJ_BATCH_DONE           -- queries not requiring inner fill done
+ *  PHJ_BATCH_FILL_INNER_DONE -- inner fill completed, all queries done

Would it be better/tidier to keep _DONE as the final phase? That is,
to switch around these two final phases. Or does that make it too
hard to coordinate the detach-and-cleanup logic?

I updated this to use your suggestion. My rationale for having
PHJ_BATCH_DONE and then PHJ_BATCH_FILL_INNER_DONE was that, for a worker
attaching to the batch for the first time, it might be confusing that it
is in the PHJ_BATCH_FILL_INNER state (not the DONE state) and yet that
worker still just detaches and moves on. It didn't seem intuitive.
Anyway, I think that is all sort of confusing and unnecessary. I changed
it to PHJ_BATCH_FILLING_INNER -- then when a worker who hasn't ever been
attached to this batch before attaches, it will be in the
PHJ_BATCH_FILLING_INNER phase, which it cannot help with and it will
detach and move on.

+/*
+ * ExecPrepHashTableForUnmatched
+ *             set up for a series of ExecScanHashTableForUnmatched calls
+ *             return true if this worker is elected to do the
unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)

Comment name doesn't match function name.

Updated -- and a few other comment updates too.

I just attached the diff.

Attachments:

v4-0002-Update-comments-and-phase-naming.patchtext/x-diff; charset=us-asciiDownload
From 213c36f9e125f52eb6731005d5dcdadccccca73a Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Thu, 11 Feb 2021 16:31:37 -0500
Subject: [PATCH v4 2/2] Update comments and phase naming

---
 src/backend/executor/nodeHash.c     | 19 +++++++++++++------
 src/backend/executor/nodeHashjoin.c |  4 ++--
 src/include/executor/hashjoin.h     |  4 ++--
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index dd8d12203a..6305688efd 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2047,11 +2047,10 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
 	HashJoinTable hashtable = hjstate->hj_HashTable;
@@ -2064,13 +2063,21 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 }
 
 /*
- * ExecPrepHashTableForUnmatched
- *		set up for a series of ExecScanHashTableForUnmatched calls
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
  *		return true if this worker is elected to do the unmatched inner scan
  */
 bool
 ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
 	HashJoinTable hashtable = hjstate->hj_HashTable;
 	int			curbatch = hashtable->curbatch;
 	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 37b49369aa..40c483cd0c 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -1183,10 +1183,10 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FILLING_INNER:
 					/* Fall through. */
 
-				case PHJ_BATCH_FILL_INNER_DONE:
+				case PHJ_BATCH_DONE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 634a212142..66fea4ac58 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -274,8 +274,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE			        4
-#define PHJ_BATCH_FILL_INNER_DONE		5
+#define PHJ_BATCH_FILLING_INNER			4
+#define PHJ_BATCH_DONE		            5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
-- 
2.25.1

#9Thomas Munro
thomas.munro@gmail.com
In reply to: Melanie Plageman (#8)
1 attachment(s)
Re: Parallel Full Hash Join

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

Attachments:

v5-0001-Parallel-Hash-Full-Right-Outer-Join.patchtext/x-patch; charset=US-ASCII; name=v5-0001-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From 87c74af25940b0fc85186b0defe6e21ea2324c28 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v5] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard posed by allowing workers to wait on a
barrier after barrier participants have started emitting tuples. More
details on the deadlock hazard can be found in the referenced
discussion.

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.

To align parallel and serial hash join, change
ExecScanHashTableForUnmatched() to also scan HashMemoryChunks for the
unmatched tuple scan instead of accessing tuples through the hash table
buckets.

Author: Melanie Plageman <melanieplageman@gmail.com>
Author: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 205 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  58 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 283 insertions(+), 91 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index c5f2d1d22b..6305688efd 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -510,6 +510,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2046,16 +2047,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2069,60 +2126,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3131,13 +3238,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3271,6 +3371,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 510bdd39ad..dc526b49bd 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -82,7 +82,8 @@
  *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
  *  PHJ_BATCH_LOADING        -- all load the hash table from disk
  *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_FILLING_INNER  -- full/right outer scan
+ *  PHJ_BATCH_DONE           -- done
  *
  * Batch 0 is a special case, because it starts out in phase
  * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
@@ -99,7 +100,9 @@
  * while attached to a barrier, unless the barrier has reached its final
  * state.  In the slightly special case of the per-batch barrier, we return
  * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE or
+ * PHJ_BATCH_DONE_INNER, depending on whether or not the join requires
+ * a scan for unmatched inner tuples, without waiting.
  *
  *-------------------------------------------------------------------------
  */
@@ -360,9 +363,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -455,25 +468,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -531,7 +532,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1173,13 +1175,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_FILLING_INNER:
+					/* Fall through. */
 
 				case PHJ_BATCH_DONE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 57ce97fd53..dd9e26dcd3 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1845,15 +1845,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1881,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d74034f64f..66fea4ac58 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -265,7 +274,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATING			1
 #define PHJ_BATCH_LOADING				2
 #define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_FILLING_INNER			4
+#define PHJ_BATCH_DONE		            5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECTING		0
@@ -351,6 +361,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 3fbe02e80d..7460dfff64 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.30.1

#10Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#9)
4 attachment(s)
Re: Parallel Full Hash Join

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

Attachments:

phj-phases-with-full-scan.pngimage/png; name=phj-phases-with-full-scan.pngDownload
�PNG


IHDR��?�ezsBIT|d�tEXtSoftwaregnome-screenshot��> IDATx���}\����W���o(�n���&�$�S�L�W�a�����L����w�%�2��t��MXt��Z)��:����_�7��9W��~>�t���Ng��\���.�!�B!
N���B!�H[B!����B!��@��B!�(*��B!D)P�%�B!J��-!�BQ
Tl	!�B�R�bK!�B�[B!����B!��@��B!�(*��B!D)P�%�B!J��-!�BQ
Tl	!�B�R�bK!�B�[B!����B!��@��B!�(*��B!D)P�%�B!J��-!�BQ
Tl	!�B�R�bK!�B�[B!����B!��@��B!�(��\ �B�����Aff&


 
QQQ���
�B���@SS���PWW��������{w����uk�)���0��!!���<x���8\�r������B^^LLL`ffuuuhjjBGG���h��-��� 
!
QVV���
��{B�=z������5������


��&i���B!���B�={������C^^���XYY����������������L���"!!�������@ ��������J�*���bK!��&kll��K����p���#F��@ ��!C��m[�JoVV233�����w����B�O�>EUU�����}{hhh@SS�����������577������			�����3g �0i�$��9���\~YH3A��B!����G����M���������B���!66			���E�n�`ee�+++hkkC]]������D���!�PUU%Y{���deeI������O�>������pvv���&c��}��at��}�>��I�&-[B!���������AAAx�����'����***�s�BBBp��q����...���?��o������"))IR����;;;L�2���044�H$���'�u�V������?���s���.��Q$Tl	!�����B���#<<S�N��+��G<z��BHH�����S�b��)ppp������R�������8�<|||����v��!666l�����l�2|���h����s���V\B!DB,c��-���7�������={��u�����O��G���c��Ux��v�����������q��q�������7o���96o��A�!&&���o�����{#**J.����B!p��E0�FLLv�����j��9�{�Fee%����	&p������-��k���/� !!fffX�n����u��a���;v,���8�Kd��-!������b��%�����9sp��%�x<�]�C����>���KKK������N�<���(��y=z���m�0u�T��{�z�B���q�����5��BH���///�o�������3>�e��a������1������CCC;v����-._�///>;w�������%�BZ���H8���8�<`��Q�������q��I�,�0l�0��y^^^���/`gg��7o���DJJ
�1��Q�%�BZ���Wc��8|�0���[[[XYY���;3f��Y����d��������pvvFEE"##��Ga���8s��1�Q�%�BZ�����?aaa�x�"���k�b��)����m�6�\�9���+bcc1j�(���"""K�.���G1c�������DJZs�B!�Q[[�i����?�DRR��k�1c�������077�:���j�
���ptt���/����f��;wc��AYY>��s�c�wD��BiD"��}0����z���������-�&#G�DRR���������w����pwwGyy9��_�uD�h)!������555�={eee:t(���p���Sj�333�������///��� ..��-[��G�[B!D�1�0�| ""EEEprr���'������[��[===�?B�c�����!����q�F������B!J����x�"TUU1l�0L�:���\Gk���0v�Xt��HNN��Q�p��!�5��x�
Q�%�B���#G�t�R$%%AWW�������O?��u�f���|>��3g0m�4\�r<��x�
P�%�B�Pvv6���H888`��1h��=�=�V�Zq��y��1�
___���a��u8z�(������g���-!��dD"0y�d���a������G\\\�;Q�M���`���8t����0j�(�x<r�4[B!D�|����������q��y��� 99��u�:Z��������h��5������@L�8��h�	��B!J$!!S�L����Q__�`��]7n������FGG#66��MCzz:��F�[B!DI������X�|9>�����b����y3��J}}=����{_}�|||��C�����h�_P�%�B���
���D8p�~�-n����m�rM�dee�����]���6lllp��)888p��*��B����G��}����n���������+����+p��-DEE!00{��Arrr����"�bK!�(�������[�l�����S���qK�	�B���`����������x�b��5��h�5��B!
.;;������AQQ\\\������;sM�EFF��O?Eff&��=�/��iiit-�fJ���By7�6m������S'|��7X�h�Z)7nLLLOOO�m�\�"�A{l	!�����������D���GNN:v��u4�q��),Y����8r����[���@U��67��B!
l��-������)6n���s�R���1c�@KK����:u*���q���c�W�=��B��������1�������^�z!33���\GS:������q������������r��
��%�B��3g`dd�~���������R+#'NDyy9���0}�t�;wO�<�:�*��B��
���3�������6�SUU�����N�:a���8|�0�����RB!D����k���������1i�$����e�d(--
NNN(**�����m������\�"A{l	!�t��1899�s��		��i�������
���p��i�7w��A^^���_P�%�BPll,F�	��;ooo�#�^^^���_��}{6111\G"A��BQ@���HOOG}}=����u�������>����xn�P�%�BLzz:D"������X���������uuu����@ �=��}B!
&..NRf���������b������������Emm-233��E���-!��`�����������@ @\\TUU���@WFhF��B!
&##={���PSSkkk�#q����| �����p��m@��=i�m3����By3w�����5233aee%���W�^E`` Z�n
l���;w���MU\\,�Ko�x<��w�����x8}��\�%����B!
���"�]�vEFFx<���<|�0�|>�,Y�9s�`������/d>�?�����%K���c�����h��b|���8v��L�������6rss������!�y���bK!�(���LXZZ�U�V����y������y�������K�.���/\\\d:��ill��s���o_DEE���FFF������6o����:������x<���@,�l.�t��BQ yyy077���`���2�/%%������������[2��)��������'O"  ����H$���'f���9s�@CCCf�[ZZ";;h��
<x�n���l>�4Tl	!�RQQmmm@YY���d:_qq1�|��������uuuX�j>|�5k�`���PWW���zzzx��)@KKUUU2��4
-E �BHee%455UUU���4b��v������{�v�Z��7%%%033��U�PRR"��555QYY���	�h�-!��@���$���Zr����.\���W��_G�v�<[p���������}��b18555x{{������
q��qddd@MM
vvv�:u*Z�j���M����~�����q�F,]����(--��={���___���`��-2��hjj��?�����m�@{l	!���2+�b[WW���lx��7;;���x��)rrr�e��_����X�t)�����������=
{{{t����m��_�'N���
eeeo��{�����c��ePQQ������C��������M�6��k�����-!��@D"�d��_�.mX�d	<==���X�d	�,Y;;;�^�,l���7o��!C`ii	333�8��]��)S�|�rL�<����}��!==6lx�m�gk[�{��1=z$�w��m���&�/�_�o�555/��p��-!��@�^����9���Tkjj�S�Nh��RRR�s�N�6���G�6m��G���:t�{����;w���������b��]�|z�H(JNP
�������&�Gkl	!���C���l|GG�W>^RR�7n�g��`�A(��qTWW������M����������all,�'�/�$����-!��@444�����������+�}�6�g%��o�y�6~~~����\�)�6�Z�L�[B!D��u/ms)������6�����q���M�m*++%��b�|�[B!D�hkkKn���'�k��+�


�������������m�<y]]]@yyy�����Q�%�B���9rrr<��kVV��^OUU��/GYYN�:��m�M��������Aff&���PTT���F�g�-*��B���x����X,��Cff�L������^������~���+�����+W�4FXXz��!Y��&�r-++K�����z�r"_*�1�uB!�4���������|����s����x��f�����,TTT@MM
�z����3��???��s���������1e���;����b16m����8;;���������'V�\	����+���055�P(��={�#G�p���-!��p���{{{I�R�=�999
������f~�m�)11Q��b��ePWW������E@K�ITT�]��b�'����={"--
�������\VKt��}��mRQ}�m��������? --
���'"�Q�}�.]z��}-m~B!�pttDbb"���#..��D-Kll,�|>�b1._���C�r���wp���=?!�n��|$&&���������b\�p�W�^��������E����[:y�$�_��b�'�����#99|>�����\�j�]�]]]���#66���H�/��c�������D"���c���������LMM����C���o�\�zU�����/�/�1���O���s������><<<�����v�=Btt4JJJPRR��>�b�������a``���BQN�qqqX�r%���q��U� ������ ..~�!���_���@XX�-[����c���(++�g�}��xv?


�;���"dgg#;;���/�9}�t��u��=v��
L�4	~�!%�UWW#''[�l����QXX��K�b��X�|9|||�j~B!����U�$m��I8t���Z���0L�4	HJJ�=��
#�1�������{���K���bIII/<��S�N�v���L�������CBB���<w��Y��������>}���������B�WUU���d999����LOO��D"�c)�+W�0CCCV__������������y��)����{���>���==�7�K�.����KgK:;;x������k���D�N���];���`���o<?!�����OOO����w�����+�T,c!!!�>}:Z�n�����T�|P���n��a��!������kW��3{��AAA���aii��c�����?���?����DJJ
���@II�k?��IB�7���c>>>�:�����Cxx8|||������dL�8��X�o�������������"���s��E�=�����7h���E`` ���0m�4DFF���������k.��&��|���B$!))	>>>8�<����u,�sss������455��E����_t��	@YY�����7����7nl�R���tTTTH����C�����o����q��I|����4i����6wY����B����*f���~��:u���3�y�f�c)���l��	~~~������;1g��c�W�b�?���X�r%�g�[]]]�j�*������G���1>�����?�����#$$������~����8����O!D�-Y�QQQ����������|�c)���CMM


���	�|>���+P�����:����T:���0a����"D"�����rhkkK�������[������MKK���O�FYY��m���B����>f���M�6�k���:u*�n��u,��C@@V�^
�����`���\�"�A��/����������������cC����*.]�$y,??����<b��o�~�s���0h� <x��������=�����)�Bi�/_������a�����w/233������������'#44x�����E^�����?�!���w����7������b���`��
������K���"���������u+?~���pL�4	666�m��������[����iii���31b�����8s�\]]��m[��9g��A�6m�����g����vvv/�m���BZ


 &&�f�BUU���0c���)���R�?���C�.]����������fL�����J���O�>E�N�PQQ���hhh�G�h���k?����������+�)))Avv6���amm
555�P(�X,~��M��B��{��	����A��W�^������T�`��y
�8x� ��[���h$$$����4/Tl	!�%��O?a����q���9��"==\GS8W�^���;RSSQ__�~�����K�����bK!�(���F8::����~�)&N���m����C\GS(UUU��������`��������7��F�[B!D�\�~#G�Drr2ttt`kk�5k�`��Y\GS��O�H$BDD�9�/�����PWW�:�Tl	!�%�z�j�;w/^��[�0b�$&&�_�~\Gk�v���
6����(++���=�9777���&�bK!�(�����������u+6o���� \�t��w�n��>����(0C����c�f����&�bK!�(���b���b�������3PXX���(�k���x���{�����o���g�����q��mDGG��m�	7��B!J���~���7`eet��������(..���C1{�l���������/q��-q��������#>>���BZ��#Gb��upww���������,x�V�-UEEF�
www����������Oq��)*�
���]�v
���\� ���|��'���1j�(TWW�����t�f�����z��q���'pww���
q��eL�>���8p ���[�bK!�(�u��a���3f��m���D��{'NDuu5��8���GGG8���HOO����m�www����D��Bi�n�
sss��|��bDGG������(++�:�\��y���?~<����@��k������x�P�%�BZ�V�Z!,,���prrBqq1"##aii	[[[$%%qQ.���!�~�z����1b6n���?���x���:!�B�CEE[�l���!q��Y���!!!5jV�\����CEE���RWSS�%K� **
�N����Cq��A,Z�aaa=z4��P�%�BZ�/��������������;;;L�2W�^�oi IDAT�O?���;rSjn�������G��u�����v�Z���O8w�
�uD"%��Bi�����s��������9s`nn���$��������~@CC�1��P(��+���1o�<?~:t(bccq��u*�J��-!��B
4��]���1h� ���c��=8q�����A����+\�|+'O�D��=������oc��%8v����0d�DGG�K�.\�$RF��Bi�p��I������_}����p��
L�>����:u*RRR����c8~�8
�e��a������L�8.Dxx8~�����q���[B!��SQQ�_|�7n������Bdd$�-[���������#F�h�WOhll���'aoo��K�b���s�\]]�m�6���HOO��#��Kd��-!�B��w��3g�c�|��gx�������5k� 77...;v,z���M�6������������%����l�2��{.��'��_?���������k���9�Kd��-!�B^0v�X���b��A5j�
����c��U���?�i�&$''���8x� �����-55[�l���1d����b��]HII���~��W���k����U�p��U����%��
c�q��3f�M�����s�Bi���*������`mm��?�h��?~���0?~�.]����|>���SSS�j�������EVV�\����X���A,���c��)x�����];<z�aaa��m����j�*L�0�������b+GTl	!�(������AAA�{�.&O�899AEE"��/_Fll,���q��������<������&444$���QQQ�P���*#33YYY�������@>���}�BUU"�'N�@HHbbb����y������S�L���b+GTl	!�(������#$$b�nnn����d���bddd ++���x��	���PUU�P���JhiiA[[������@��aee+++�x<hjjJ�KMMEll�����	|}}1s�Lr�� �[9�bK!D�466�������A\\.]�333899���������fffh���7;�����������;w����X�1=z����#����Q�%����/G�r�
���������,TUU���zzz�=�PWW�P(DYY�d)BYY
abb�+++������	}���u��5��!�B�?h���|>�|��?~�(//�,C����H$B������MMM���C[[��w���:G��(2*��B���;�c��\� -��'�B���D":t��D�P�%�B���^�3f�@tt4�Q��bK!��:|�0:mmm�������\G"J���EEE��-�\����49&"�B���K�b���h���������u4����P||<�������������|||����Q:B!D~���l��				��x�>���o�����h�"���q��(2�*�`���3f���<[,���KKK��sm���8%!�"{�Z�����1y�d�k������yzzb���8~�8����A�c���������*
��;w�7/!��+==������h)�������B�6m���?R�%�B�2Z� '666��w/�����~��B!�i�a����7�!�B�-E �B!J�N����dffJ������������P(�P(���B]]������D�n�`ee�+++�m���g�r���������0??_��UUU����`�I^?


���@GG<<���000����h���DVV233QYY)y��B!jkk��ukhjjB[[[��haakkkXYY����Z�����X��0##�=Byy��giEE@KKK�����###�kheeMMM��I�%�������dff"77�����������������:������	--�~'���p�T��b�����q��U���!>>�n�Bee��#��������$?x��o/�p.//G^^��pQQLMM���>��@�������E\\���p��%������P����TR|������������p���|�MMvv6444��_?��|��|<jjj?[�TUU�. ..			HMM�k���$�8���M�6hllDyy��myy9������tdee���
VVV6l�|>\\\��cG���rjllDJJ��{����x��LMM%o


_�)��������eee(**BFF���������;c���������7��+#����������{�.���$������{PCC���PUUE]]�B!���$�}�;1++������7\\\���1t�P���s�tI3E��
<}�G���c�p��Et��IR>���ann��'�UVV"##C��:11���pss���TUi��jllD||<����'O�`��a6l�������Ns��b����]���/**�������S�BWWWJ��e������q��\�~�z��|/���]�v}�9?~�;w� !!����z�*���0j�(��1}����3i�D"�?�_~����PSS���C�����;��D����������x����)S0f�:B������s�����{<x0\\\��W/�������1�����?�@ll,������	{{{�;��M�=��Tl��X,FTT���q��i8::���nnn055������8{�,<���ZL�>����������"##!!!8x� Z�j�3f`��������U*���������=z4|}}1z�h���D������@pp0�]�OOOL�8���_�M!
����������	|}}1m�4�|~e�����_~�<���9r�\~�1�����s��!44yyy�:u*|||��� ���Eaa!BCC������c���������,=~���������S����___L�0�����W���d�7of����W�^,  �p�����]�x���7����2ggg�i���������3mmm6g�����9�TXX����{��Ofhh�6m��***8���������O?e��������������s�����;v��?�u���y{{���N35guuul�������u���������t�c���o�����.]����{��2�X�u�f���l��I�C�l������������Leeel�������iii�/���q��p���������k�2}}}�������J555��d���l�����_e


\�j��������Y��]��m��P(�:�+]�x��=���������=y���H�FNN��������={6����:�+��+W2mmm�����\��u�f����m������1;;;v���f�sJ,���p��o_��{w�{�nV[[�u�f���g������TII	��^)55����0


��'�����s�p����������736~�xv��5�#5I]]��o���b���c.\�:�._���,--��={��Srr2�0a���b�6m�|/�JKK�����&[�h����:R�����u��1}}}��������u$N���2ccc�:�����N�8���u��"""������,6j�(fhh����_������!�E��1���������������V�b1��c���c�f�b�=�:�\����9s�0===�}�v�=�x��M����lllX\\�q���������u���y{{���B�#����
��g�1---��7�0�H�u$�JOOg|>������={��8o���c�����5���{��8rU]]����k����V�Z�l�x������q��1ccc�u"'-�������3g2}}}�k��fy��MK���?��u�

b����=|���8����������3f4��~����������c���\�����oK�S||<�qd�����\��iii1VSS�u�w&
_xN���\G���~��u�����������H��S����suue999\�!2�b�mRR333c��MS���.\`���l���J{����y{{3�,%%%����u�������\�����������]�0KG���^h]]]�����G�MNN8p sqqa���\�����t�����������#���l��L__�:t��8RW]]�������.���_��Cd�����F�����iii�����\���������]�|��8R����lll��q�Xii)�qd*88�ikk�5k�(�Q��jjj����������
��>2dsqqQ�%�s��1�������K�-��=+~k��a;vd'O��:�T0'''foo��{4������1���a���\�!2���mee%���d={�d�o��:�����OL[[������(R�o�>������"7iii�O�>l��1
s�?���a�z�bc��a�?�:�\�D"�h�"fdd�E^,���3###�Y>��O�f;vd+V�������:v��>���s�������0`����o�ZL�}��14h?~<����:����q�3����o���)�U+�����M�2�������b�����7o���;3�(o*<<�������H���5�H�&N�����[�5C

X�~���3�>|�����c��qE���+X��]YZZ�q���b[XX�����f���"��������c�f�R��Ccc#�������y����<466�e��1sss�<S;>>������;wr�SqqqLOO������(o�����9�	�]�����l�����U!��l���������D��p*00������/r�H�����4fbb������w��=z��&M��0{�����i�X���[���WY�n����B������LGG�=z��(���7�����q#�Q����G����yyy)��~o�����?�
<X�n������t�������C�1��<�J]l������	��e�Q����J�����O����~cc#�5kspp`O�>�:N��}�v��sg�8�#::�������X��4+�������m����(�����
8���7O�Nb|Wb��}�����Q!����w�1333�+���={����(����Ni�mII	���'[�z5�Q����rfkk�>��c��������^�z)��yZ�~=���h�{�������G{j_#55�����p��jkk���;7n�R_��m��b6a�6f��f��+$$�u��Ii�O+m���LOO���y��(�(e�
�����}��G\Gi�������%�:�+�������Dan���O?���������q�%������������(�ZRR���m���mhh`S�La|>���E�MTWW�a��5�#a�N�b�������\Gi�v������Ynn.�Q�[R�b����<<<��	h�Bdee�N�:�#G�p���c;vd���\Gi�����G7�C�O�>e��wg�6m�:�B8y�$���mvgh/_�����)�	R�VZZ�z�����]�u���u��������sE!�^��������J�����t�v������F!�:5���LGG������c���s\GQ555����Y�������L��u��q�F��w�f�����3L__��c����l����lJdee%���nQ��~W���l��������(�-(U��z�*���b�n��:�����g}����N,uuu����}��W��PDYYYLOO�Y\�'00�����E_�m<?�4w�\�������cG���.W~��fhh�<x�u�������,�G4geee���������(�
)M���	�MCC1b[�p!�9�.]������	�Yxx8311��n^�����a7n��,�"{��	����,C}}=srrb_|�g�����tI����Y�n�����t���Y��TcJ��>@CC<�u����C������pss���			�4in���.]��}~e1{�l��� ,,L�s�������|�	>��c���,.\�OOO����s��r�?  ����p�����>�2�D2d>��C,Z�H������_�~����0h� ���,���{�������h���qH(E��x�"�����tt����8
m������oq��m�m�Vn���b���a��E�3g���UFeee�����C����*��p��1\�|���r�[���?���

���������/��������l�]���#G"55���r�{��q���;�����u^e���{{{|������O��C�@����B�p�B��;��8
�1�@�#F���On�n��	G�ERR")��
JAA���C�HJ��A	�@ ���T��k��y���FHH��������Y����mmm������AIKK��
y3
_l���;DDDP!����T8::���[077��|�Q\\lmme>_K��
���#�r�J��9~�x���c��-r��%

B@@RRR���
������g��r{�RSS���{c����2e���k)>��#�D"s���.��������B$�}�>|(�����������m�d>WKr��:���2_����///dffBKKK�s�$�1899���K��4`cc��k����K�s�4{��������������hDGG�t�����'��x��������C��B�5k� 55\GQ:O�<����]�+++��s��=������r_��x{{���6l��<#F������l�2��WYY��G����'x��	<==1x�`���hy���1k�,����M�62�'<<�����;w�r��^�������={b���3f����D077GDD�*�yZ�u�����[���_��B����
���cV�X�u�������g������<�}�>��*�2�z�j���eee2����k�y�&>��#��������2���b��������������
��u��!P����;|��WR[�E���k��>��s�_�^�����={��R+#K�,A||<n���u�O��1���i=z4�1���������:TTT�455���2������_������2l���2�Mq�������Bf�w����>SWW��u��bbbd6���)��������+V�i��q����c[__��[�������s���6m�n�*���n���'���L&��gV�Z�~�"�H�cgdd !!Af����%����<���>455e��������+��uk��M��3jjj���� ��CCCadd$�K��4K�.���'����u�
Yl��9}}}899qE�-\�!!!������b����t9������9N�8!�����///���J}l��TTT0�|���_�c��{)))�>}���&/�9s&.]�����K}��� ,X�@���u��	�����#4c
YlCBB0s�L�c��{����	����:�o��---���Ku\�j>>>R��fcc#:��K^m����p�
�:npp0&O��:Hu\�2---�;V�w�����70a���K^���S����+5�w����2�={?���QZ�������R����������K���P*c����m��ppp��xMq��y\�x����������c8}�4��;���Z��������Y����H���r�9����������;��]]]�=aaa�����2&c���

��xM��_C�����?�\���>p���MMM��I^O ����/_���#�q��q���������5��-��X���YII�T�+//g,??_*���;v,����6���[�v���{�������W����"v��9��C�j��W~���7[�~=���a�1v��%fll�f���^�v���l�������1��X,f���LMM�%%%I%��DFF�^�zIm���8fjj���D��5|Q}}=322b��]���<����oR����������s�����#F��� �c�8�����He���p6l�0��E�.44�
>\*c��b����233�2��</!vvv����/|�����o�������xff&�z�����!��U IDAT!!�<V^^�������_��������M�HSmm-���f���Ro�����/���X�C���.\�V�\)��RRRX�N��X,��x�in���

Ycc#�Q��(����:\�t	nnn\Giq\]]'��bcc��]���!))	����<Vrr2���dz���266��������555���~��.]��o��/]������C��=}������{�Kszxx@OO���HS�6m������X��'��Ez
������|�j�J*������?����u�7
Ul�����K���p��R�Ec\\�\��N^��S'XZZ���K�<�������������TWW���������?���?xv��������������u��!C���_�k���3g������x{{������H���J)z�����+�5���?��y�<V\\�|�R�7������$��P�����3p�@<}����{�q<x���B4HJ���R)E��^���y���+�L���E`` ���0m�4DFF�����;P�����������"���s��E�=��������4�4	�����<���<x0��������k���}��Abb�;�������D�Q�i��$��P�6>>��-GZ�n-�C�111:th��h{K!��5��������l�>|[[[|����������������([�J���hE($��f�a[��E����
��}�>c�L�Jv)Y[)�iW����G��������{��|<<�1������=�s��s>�f\�|���=zt�������c������7ob��
���#6o��}��I8��u��DT�G���PP��! �����0(**V�*��W���>��u(�Wd*�
c��r���aaau*#,,���r�����=���8::������ad�3g�������[�z����^�G�	�]RVVF����r�J<����8��Dc�999���������3�����s�|�>}Z�2�o"����������;�Ca�"3�mRR���+��P�rssq��1l��+V����w�I����U�2"##all,�����b���b)�u��PPP@|||����syyy���Wh{ig�c�+W� ))	�O�.�0)((������	����D�]411QD���!���FFF����:�+2��FDD���HjF~#==�O��������+�C;cccDDD���.����H�MJRR�X[

�t!����XB���-�����INN���{w�x<�x�Bh���G��[7|��@����[���w��m[������q���9q��w199999i(`��|���HLL��2��r����%�RFf[i����`��E"]=�&�^����`��idd��?"''�V�"..NbSD}���oR����`����Z�j]]]%�^7m��.��>�:]�%�]�����A��f�hhh��?�������\�~�_�


,\�}��$G���a�0b�xyy���C�������m��!..�z����%�4i���
����������������O�s<�P����HB^^|�O�sX�f���]�v����u���d��[�#3K�FEEq�U��AP���G���%Zg�-��M����������y������F������������>I����v���;��G��U�Vh��bcc������(�����8::c��Y<������k�*�?p��
��������HMMELL1y�d(((RRR���������B��w:::���BDD�������&M��$q066Ftt4�rrr5>^�Sv�V�]��|��������brr2n�����T���b�����x8v����
---������+HKKCZZ����#((H�o��)���rrr������4���������������qc�,\&&&�:�+2�b���*�5��???N�����C�kDGGG��?%%��sX��W7)&&&���e����O�>���#1n�8��c��Y}��C��q#|||*�/
��:�����GXXX"�d�TUUU%���(���������"i��eK���U��FTT&N�X���J����...���+w����AD.@!nyyyx��
�o�����#!!�-���5�.]
777%�����������'�<y"(#;;�����q#��['�bRz�����f�DDD�������6m���1t�P�������������1�Af���l(++s�T�|����A����������VWW���;�������a���0l�0��;���x��)�L�����CIII�uUv����V�B~~~�����ES3���h��Y��Q__AAA�$���t�����S'�^���}\�C}}}�Z�
�g�xyy���=z����!���������������aff�5k�`���B�����|�rAW���7c��i�4iZ�j�������o������F�P�9d$Of�"H��4!!>>>������lll0v��^�I9����p��������6m�`������������S��i�����c���%��PU_��~�
�z�������[�},!*����������]����HMM���>f���E�AKKK$�UuG�����������Y�&�?�L�����U�2��4i��G�������055�����YK�?U}W�\	GGGl��B�����Y�fJ�Ki���������ki�V��U�V�.|��-�������V��Kl�k�-����aggmmm�������t�������!�r���`cc�7n`��%�����������>|�%%%�*3�>}BLLbbb��� ��U}���k���/�������'��������y��a��X�|9<x �:J�������X�x1�������W9mV~~>N�:�E����
e���~�:������g���!==�6m�_��'NnfD�:�����a������l������c7(R���������prr*�����U�C%%%\�rG����K�V\��sXU�J�F�O7�\��*,��>2�b���#�/qpp0\\\����
�������#���#6n�///�����ggg�������B�<|��9s&����/_����#G��7�|#�O�r����s��_�^��������?����������CQ/�9a����a��mh��<x���Gc���8x�`�.�_{��f���E�a������G`` ���~�	S�N-sLXX������c���h��5���1u�TL�23g�:)))PQQP��Rbb"�O�>�����J~,3331r��J_'''���������033C^^�|���ae*������wWy���C2k����%KH�z�TNYYo�������cG�<y���D�-��jkk��l.�?����


PTT$�����$����e&��Y�f�I�&�1c���-Z`�����o�n�Ze�Q�r�,Y���4�Z�J�����5jz��-�7'<m��A�.]*}��;w�#F�5n����u���O���T0����������`ee��s������8����v���I�����BYYYh������*MjK��zMQj��x���+������899�M�6 �BS\\,������x<XYYU�����q��i�l��z�l�����\QQTTT�l�x��5>|��#G
���zZW�2����x<���5��/�d��III����VWjj*BCCajj
"Bnn����m�"//����Nl^�r._�e������t�RQ������]�+c���o�}�6>|(4����H�ai���%z�$��Hlg��
�W�����7�����������;W��i���@UU��s�Z�
�f�lo��9��������,L���l899������D777���!,,L��I�S�j999h��u����W�b��e�t��e�xe����!�J�D���S72��J�K\��Mvv66l�P�kV�X!�Q�r�����thjjVY�4�������n���w��I����Dz���3��bcc�v��b��������k��>����A`` ���'hy���J�����u�:�^���ann�`*����R�I�����bd�V�y\�v-��{�7n��#��L�v�:�����<y2|||��G�}������@�������VP�2�����~�tt���66o�,�r��� ''����ZO��\��i#����/����������mq����?�����7o;;;A��xLVe����7$$�|�����Tu���++�r�Z@�7(L�T63%%{����W��q���$�U��������o��U��j��2I- =7'�GU
�555E��M+����(**�2��J����a������sI$����PRRB\\����o->P�r�����S'|����C~~>�|~�u�={���(T6�����?�����WVV��ibb"����i�&l���/_���'F�-�:�3�����VEEE�fE�T5��������WQQaI����QTTT�y�����sg��0�����NU����~(w���2rss��m�'O�`�����o444�|�r0,��ZZZ������<<<p��1,_�O�>���+`���ptt��W��j�����V��Lb��m[��^�u4j�K�.EFF|}}�}�����\e���,Z�@IrZ��s�
�Y�c�������L�J<����{�����ONN?��S����CQ%{s��Axx8���agg'���A1���YXX�Y�f���S��)��(�KQT7+�����
�!|��7��?��M��D1{��=���+����e�JW�����ZU���3gV��HUUJJJ����������-�_���?"--
����q��O�^�1c��ALL&N�SSS�]������	��/_�������v���������?����������q��
$%%!--
���C`` gO���{��m�rR7S>�Il���}u-_����X�|y�����a`` ���4a�wkrM��={6�
�
6����B��y�&����Z^z���F������m���k�L���ONNN��*��m[����l���� ����o��B�_�~
����\�R����&//����#>>���e���|\�z��u�Q��I������q��766FDD�#����N�:!&&Flu�����:�CI\O�����hhh(���8����s������`�c===XYY�]�v27�`]�!#z2��V�?�����q��-���/pvv���#���SSSl�����G���������v���7n`���077�v9@IK���v�����c���044��7o����m��	�hbb�;v�ZLOO��	�>*322���INN����n���q���x�B�:=z��u�;���*H�+��l����q��m��3��]����>�����M�2{�l���a��
2d:w�,�W���$�")���J�


p��������'000K=���?�FFFHHH���Pk�������zj#�������:�������02�&"""���d�'G��	����PUUEVV��/�$�y����077��<u5)����;w�4Y���@DD

E��je:???�?��e���������u�'99��MCXX,X555��wS�Na��������1c���"�)�233�������^�>sss%�h7l����/������������#XJ�k���o�^�f������a�������O�>�zV�7n���!!!"��D@@������?
Zta��M����`���h��=|||`ii)��$�����w��b5uu��}L�6
����.c��uHNN��={DS���8t���<��d&�J�k���j�c$�?���4iR��]��Y���4���o"�+55111PTT����`����\�x<��=&"�y�999077��J3��Y���p����N#����aff���?�I�9��W/,[��N-E�
��)Swd�����Y#s���#Gp��%\�x��e�;w��[�DS]���PVVFBB�D�����>�@I���w�rF�u���r���	q�C---���B��������v���������:uB�.]8�����;����SzzzPSSCXX���bj"//������{�������/���'\�Q+�����������������G���}{��J��c�����70o�<�Cip233&X������Tv1�@@@���W�r���������� ��������������T0@�����___���!55...055E@@���������}��*����JHH���"""����;V�R�����7o
b^�x1x<�;���������{044�s�~��a���"�����\\�x������G���1|�p�Yrrrp�����!--
����s��� ��)S���������S��G�?������={
�"��1  ������tuu��s���NNN\����L�����R�>vCq��mXZZV�.}u�h�666�}���"c���(�q�wQ��|>��}������ShU���"���b���X�f
"""������xL�6
�������V������������6v��
OOO\�t	����Y6������l�����GBB-Zkkk,]�nnn"�����������w"���k�=B���Q\\��k�b������#��#G�^Wz~~��wxzz
��fgg#::7n��u��A���PRR|�>}BLLbbb��i<�111����Hn������/�������IC#b$c��iC!!!\���,X��<<<DR��?�Ls��IYL�=��455�����e�{��������P�	;�<������w��I@vvv����}�������SFFF��{��15j��v��!����\j��%-^�Xh��-[������D���daaA�f�����J�n�����")����N�8!��J������":t�����h����s��	m?r� //�2�,\�����w��+��}}}��EZ�����i��")���S��_?���T_nn.5k������j�J�N�������z�j�+�����3����rU������pvvI?�v���U�Vb��Y��_�k��U��.sss����;�mM��5k�4i�3f��E�:t(���'��F���������A�f����s����:o���������
�N�T�wQ�f��
���c���g``���{c��9����`{eS���$puI�y�����	>�<�������g�62���v��q8~�8�a4(�?FFFF��j���EEEb��)��'D:~��q8q�������]���V����s\jj*BCC��Crss���m�yyy��������v��i0��]�J������Gd���������033�0Y���AJJ
���'�&�A��z���q��5|���")�e�����'���O���T������(R_���18p ���,sr�*oooL�8��3�[�F�0~�xx{{����3|���Y��&M���-~��7��-
�����'�9���J�xn������X���%<�^�P����l�2�����+++\�p�&M�syaaa�����U������u�.i=�g��E�>}��M��������W��-#:YYY�r�
�����)��%�������%������������"-w��I���7v��U��gF4J[D�Y���>>>����U�VJ����7��Xq�����6L��������[$�muZ�����^+j���h�����Gooo��;W�e�=������o��cG��������{��B3|0�C��"%���O���$��������W'233C��q��%�������p��i����4iR��dll%%%���	��+((�pT�������������\<x���G�5eaa�f�����O���[[[�����NMM�Qg��E||�T����h�z�
�F�i����5j��}� IDAT���EZ.S������z���L&����000��c�������_1k�,��=k�,l��],e3�s��i�l��������>���/E^6W5j��K�"##�����f���HII�XL���8x� f��)��UUU�����;w��,yyy��?���

-�������������������>}
��.&�w�|�"����	UUU�<���o�����Z=s�L������"/�����`�z�
�G��:�2��%}��l���u(�����S������'����lF1������_�r�J������Y�f��Qoe�����-�o�����Tz\y������������/���^��i��,-C�����o�u�&�1��b�
:tH$I������{w��3G��%���y����q��q������h��)bcc���p�������z���F�	
D}��=Z�n
@��cbb"N�<�%K���l�d�e>|X,�3%6n���V:��1��>�O���"�����A���m��Z���;���I�u4d���#SSS��][���$RVV����:����@�
"}}}��� ===rvv���|z��=
8���oO���K���`�v�9;;���ihhP�v��O�>���Y�������h��
dllL��O�;v���i��������(88�@������Am��%ggg���?�������']]]�s����,�������")����<==�������O�W��>}���1c())��c��;G����e�����_����U�V����	)++���������k����O?�DS�L���������h�"�:u���+����IOO�


�ZOC���+RSS���t�Ca*!G$����={k�����/�2]LC��"66���b�'//:t����fH[[[,\�'Nk=,@nn.:$�z����������\����{�n\�xQ�O6�={�>}� ..Nd����y������W��(����<XZZ�I�&���Gjj*455���Y��������a�K�ru�����S'<~�FFFb��g���6m�M�&�z"WWWt����Y6� ��mqq1�t������qyCDDprr��A����!���m��K�.!((rrrb���8q�6l���/_�l���|������{�.,,,�ZWC���g������3"�G�2�~�-�m�6�������#''G"-�\��Y�f!<<�=.���`4QQQ��<1���������w�!""������'�v�Z�x��N��TWaa!,--�t�RL�2E��5YYY��vC��H�7n���W�
���3���8}��D�{��=,,,p��t��E"u�w!!!pvv���/E:wme�SSSl��U"��w|>����0a����u8Ld>��	&@YY����:����SSS:tHb	��}�G�Fxx8�A�y��!99g���X�������+<<<0y�d��[_q�%���_��nPD����g��puu��$V��w���kW���w/������0�?�b��^$�III055�?���=zp�L�7o���p��9��=~�x����|]��&44����xB7o����+"""���)���>��^�z����-�h��7(+V�`su���}�����#44������nPD#99������;�����~��;aD��1k��g�255����C�Y�n�"


�������?���&]�z�������<����;vp��	h�����_l���,--������o��IZZZ���;N�����I]]�����I�_�|!SSS��s''��|>��N3f����L;v,���O���D�Il�|>�5����u(2)))�tuu���S��q��e����>p�����i��!b���*YYYdddD����,Y���RWW���_s���K�[�nl��Z���Y[[��u�8�������J����4Y���EFFF���%�v��1RWWg7R��$�DD�����C:r�������b0`��;��P��h�������Yk��:s��m��RRR�����HMM�BCC�E����Q�������\�BEEE��woZ�t)���www����x<�C�P�v�(--��Pd����IEE������		!����(##������������CUU�^�x�u(2c��5dmmM_�|�:""*((�n����+�Ef��������'�����w���Q�	������C���:�������]�|��Pd��s�HWW��E�������;��L����H__��F���?��1c����=��2�.�%*�A�������,9~�8���PLL�������-[��C��E�}���:t�@���+������JNNNRs�$������������E������Spp0��H��w����r����,������s�������={V�����>�2�%"��� 333���7n� 555�����3���,�D&�?���deeEs���:�r��A�h���R�XVZ�]��:u�$U�|_;q�ikkSxx8��H��/_����={��P����@����u�V�C�Z<����[6l�
'��mb���i��i��[76SB9=zD�������u(�
 555


�:�SPP@���4~�xN�U%77����i���\�"�8@:::�u(���u+��������E����S�v��~@Qtt4�j��>�u(R������S�{��,g�q�6�%*�0b�rvv���l���>$---:y�$��T��s�HCC�����u(R#77��B����B���Rrr2�O?����}�������Q�i�x�b233c���K������?sJ�<~�����e��/	������N����)o=P�[��V��c����
%%%q�n��A���2w�~��RUU������P8���N�z�����K]��|���,--i���2������;IKK�<x�u(����i�����ukz��9��p������m[Z�l�������IGG��m��u(�+((�q���%Gx���H�c���'�D%�E�Q��)::��p8���Mjjj��?�pJ����������\�����������'�d���rtt$ggg��!>�OK�,!}}}����:�Z��{7iiiq���4x��ikk��}���V^�~M�������7��(���4p�@�����go���#5556�(Db[j�����u��H������]K:::���#������j��%�Z���
Fz��!�m��V�\)�?Dyyy4r�H���[�[�*33���C������'����'N�������c�������l���'333�8qb��WC���4n�8�M�L�[��e����5[�4�����b���F[�lih������L���R7�Wm�}��lmm�_�~���G��;>�O^^^���FG��:���x���AZZZt��%������P244�1c����}HWW�f��M���\�#v�����?P�v��v6��JOO�#F���Y����t���5k�>����dnnN��Mkp�1\ip�-QDDu������/��&�	���[����L������"Z�likkK��u���g=z4�����>�7o�$]]]�?~����>/����L�&sssz��%���Mxx8YXX��a�(55��pD������;IEE�^��������?�ttt���k�7==����i���
��k
2�%*y:}�t����S�Nq�H}������O���t��9�������444h��9�ni�s��Q�6mh��)����u8b���rpp +++z��!�����7oh���dhhX��...�������m��]&�W����6o�L������U���=z�����i��Q���PPPu������9�/:''G�����/������u����P�>}�Ek��K�HOO��
Fqqq\�#?~$777������Ott4
2���m[�oLJ��c�HKK����(99��������v��Ijjj4���CJ=z��.]�H����H���dkk�`V^������W���*�^�Z�W
LKK�3f�������������j��z�P!
|bKT�z���I***���!���S�~�����^?��������������\�Sc����b�
RQQ��+W6����O�h��!�����=���������lmm�e�����}�HCC��L�"�7�1114n�8����#G����rm���Q��=�����\��u85���O;w�$


�:u*���p#!,��JTT}������BK�,���-�v��]<x0ihh��
|��/_���M�HSS�H�o��:�*%%%��������Q�dv
(Q�w�ijj�����{�����G�v���>����t����� :y�$�����={��3III4k�,RRR��S�J��jD%S`M�8����h���2��!J|>��9B���dmmM�����U�J������V�Z���C�����b�m9^�zE'N$eee�7o�~��������/����Z�lI���K�y�Y]����m�6���%�����E"""h������L���
fDrE����[�n�{�n��7n��7o�,u�=������CdllL���t��	���{�����F�hTS>|����mA
>�Ow�����G�T��$���G�����nz���Z�~=iii��d�Q���V"&&�f��MjjjdkkK�v��t��'O����e��dffF�w����,�������{�s�����M������BJJ
���o��{wRUU�3f�DK�$>|�LMM���{�.}�����E2d�:u���}�G~~~4a�RRR�>}����]nK��q�h��yD)}���h�����uk222�u��q�2Stt4yzzR��IOO�V�^��oB�R�d�W�^���L�&M�7np�����C���P�-h��12?W;SwrDD`*���\�|����y�&��899���
�5K����

���?������WWW������F,u�gO�>����q��i���a���prr���#TTT�R'����g������7o����prr���F�������^Y���
ccc=z�
��uiii8s�N�8���_c��!prr����_bb"���������***�8q"�����}�
�������q��]XXX�->YR\\�[�n���/^D�.]0p�@899�{��h���X�-((����������������������}���:^_�y�'N����7


��~��AGGGl�FFF
��W�^���%������555��+n���h��1����E�����RRR���+�b}��}��������all4m��F����#**
��������;w���;���	������?�������'H4���sX[[���&&&011���1455kTnaa!bbb���H<y����h��� ����o��eK1�3�������\�x���DEE������?�������~�����&&&022B�����q����� 8�/_�D`` ��}{{{899a��A����vyk�����wq�����dgg����n�B@@>~����{�G������kTnNN"##�����{h�����8d��h�BL��� "<z���]���?=z###������022���	tuukTnqq1bcc���������yyy������0l�0t��AL�L���]��/������\�#�Xb[G��g�������@__���PRR���:������"��� 77999�����������:.�������444�~��^FF���p��}�9|��-TUU��];��SRR������'8���HIIA\\455��k�����LMM�~�R���������'O`ddT�2������o�������@TT���a``uuu())AYY���h��)������g��bll,���add###������={�D�f�j[~~>LMM�{�n�1�Ve4���@pp0������x�i����PQQ���
������"����ldff���O���#��o/H�lmm������[s�����<��ww��Exx��<6i�:t|���
 33YYY���Azz:��yEEE����;wF��}aiiY��UY@D�9s&�<y�n}�Kl� 33QQQHOOGVV233������<4n�����$IEEzzz���#���<o��E||<233?�YYY(..F�-���UUU(++CCC���PUU�:t�s��A�}��7oy��������`fff";;h����G�����C�k�rrr"����3�{�.���#�r���|DFF"%%�?FNN������ I*mD������Q�oD����x��=�����������@qq1�6m
eee���AQQjjj022jp�����1i�$������kPRR�:$��[�a�a)PTT������������g�a��


8s��|>�M���Xs,�e�a��M�6�������+���r��a]�a�a���c3!�Kl�a�a�z�uE`�a�a���2#QG�A~~>�ap��p��Q���q
�0L��[�a$����W����:N���������u+��0��+��-�0QXX�]�����:�����G�x��9��o�u8�����@�����0�k�eF"v��---�;��P����)&O��CaFF��������{�Ej�[�a�.))	&&&�~�:����Gjddd���������#��0#�?GGG����w��\�#uXb�0��M�:�7����E�����Fpp07n�u8���S�N�?��BBB����u8R�%���Uhh(����.��(..���5�������p�������7�B_a}l����Dl���%�h��1v�����b�Fv�����"�\���P�
k�e�a��A>|���
�?�A�q�T`�-�0�0��z��%��Y3�C�
,�e�a�a����a�a��Xb�0�0��,�e�a�a���2#2|>���Gjj*���4>��y��!--��P�ad
Kl�������[PSS�:���Q#ddd�����P��A<@@@�ap�%���Dvv6<==�c��
����/8y�$�?�u(���O�>a���HOO�:�c�}1#K�,���oq��y�C�7��_���@��u��P��1&L@���q��!�C�(��2Sgo�����BBB`hh�u8���/_`jj������o��:�adHjj*���p��899q���������1w�\���X�f��u�V��?���/_��a����-[�`���
���[�a�����������Kc�����v���u(���~�zzz��y3��H���0L��z�
			8p ���[/^�@bb"�u(�����h�������077�:�c�-�0�0L=v��������\�"v,�e�a�a����a�a��Xb�0�0��,�e�a�a���2�kHs2�0LUXb�02���~���2���%VgAA/�:��x<�u(����:wKl�z����:uBLL�eH���/x<���$V����
>���m�J�N�,yyy���`���\��0�������
�E�Xb����W�"88��}�r�
��}�'O������!-���:::�/))	��m��]� '''�:���^�����}�6��0#cLLL��ys�����PD�%��L��>�������iS���b�������j||u���	���e��a�������H}L�����n�:,\����\��0bc���]��a����r�H����)U=v��������I�Z_�2��$������`��5b���������p��a�C�wq��l��
����:$���*\�`����C���u��E�Xb�����/��{@]��6������.\�U�V�U�Vb������c��X�j>��u8�JQQ���p�����/���#�!IeLU�b,S}6l���G��@Ty��v999���EZZRSS���SSS��u������������U IDAT�(..��


8;;�K�.�������/"44������3�===�k���q��M���"55�/����c����WWWA_�R			���ADD`cc��c��q���z��u���!--
nnn�����[����3����W�^022*�x"��+Wp��5@SS#F����}��T��bccq��)l��	���cA������'�������0`z���:���UTFM�P��M@@���������}��)��=|��n���/_�����"66#F�@�����T���3g�����s����v���l��	[�n�:�zCOOK�,a��e\�@�1]�z�������S9ZZZ����X�)�f��o�	&`��-��?���k��BQQbcc��~�Y�����={6>|��3f�W�^����0�|`���h��,XMMMX[[���3e�}��z�����b�]���oG��1d�9rD����<�y���o��������E����K�.����P�����������{�nxzz���KpvvFFFF��s~~>����w�^�]�'N���y�PPP������������e��Q9a����a��m���?0b��=��M����{������������bbb��������oq��axzz���g�z�s|Ue���e�n"""������xL�6M����:n��-8}�4~��'�_�;v�@FF/^���D��J*�6l.\� �]3�]�va���\�Q/5m�����DLU�G�.I�`jn���8u�bcc�E4����'O������`�}����F���)S())Ih���u��Ah[ll,)**��C���M���t��9��[�l!��?PRR��������5K����S�F�h��B����R��-i���5z�^^^�F�A|>_h����	M�>]h{dd$ SSS������~���2�T��}�:__�
c>�<����WXOe�WTFm����n������'B����O��7���""���$JLL,S��q�����B�n��I(;;����0L�����P`` ��H"&[[�*���1}�t@AT�����
�C$X�m5��!kjj���Vh����`n������!66����m�g������c��c``���{c��9B}��5kPVV����5k����c��}����5M�4��3��l����}��	��VE^�����I��L�4`�899���C�s��`{�6m��K���K�����J��[u�[u��%��2js��.�U�Vef077G~~�`����?�����G�:F�


�m���h��9���j��a*!��������=�C$X����,������}PTTDnn.�_���]�V����� 00����7�|#���?�����"44��� "�D��m���<�������#F���>>>ppp(**
=����Fll,��{'��"�7����@��]�lk���s�k�=z����'���4=z���A����Z�x�l��.o�a�$�q���5(Off&����'O��S�N���:v�(�Y]�rE0>���Q��>>>AAA�}S�LA�������. 88���h��
��++�Jc{��bbb��I�����������gR�����`�R�������j�������0��|(**V����)$$������{����Dr��
e�a��PQQ����*��?}�Th{AA~��78;;c����x�"������6+zo\��9���>>>�4i>}����c���000��+�,����[F��5�����v��5��?����f��EEE0?��3����>������B������������n��rg4���
n���%K�����'O���;8Pi|���5j����[�n��3��xi�0�X�������<����~�����i�����y����Y-999 ��<11NNN�����K�#jsss1e��J��MKJxx8��iS���:���������;�={�����x��!N�8���7�m��pww�V^^6l�S}Suuu,_�\0z����w�t�j�����{�";;���� ��<y2�n��+V`��qB���������k&M�$�>x�`������3f����j�*4i�������TTT`hh}}}�����pqq�����1c�TUUq��t��7n���W�?���8�:uJ���}����`mm���t����PWW���Z�l��S�
off�5k� 33;w�,S~JJ
���acc��G�
�{��!2220s��
��������s�NL�:U��Xu?888���/������#�<�������'�����ys%�n777���?e�b�-#i��V�,,,��Y3|��������@����166������I���,�*����u�&�6g�������[h��'tl@@�������g�����9����p,_�@I����c���x��9���q���2��>��wcad����(��3�����~[f[�����b����w��`{e��K���-Y�iiiX�j��v}}}�5
��O�����(��������M+3&B��	�H;��J���<������x��������q��Ut��M�o�:5j��K�"##�����f���HII�q���@�������jm	

���<���+����_��c�+W����`�c���g�������X��9����B�>}��M���������j��E�]l���(�4�<`��A�1j�Fc��cy4jb�%�X@1�kDQ�DPi��( }������W���Y��\W����9_���3��6��T����c��5x��y������XYY!11���d�WZZ
[[�*�������B��u;;���[����T0Vx�Z����K�����k
j�I���.���"��������9y�$T������c��a�����.((={��������P���~O^]��m[L�:{������1v�XXZZVz=�`���m5���W�M�{�z�+V�@�=0k��JG-�_~�%$	|||*���x���E��w��X�hRSS+=w��aXXX�j����+�#",\������wo�A�G����9����'''i;���h��u�6pvvF�&Mp��U�c)))�v^m����V������������h�����X�vm��^�|�������c��Eu:�d�����������M&����1cf��U���z�u@�ZkP�h�u_z�+%%YYY044�Q�}��a��
����rM�
�xOx-@�&�1j���.�Vd<��?~��S�"..��k�^��U�V���?��#�����?���+~��w����8t����```��C����PUU�����r�J���~�!���cccDGGKO���y�/��{�```�E����5jT�SS***�x�"~��'����{����n��[[[�Y��V����3�������-[���'PRR���o�����k����)S�`��!�3g������'c��	8p z����#G"22��?���`���X�t) ++���G�&M���SL�<Y�{��q#��9��'OJO��m{�l����w��������k��6������7c������@YY�����gO������3ptt���:�������k�{����X���W&G���-X����G@@F�!t�J�Z���"�r
�&ttt����H"�2��MLLL��~,]�������Ga����^SW����x-@�����D"]Y������U��<x@���O�_9!!�"##I,�j����=z������)""�


��mFF]�v����*�\���S�<����������!��������Ho����K��_����SIII���6�
�~�A.}1���m��H$z���=Jh��uU����]�p��s�233���������m����yyy
�>��������������Y\\��>_�����m�����?�,}���o|��N�J���+���� �����~
����R�;w��X,���{�������v�yO^w3��K���{�(::�����*m�����������V�DDDP������P�(5�S���t����/�lnn��;��u_����������a###8;;�C��~.MM�j��}}}}���T�n������LUUUz�WGGNNN������lO�>���(������a�`cc�
6�������*0����_e����>��_�������S�����rA����=���������555�=��:���'o[��k��u��������:J�qa���b���@����2��?k�����
����v�Z����W;u���_k
�6m
�J�r^�q�~�z�����h��=zT�����N��w���_���+W���{�*=w�����I��x^}���i��s����{�8qb�����=y�z��0�X�`��__���Iy��e���Kqq1?~��wm�����-���j���)6DFFb��������ccc��� 22}�Q����1F����(++#22��7lmm�i��!((��5Chh(��9���a�����������/���H/������>�O�<��������c���PRR�����w��y�&&N��3g�@UU���8{�,JJJ����I�&���B~~>,X���($&&b��mPQQ��_]��_G��a�,Y���������'N�����6����������3<y�G�Azz:�v���/���38{�,��f��AII	c�����f��� >>��/���?���[���������Y3\�p�N���1c������gCYY>��������n����=122���>6n��������1b����w�spp��={���sDEE��D�.]0o��Jmeee!::s���r�������c�������F�8��D|8�����w�y�f���AYYb����X�|9LLL���d ''��+�Y�VPP�f��)�������(((���}��LLL�H$���}�L������`gg��iYb����(,,D���������#33���044|c����Bu����l������R:u���999066F^^bcc����L�b��k�.<x���BG�6.lc�1�X����6m���+�I�����1�c�5<a�1�c�5\�2�c���[�c�1� pa�X#s��=�61���w���cu�[��'O����qqqBGa***B���$t��S|U��	&@WW��m:
�����i�&DFFBEEE�8��z���D�����#��5���8{�,�/_.t��L�


���[�(��zb������:�[qa�X#@D�3g�.]*��k��4i���7����/^�x!t�X=����C�	��x*c��������?#22Rao���1z�h�j�
�6m:
cL�����u�����A��m���Z\�2��������(t�`?~������A�8�17j�(t��
.:�k�T����0���pQ�^�m���;w.��?/t�X=0~�x����Glc�1�X�����u��F���S�e�1�c�����#F���O�(���-c�1���������R���Sc�1�X��Glc�1�X���-����;�7n4��c�&�gT��k���e����W����������dee	��c������A}��&�gT��k���e����ge�����'#//O�(��[�r%�����Q+BF������[V��<y7o�lt}W��_�y���]�vBGa����*~��g,X����B���?�B��Xc�"t�*�������(..Fnn.>��c<z�C����)=z???�Z�
!�V__={�����p��i����())���!��J}���������Dff&����X��i��;v,���j��PN�<��w�����BGa
���C����b��uX�d��q�}��H$5��6�1�1Y�H$h�D1��ra���5k����5k�@]]�������������SSS���BKK���8u�������h��u����;;;�]�jjj�v�F���b����`aa!��o�!99c����5k0y�d4g�����gk��JKK�`��������:k 6n�|��g0554�������}F����,Z�����������1&���\j��)={���sc������J��Y����S�^�^\\ [[�J������eK�m*��4i=������C�4c���-��k����I$���f��Y4n�8A3�d���g�1�����A���B��R����Q���AYYv��U��!C�����F��i�;vD�^�*=��wo/Og����@[[���PSSCTT~����-���t�Z�
�6m�����qX�b�
�?�/_,��)�A�!22���BG�S��������%K�`��]0`���1`��;���ijj"22R����|<z��������7n[��=~��f������QX�����~�	��?,��).---������3�>}��q��L1�8q���HKK�o���i������/���4KJJ�e�������������v-//�v��7��� GGG�X�B���<y2F�!h#S\@``��1�[� ���q��l������z�j���`���o�>&&m������={wwwdgg����B���"�'N|k;���5��j��1�x�1���Q#�[�1�-[����Z}F��e������E������_?|�������������#G���c��Y�___��bq�m�����F����{�;F��3�ccu�������u���Q��e�+--������T�6m�a��U9���E@qq�����\���BCC�����}�V�.::���>}���5����cu�&cDu>�<F0V���/�\�
\�2������k�Vy����3fL�������I\�zU�XJJ��Z�=z��X,���w+m�o�>899����^.�����������o��lTw���g������U����)t(/[�l��!X�Vqg�����?GTT~��Gt������t+###���c�����������#F��������b����H$�����-[0q�D|��G��u+��9�~���Y�f�8q"��9UUU�������())���c�����1V�j2FT�3�cc
��f9)cu���999066F^^bcc�������q���l������FFFU����DBB455acc��M�x�@D,����w�-K+V���1c`ii)�~�����e��a���PQ��������6�1����[���k��������044:k�$	\\\������g�1����e���H$pvv�g�}�Y�f	�5r_������$cLa��1���}��A$)��]sqq���|�r��0���e�������5�����1@jj*���q��t��A�8�1�Gl�V�X�=zpQ����	���k��;W�(�1q��U���	�?��)���D���?����Q�b���x��!N�8!t��������[���"0��RRRp��e�?^�(��V`` �����[7��0�����6m� ;;r��[��edd����6l��Qc
���Kh��lll���X�`cc�]�v�w��r���"�/11�/:cLA���AAAB�`��puuEXX� }sa�c�1��L�^���e�1�c�_Ea+�H��7��1�c��XZZBEE���r��[�c�1Vg���p��i|��r��[�����!t�j-==nnn(,,:
cL NNN����{�\�2�@�?�k�����A�(�����1�����"�1����1QZZ��b��u�\�����a�l��IIIBGa�5"\�2� 6l�����c���BGa�����b����������kDT���?��~�	���PRR:cubW��3 IDAT��e���Fhh� w b�5>|��1�h�"�9��u:
cuF__��-���sQ^^.t�X#��-c�}�6�;�+V��:7}�t��b8p@�(�1�\����1�������sh����Q�s***8|�0>����0��,!!fffr��[���Y3���C������=

����3SSS<}����r��[�c�1V��6m
sss�����O.lc�1��L��� &&Fn�qa�c�1�d������r��[�c�1&|������H��	�?�5666|����J"���?D``��Q��'O`aa!����1a��� 77���r��[�����~Cqq1�������`��iwww,]�T�(�1���Fff&TUU�����I~~>�,Y��7BEEE�8�	j��58t�������k@��e
A,��5�z^�/_�^�z���>�{��)�6m�`���;w������_�1�1����e
���'��Ml����s���=z4LMM���JHH��]��f������[�`=z�?��S��<}��Attt��N�>
�Z�J��cu�[��2�/_������C"���gO�o����r�0w�\|�������[��):555����X�`�������s�0a�������K���l��/�������%K���1Vw������,`���044����ADX�`f��!��o����'������%�������	&`���r�7$$�G����#���p��5\�x|��\s0����A���E�n�����Y�fa������������ }3��^�x())�����L�6
+++�g`��.lY����������0�����/����I�&	��+>>&&&����i?\�2�c�1����6o���}���^<�c�1�d������2�����z-;;qqq���E\\����������D" ''D555hhh@OOZZZ���������aee������(�1�*//Grrr�1"''����qB$tuu���	


����������q���-[���b�~j�����d�OE`���g�,�/))	������
���amm�>����������&�������D����H$Bnn�tGW�����A�=���7778;;�Y�f�����(//��;w��� \�|***�/�_b


���hjjB]]������B�D"��� --
�����������pss�����c�z��_����c���2��[��<x��"  ���pqq��T���*a��x��	����;���\����Y�f�����122���q��222"�1����w��7n�
V��u%&&�����1����`mm�������������q��yhhhH������]�v�^�������K���D"BYY��������������M���I��H$�������������!C���''��~k0�}�v\�xQ��pa�Rvv6�9___��{����q����Jw4����t�������x�������PSS����t'���
UUU!//yyy�Dx�����+�qtt���+455O�>��S�����;w���O?���7�����I�)���������M����)�����"))	�:uBddd�����[��������y��������C���*++CDD����gfbbb��������/'�b�tZB~~>rrr���SSS�akkWWW���xy�����8r�>===xyya��	|-\�����k�2e�k��W���e
%55������{��gOxyy��O?������p��9�4��������:u���������b���������x�����p������	nnn���\]]�����������PVV�w�}�	&�i���68�}��!$$DF�c���_���rl��Y����3X�j0v�Xx{{�k��������������eK���V��daaQ�y������*�����PVV�8p >����b�?���8u�<<<�h�"t��Q&�c������{w�x�B�c
 !!��N�J������M���DD$�)00����IKK����h��t��*--�I�������/�������u��4g��u�I$:y�$����LMMi���TTT$�>''G&�kLD"��3^^^N��u�����kG�7o���B""JMM���7S����E����M������d���H$t����q#yzz���&������;)77��^�!��-#2d����$c�IAA�������e��LP���4s�L����/���RRR��())����C�����S'Z�~=���	�1,,�f��A�����K��k������g��?���[������XCJ:t [[[������2�H$t��q���ihh��������TVV&�|����w�^���/ijj��������D�r|[�b�'�|BIIIr��Xc��-�D"!j���=��<yBDD���4q�D�����?�����#p�������������LLLh��M$������SdffF����mf���������>#CCC��k����X,&???���YXX��;�IRR���d``@��+W�Q^^}������C�V��~1f��=.l�����R�>}������?ODD�=���G���6��7OZ�*�.���5o����_O���TXXHK�,!mmm����y��X-����h������ADD�&�������X,8����������������K7n� "���(ruu%�t���)k���er���Kzzz�l�2*..������IGG����k�N���=z����tGO}������Sbb��	�?���i��adee%=�K���#sss:v�I$�SV�H$��k����.��9����H"����{I__��-[��:c��L.�������"�|�2���
���RTT��	kO"��������������$�i��%���G�����Sx7o�$sss7n���Qaa!}������I_}����>}J^^^dllL ��f�o��
�����[&s������@����g��QYY-[���7oN����WG`�&##�&M�D��7�s������U�V���_
�����`��-���C�7o&��Gi;v�H������x������@����O>������������C-[������1� pa�d������EZ�bI$JNN&rrr��
O&�;FFFF�t�R�����F...���)�Dc�����K���������HWW��.]*��	!//���OfffADD�������#GN�X���-����`200��{������������+�]�VQ$%%���3���Qzz:�D"<x0����233������b1M�:����)55����i��I��+5d ===��e]�t�

i���'cLv�={&��\�2����':z�(��
����'����b�>}:�����H,��)S�C�<��5j������INNN���A������S�~�����H255�9s�Pyy9��w�LLLh��eBGcL&��=K=z��iUov��{:y�$>��s�>}���O?���������<x�����Y�f��s'�O����{������{7�����}�"==]����]yy9���X���`����O�>�����S�`hh(tD����#�]����L�4	VVV

���V�\)t<�����.rsse���N���c������G�^�0�|���aaapvv:� ���[��������\��
6�w�����DAA����"����������������...8z�(�����(w�Z�BHH=z��C��e��8�<�m���[�
��:%��V��H�=�F#**
nnn��cF���������x�"Z�j%t<�������?G`` :w����G�����G��M�����}��78w�BCC!�������G������WTT�����I�&8~�8bbb����={�`���B�c�N<y�VVV�D2�����:�����b���9r$�o������������9�����A����������������M�6���#8s����1p�@0���������G�";;�&M����=�I�&���kB�c�N������eee2������&����'''�[�~~~�;w.BBB`gg't<��z�j���W�\�������c��)BGcL&"""0p�@\�r���4hZ�h�C��I>�����\�����5k�����������������{!"4m����000�I\����x�b#447n�����={�������s�",,W�\Add$���/���A�h�����,t��+V����7������3�:u
���B�SH����������b����<y2222��_AIII�x��}}}��}����I��U����� ���~~~(((�����i�&.j�a��
����������%K�`������:cu��0e����������.]����sQ�&&&����q��l���?��������{�0a�L?�|���ZFF:t��_�C����~
���W�h�BZZ�t�������O?��a�`hh�={���:�e�l��7o�DJJ
\]]������I�h������m�6��uiiipqq�������(t4����&O�"��}��~�z������:Z���#G���������-�=��}�
������3����������-�w��i��a��yBG�7������|||�i�&<x��_������SH\��Z	��!C���\t��aaa���:Z��h�"��y�����s'�m����oCEEE�h����1c`hh�m��a���������'y�h
egg�c����};�n��a������/����B�����X,F�n�0c���1�F����|�r���KEEEppp��U�0r�H���#G���_-t4�j���?~<bcc�����������b�����,@tt4���#=�`ll,t4����6m��C�!<<�������q��=�����:}�4�N����X$&&�_�~����k�z���:t�������7770�-:Z�6p�@t��
+W���)S@D���������Hqq1������S�N������;���!t�z��O?E����a�L�4	�
��;�����-[p��M���k��ATT�5k&t�z-!!���������,--q��-XZZ
�1���-���[�����		���+�S�N	�AHNN���=������28::"!!��7:c�"�H`oo����������]�0`���5�/Fbb"�9�9s�����w�:c
�[Vmeee���������W/�k���G��=���`L�>jjj���_0f�XXX`���B�b�Z����t�R��w������������x�����p��5�������������������/C[[�;w�I�\��j��w/�m���7ob��M8s�����<|��:uB||<�������G�AOOO�h��S�n�0w�\�;���X�~=<==������?YYY��o_�/���_~�%Z�h�~�A&����X����/X�x1JKK�~�z,^�X�H
�����M�6����z���������;]�t	3f�9uuu�{/,@@@����p�B�����X���f�����Df�sa��%22O�<���'���abb777�c5H�}�v�����"L�<���BGb��|||���
l��.�k��@�V�0n�8l��pttD@@����6555��}.lY����`���PUU���&O�,t����6668q�<<<�����w�
��7***B@@&L����x���a��aB�j�&M���B,�������z�I�&��,X.l�;��b������O�>���W1j�(�c5h;+UUU�1�:cot��1�����������Q����2��G�������9r$�_�����1���-{���@����{���������y1���3!!!x�����p��AH$�c1�Z�������D"������%t�o��	������<<<��/�7d}�.l�;�9s#G���[&[����������g���H$���:cU!$$��
�������WWW�c5x�������!�0|�p�>}Z�H�U�,��sa��)((���HKK�����#5
8�<��������� �#1VEXX�����E��������Ecr��];������+pww���7!�����;u��
=z��Y�\���JOO���������`�����99�������2���!88X�H�Uwww���j)�������`���
W�\:c���'�`��2k�[�V/^�����/SSS����pww���)��q!??������#t�F���]z&���e��������K���o_|4F;.333����BGbLJ$�������BCCaoo}}}�c5}��ATTrrr��e��pa���������+������
'''�#5*�{����W]�vETT�����bbb��uk���k������888�������+���'���):�0�������M�6:D"�=�/^ 33�n���mmm���F||�����*������N�������1�4i���T�m�V�X�	����7���@~~>��k���XX[[	P^^���,>|�W�������$3VVVHJJBqq1����E.c� ..N:.��g!5���t\PRR���bcc�������eosss���(�Nxy�m��yX�h���>w�n��!��tuu��ys$&&����wZL�T|��H$HHHP�1B������^�����-���aeeU����Y�fr�����HOO�k�;+kkk<z��������g�5k�-ZIJ������^.lY}p��9\�~]f�sa��(33S��z��	��p��Y����m[<}����PRRBvv��30�:c���Oabb"t� �1�m��HKK������r��������.����eo���mmm@AA�������'q��M��������|���


�����������������#t�	1FhkkC"�������<>0�W\\555���WE`oTPP]]]��\Y{��	N�8���X4m����=z4���e�FQQ�;�7n 33m��������K��G�����U�V"""������g��������-���� "�D"��I---��[�CM�Q�1BEEjjj�1�b�`LQ����#���^�Y�k������y�����_�d����_����O����;w����������o�����>�3g����;��������64--
			HHH��'O��
x����b��������#����[�CM��Oc��>�uab�
F�M;v����rRRR���l��AM�4��7Vz\$Q�-h����?u��;v�����t244��?���k���	Y[[Wz|��5�N�:�^?gMm���>��3""rqq�3g����^�������JDD�7o&ooo��W�CM��/c���9��y�"""���R�}3VS}��������}>b��HII	D%%%())���3f@UU��O������_��������o����������v��a����6mZ�T���w�M����)���\U��T�CM��/cD����X���*..��UKx�m#�����ye����������|����$Gff&n��
[[[���W�������?���i��q��I@��+�N]]��������z�W�s�{mmm������T���b|�M;�m�HNN���)<^<�d*44����;wn��������^�+W�|�k/^����5i#%%YYY044T���\�2E��������������1��VL�:����Y�\�6rk����A�PVV�o����s����q�l���ys�^�Z�mTL��D�u�.&&m�����/??_z*���� IDAT??_n��{��39���[�CM��/cDYYJJJ��e�����e�>O�k�������o���III��{u5~^^��rX[[CKKIIIo��VIII�����sss�����}mQQ�;��9r�����W����|���������2���wy��R�������1"//���PWW��e�ST\�24i��F~~>������066��g���{���"�.Dvv6N�:����7u���y���������+�Wq���b�c����k��Jrr2��m+����9s���---8::b��98��w��S�LAjj�Ls���b�h��-RRRd���.����S�����i�JJJHKK������b�>����H$��c��m����OOO�����������E���wo,Z��Jv��aXXX�y����*��:E�&m|��������+q���J��p�����;*pvvF�&Mp��U�c)))h���{��o������qqq���Frr2V�Z555��;���X�|9rrr*m���eee��)�sVVV���G��m!�H���S��U�CM��cD��qqq����Y_��<���z��9F����\=z���C`` ����������C���������L3����������������vvv�u�lmm�f����O1i�$�������7oF`` 6l�{{�j���Cw��	l��IZ�[ZZ"11��7���k+��������t�R@VV��/��oeee!''fff�����G�����~BXX��[KKK�]�'N����YF�xU|�URR�~�j���L��������c�x��������.���dv�\�����O&&&4{�l*--����
���Tym���)&&��\�B666r����@���$���F�k��������,�z�*edd�:Wu]�z������h��������s���Pj��=M�2�=zD={��uL�H>|Xz��Q�F������w]�5mG��1c����[����444���'2��1E�Gl���8����~�-�����a�-[��y`��]]]���C��
����rm���������Km#�Httt����|��k_WTT��={����������p��1��=�����������������������C$A$!''JJJ������������	cccXXX������G��Mk��3�fmm���X���-���/���b|�i;�8F���`���HMM���2Z�j%�~ST\�6"YYY8p ���/-j����~�6�:u��[���'���������������P���p���*w@�������ox9�.00����o,�_UVV����������Err2Z�l	kkkXZZB__&&&���������E����b���w��E@@������333������������#�=�����Azz:�?��={b��BGjT�������#00;v�;�1��[�na���2�C�H��Ad
A"��?��Z�j��{�V{���l��W�\��Y�`dd�����0){U��mq��qhii��������K�������������"  AAA�r�
���������{�������}M���,��������t����QZZ�>}��_�~1b��������Y�f������HJJ�����N@@6l����0��=����'t,��h���8����K��Gl������#''����H$BIII���G�LMMajjZ���U;w�Djj*����m��o_�7���pss����������8�s����k���j��6lX��������>>>�������Q�Fa��o�im���...�>}:���+���q��9|��7pww����"�i.�����!88�F�B�����#G
�QF�~�AAA��m���{���<����[�H$���Bpp0������X���!//fff044���������XQ�";;III(**���%���acc�^�z��?|���?�~�'O����z�����aaapss���D"455k����	

�����pss�u[�n�������_���S�N��a���������0k�,dff����X�n>��s�;�������L����1m�4����������b6--
IIIpvv:co���!�3:<A���q��I���KPUU����t�"-J��o��}�HOOGLL����K�.���������������������3g����w����3�|(++������.\�#F��-V}�
���C1m�4�l��������Q�/_��U�p��
��=S�NU��������_��������E����A�X�JKKa``���<y�#F�@rrr��.��y���w��g��!  ���������[M�4	�:u���se���eh8rss���~�>}����&
6��n�J���2����@�g������|@�/���""JKK#mmmz��Q��

�v���D"�M�6���g�go���SRWW���L�x�"����D"���!!!��woj��%�]�����e��n=�����[�����C�RTT����;:�6l�@DDVVV(p����~���'�'�|B7n8c�6h� :t��L����=���?4~�x�����}���}�(//O�,��BCCi������KNNN4k�,�6m�{���];


���tRWW�g���Qj�:����a�����i�����.--���O����u�V***�aJ������K����}����}���P�.]��h��e���-p��M"������/HSS��������;9::��d���F���H__�~��JNN:R%EEE���G]�t��������J����no��������~������^�S�Nt��1�D���Mqqqo}}yy98p�������K.�����T����V�Z�����^�������(22�=zDZZZ��,A}B|�������[i���BGb�ZLLL����2������ 777266���WSnn����J"������g����uk��eK���C���TTTD�����S��g�w��
244���:t�������qqq���H]�v�����)�����_��}{<x0��������3��o�!"���{��={N�py{{�������G����'p"��g��=2��������,�1c����������P�H5D]�v�.]���k�j�������RYY�����S�d��
6L:�������)���#}}}Z�r�{�Z�>�D4}�tj��5�����"<<�Z�jE���t��1���j�&����G���MO�<��w�����D"�c1�0��}�DB ccc�������#������������������;���Y�I���h�������~�:���nQQ}��W��E�F�P'  �

i���\<)�^�z���;I"�P����:R�3c��9s&�?����[�1�X��}���L��� kkk�x���q�TZZM�0�Z�jEAAA��F,���?~�����M�6,�����q�����#��s�W�\Y�5�����S'8p`�>%O�;w���|Nq��)233���2:t����Syy�����O�J�r���@ZZZ���S�c1�P��}����S�������


��#3��'���~[�#_{����]��D"�
6P�>}d�����!MMMz��)��s����)''��kbcc����,X�s��������S�n�u��($	u���|||H,����c�������?v�zSP@��+*��b�2�eEQ���c�et��8*�.vGGT���"AD��@(�����o8���M�{_���C�w?`+;{�����;�t,�1k�,�<y2��������p"K������D�~�z�p8t�����Dbb"u���\]]���Wii)�����7����,,,���2J��\]]��_~!"���G���K+�E����~�z&�����r�1c���������S��>}�lmm������=K���J=9 +��?'�C)))���[RUU��n<,�<`�(++���'��������B T�8

";;;*--�7n�����w��w'N� *..�{�����.egg�o�}�6iii����a���dll,�V2��k��z�P(�:���;��h����h�"Y�S:"��z��)~S���I����b��[���@ ��#G����R���m������7�&�B���;m������Ns���UD�SPP@&&&t��e*++�v��������?x��8]�|����a��dddDo��a:�R{��)�������)..���?~L����)11�444�~
�2

"+++t��-RWW'�v���X,���D���KNNN�����nDDG�!�C7n���>O�<!uuuz��-�{��8�R�P���3g������h��M��[7�����8����C�1Q��X��,,,��������8@���'KKK���+M�6M|���S�������-[F�{�f;X|�������;w�PII	Y[[Spp0������)yxxPRR�1Y�5o�<������maa!u�����������8r#$$�8�7;&������#��h���djjJ�>}�UD�B������A������I���DD���J����u�V�S*�9s�P�v�(77��(J/11�H ���O�H__����I P����}44�3�PH���4k�,"������I�q�����e�HMM������ ,�&��bu��---����';��!!!���M111_�=//�LMM������4b�YFThIII���M�n�"�PHnnn���ODD���dkk+>]�U3B��F�M�����m))))�������:���Q�N�(99��}:D������Mo��%]]]�k�(M��/'*..���(���������/���������,�TZZJ
4��~�:[��D"�����}�Rqq1�q���#GH__��\�Wo���$---������B�����~�M�)Oii)u��]�a��e��S'DD���E^^^lK�Z��%������v�YXX���+���SFFF�G?�������D":s���W�!,,�8q�\���%ss�Jk���������K��McgoYr���7���!���la���O;vdw�W���������Mu6l�6m�����O����&]�~]�)�H$�I�&��������;w�����v��M_��e�\JJ
�����[����
i���dhhX����K���6�/�G����m�6""�={69::���7�~��

���3DD4r�H�����c322����Z�jU��wX,i��m��d�:Y��>}������%50y�d4h�WgE"
:��L�BD�O��������:�B��m�Rnn.������;v����={F����N�<BBB�����������>|H�[���~1��w�^��eK��������#*++#OOOrss���i�V8iii��eK��im���,--k<	s��A���"�SI��9B���Xu��MLL$---���?���P������A���}���,--i��UDDt��Q200�W�^�2����y35o����{G�����cG�L��'+++��c�)���������]�����h��e���E�����}?~L��u>Lzzz���+*..���{���7�w������];�f��}���w]/55�����c��U�f�da���4c���U�
[�@@�:u����3E!q�\������������H�����l���dff������}�HOO�����������i��q��^������S*'�@@���l��JII���;S������=��[G�Z����t�������������@]���G�z������P(�����V�7���4�S�NI(-�U3��M��k��d�:U���5����C�������q��=#�p��Y��

���PW�_��������'T^^N�F�"�f������`g����?���D7V����K����p�B��f��?�!������j��=�1�N\���A:t�~��JKK����O������dhhH��Mc���d.>>^fG@������g���!�Y��n��!4o��*o���[qR����ISS�n��)��rC$Q@@YZZRRR�����I��s��������=>e`��14s�L�c��}������x��$�D"�8q"����rss)//����K...ur3oRRYZZ���?�D"z������%>VZZ999Q����=&,�U'
[�HD=z�������������O�Vy��7o�����=M����UL����#�m�����&>��G���8~�8YXX��+YIKK#�CQQQLG�K|>���C���R=!�����������RSSI ���u�����{'�q��_�E��q������O;w����eee4g�233�I�|K��Da��~���cO����WS�^����#**���<x@-Z� ooo��x������8����Q�FQAA���P��=�����|��~eee��U+�x�"�i��
6���;�1���O��G�4x�`����D"Z�`�l���\.������������g�>>�D"m�������m�BBBHSS�R5i����IKK��\�"��X,YQ��6//�tuu��X$����lll�m��R�1��9s�������i���dccC��=�QZ�:|�0iii�g]������69r����2���HOO�<x�t����N���c�h�m�������w����^�Jzzz�����kA?~�H$�J��9��qC�Yn��A����k�.���bI���k���Y������3dcc��;�����g����Kz��
�D"��};iii����f&=99��BfffIDD���'Z�r���H$�6m�Ht��zV�\I���L�����djjJ~~~���:~�8q8Z�|9	�BJMM%'''����R-9~�8�����|*((�q�����=y���L���dbbBK�,ad|K����������_e{*V�Tf��`R�SWW�.]�DDDO�<��������B�.--�m�����Paa!��3H__��Msg��%kkk�����HKKKi?5����(�����[�2��\.988P���)++������_%�C���U�|����daaA��]#��e���i��a����h�w��Q���)  ��,�$(ua�m�6rvvf:�R��G���_'}}}������<
���~���%oooJJJ�rb��Dt��%���&'''�F���������Sfff������W�A�����?0�1O�>%]]]�z�������X��<--���K����o�>�Z����GZ�`ihh��e�����JKKi��
���)WK>|�@������?�K�X
Mi���j���B�*���2��������45j���G��(;;�f��Ejjj���-���%
������];������`�D���C?��3q8��m�7gb_�xA����>�,�{��=���Rnn.�Qd�����������(_u��yj��yxx��7o��������kWj�����oTTT�p��eddP@@ihh����~������������w�����ISff&�m��~��'��$��t��M�o@����p�9880�N��};yxx��q7n� KKKrvv���8"��a��y���A�F����P�y������{����5������G�����B!<x����h��q�������7o���� 5�[\]]�-�����D266��xlyQXXH���'


Z�j����[��O�>d``@k�����T���O�<��3g������P||<}��7a�������k��dee���M�6���e�ZQQ��_��C��Ai������-[��Q'dee���
}�����-..�+V����;V��1;;�V�\I�����EZ�h#�����t��%5j������;�;w��B!���Qpp0������}���
�dbb"�`�b��C��w��L�����T233��������rvv&###��e��U`DDyyyQ�f�����>,�_���O7n�6m���9T�2�����������i��	�` IDAT�����l������3���������L�c*ea���'j��{��
2�V'�deeQ`` q82d=|�P|[tt4��3�tuu�M�64g��t����I"�^�zE{�����G������������������#G��������5���~�:�n���
�<����jm����x��C�?>�Q�Kxx8������-_�\��*//��9Bnnn���J�
�M�6QLL�TfF�������H��u#2d�>}Z��799����C���?Rbb��sH������>X��u��!�w��GD%�k�.\�v
W�^e:J�q��l��QQQ��N^^v���������>>>;v,���!p��=���"44O�>E�v���}{XYY���666h��5j��c��������$$$���(**B�>}���777��������'O����/������W��q��I������K��g���	&�M�6����?��H
a��q(((������A�#}���c��5

��a�0a�����A�HMM�������=z������5�������:�H$��w����.��W�^!..�=���9\\\�455���p�������4i���SSS�T�#..}����}�0r�H�����P�~}�_�^fc*ea�����3gb��qLG�3

���[��z%%%�|�2���q��m���`��qpss�R���GDD���*����������*��������������������Cyy9Z�l	+++�/�N�:�C�h�����=��+Wp��Q���a��q���A�����{k��.^��N�:�������G����C�}�6�Q�f��%�p�>|


��H���oq��Q���a���6l�ol_�z���H��W�^!11"�����p8�����r�x<�x<��|���B]]���������
lmm��W/
�3g����h��=����������Gb���1|�p\�r={�d:K�4���������T�����AWW������.�q������������%z���l�8q�����G�`ii)�)������*������������x����P(D��M����#��&M��'
���k�����4h����?~<���W��..��n��!;;[�g��IFF��������H��3g������H���3G*"##q��1\�~���prr��������m[4n�X|_�P���\���@\�6h�jjjPSS���*����(N���c���",,111h��
<==1a�����<ys��ELLLLL���R ����t�:t� �1����~�:/^���X���9�������S�NIm���"��aaa

��'O��*666������Y�[---�g��|>����3�3r�\$&&BMMM�K���vvv5^j�-{�����7q���]�U{�����{7�����"Q������;�^�Zgf�RRR��gXX222��U+�����5����op�����Y3�T� --���A>|�����h��������ec��y��>���[���U���B���"??M�6���JW�.X�"��7of:J�������YYY�_��L�,//Grr2^�z%�����;�lmE+��3���������c����:k�jc��1���'����:�ff��mmm�\���(SRR�������K��������			��������hjj�gl���add$~�\�Z��Oy����r��������og:KA����������;w��+0x�`���9Dccc��y���c:�\222b>r������c����t������������^X����N�:a������a:��U��V��������u�#7yS�^=���>d:�\�����O�`kk�t��h��^�|�t��u�>���`��eI���N�8�9s�����L�a���!�$���������nT>����`��_�����s�����'���8w�>}��O�>���]�v���666�r�2O�p�\���W��f������>|��onn���||��	:::N'[�>}��I�p���n5��ONNN�3g&N��{���o�XrG�fl�\.lll�v�'O����o����]���� <y��'O��8^^^���@bbb�[�����cX�n^�z%�\�amm��U�r����f:F���|>|[�nE`` """�u233������o��!������ �T�����?���a���LGa)�%K��������QX�/(]a+��������pww����� ��y�3g�������r���\�zo��Attt���p����y���:��`gl��h��P(DNNN�8�u��!..�Z��BBB�����?

add��&��k�����2�){��1��;�
60���6l��� ,[�L�����[�VSXXrss�8}���.��-[$��I�&�r�
v���#F��:L������o!_�%$$���������,Z��F���H$o��q�

ahh���d����7oFiii�����myy9�O���k���|KZ0o�<����
�L�a���j�mZZ<==�r��e�Z���6I������4544����>�e��L��+���000`:F�}�MSo�lll���/c���h��)<==1e�L�:jjj5�����B����6l��~���(�:b��E8�<8����3�%G��}]]��K�R��@]]]�cH�Y��RWW��c:��),,����.�W�<<<0k�,$''���'�4i~����z1UWWGaa��J_VVV�Z��{���yX2��Q#l��
����������#��MCHH#c+��-������> &&F�����������?~DNNrrr�j�*qg��+W����O������lmm��A����;���#K(�������Fvv6�����[�Jy"##q������_�~HNN���CaffV�����"""***_�+i�\ HSaa!#�^�Qyy9����y�fXZZb�����Evv6Z�l�i������F�j+��v���:t(:u��tV��o_���k��e�v���<y�;v02�R�����xHLLDvv6���$E"Q�17o����|,]�T\����!99����/��];�����u��?��g��a��A�������|^7X�-&&����
����###������
�B!�?���8::~��%"���/�����3�:��)r� M5}~fee�����7:(//������Q#�7�R�����K�.���Wh��:u��1c�|1�GD�z�*n��������`����������
|>/^Dll,�����M2-Z���1����p�������
�3��Y��n������[�<y9998p����c�����������t����1�,�l��������S��uk���V�����)�C���R���m����q����	���}q��c�u������+����J***���[�����#�w�^������Q�F����/�;v,EFFV����g	u�����J���+�={V*�Vd�������j�?99�V�\Ifff������������i��4`��}��=KFFFt��i""����1c�P��})''��u��G�V����b""z����)SH(~����+_<�s[dd$�o��>L���T\\L��_'{{{


����������I�&QZZ�|���u����������u+
<X�����~u�����Q���k�y��O?��3��������G�F�b:K�={�z�����J��V(�aC�OBkjjVy[��CC�/>&���Gqq��j��!'//eee������m�������������WR5j���2�\[�	���l��%�.]�3f�<+�y�ft��
�[�o�������,X���G���<x� ����f��5p��	?~M�6t��6l����{�n�|�o�����+f������i��0`.^��������3����G����E����?`ll,�-22���k��W���xlVV���7i���a4l����5z�q��I2�U�-Y�w������t�bbb]�T������nZrpp��k��5�j�%255E�n���/��E��:u*8���T�7��)����=�MR_���
>�_��U�������G��M���3������?�q���6mZ��5k��
��={��gLLL��]�/�����7���$��1���3f��YZZ�W�^���E^^��������O��t��J�o��%�
�����f���}�j����)��v���������ys����8MMM���J�KK����������n�o�K�<����K���AFF�����O?������U^C��[�~]m�p������egg#66�Z����W���ys!55�����������|��z���x��b-ym��|��uvvvUn����>~�������v��e@�v�*�WEE.\@@@@�cWZ��=�y����s�������(,`����~��R����>D���ht����J�yLMMM!7T���>>��;w����������G�n�:4o�3g�d:"�+d��o����������|��W�000����%%%����q��%����K�.����h����S�D"���Vy���7&&���w�����JYeI����w����;[��:::�<y26n��0�����B���666�eP��V�glk+>>G���u����WWW���b�������;��r��o���>������w��u�z�>������		A�.]|�e�4i�wg���,u�X�]q_


��W|>D�H�hEz����b��}8�<�QX�J`kk�e��}��	K9ihh���c�fP��zzz���d:�T������_lni��F�!�e5UZZ������+8rss%zMkkk�������Un�+))����/���,.j|��
CAA�wej��-�6m����*�S�4�s��>�l,,, �������J��$-77��A����'all,�m,Vm4o�#F���FgK���m��������%���o�V��o=����������J_OII��M�����{�0v��Z�+	III�����������III�f����`�������+_��������G�i��!���[�>/_����]_�z�����
������_��*�p��
8::���I������N���ug��%�>�!11R��$���s��e:��US�N��!��M,VM)Uakmm-��6::������{�����s���������S������w�B[[�
��q�|�����?�/_mmm����������q��-��������k����^���mmm����pww�@ @�z�`ii���2x{{c��=

���#��S'�����{g�����2��F�}���������E��w��X�h��T�
'N�����x}n��]Q^^.^�[��?����#���|�DV�n�{���Z�
]�v���o��a����D8r�H��3f����V�^�/^T�������p```����$p�\X[[K������_�[��X����	�q��QXuP=����% 22'N���-�*>����GAA^�z555XZZ�q��L���a����������[X�x1����u���h���())A�f�`cc//�/Z_���c��
F���agg������b��E�5�YYY������S��3�����)S@D0`:t����G����'OFBB


��Y3���a��������6{{{����^��/_������}}}������_|�"���m���[1d��n�III����/�������^\SS��=�����`���HOOGPP�QX�*m��<`���dN�
���\�������U�W�L�2vvv�7o�Q�NJJ
��m���|�n�JJJ�����}�Bdgg#11������f���Q^^.���D���$�x<���W������M�6R-h ##��xR������{�n���1���Rvv6Z�l���_�����8�:D��"hii���O�>���#�q����(�?��r�E�
�HKK�j����������o���^�hjJ��]�����uk�/j###QXXggg���X����+^�6{�l�����~����

e:F��������/N�b}V�~}8::���{LGa�������`��'N`���5:���b����q��E�c�d����f�����)JY����1�N�s��u����-��)����b����_=����Gx���DN4d�����/^D�&M�����mDD�\�k�k�8`���[�����"<~�}��a:�7�������R�aK�ikk�G��v��QXR�EI�(]a��E�������LG�sn��
�c���]�"##)))LGa���{�`ee%�Vb�p��M����]��R(��
c�#��4��t�-�y]OUM�Y����#�[�nLG�k�5B�^�p��m�������;r���-7o�D������b����Cq���o��Rl���������Q�,l'N��S�N��d(88&L@��J�hC*F���'O2�������9��#G2��"""��_?���X5bff}}���B�R���������9�Q(iakgg�V�ZUy�(K����p��)x{{3E!�3>��$1���������W/��|���waaa!>
��R$NNNl7%&W����ooo3�N�v�����t�����������LG�����1q�D��!	�������X��b[�&O�k%.l���;w�����LGQz{�����S���P���q���c�i���8��B(���#t����,�wqrrBDDD"�QXR����3CLi[}}}L�07nd:�R���Ett4~��G��(����Ol��>}vvv���f:�7�����Y
���
�7F\\�QXR��Ehhh0CLi[X�h�=���t��(��+Wb���PWWg:�Bi��!����n�:���I"��6mB@@�Q���E���ez�0�%I���C�����������.lMMM1|�pl����(J�����{�.f���t�4k�,DDD���p��9�B����*�?������f�����/_�d:�P���<k��~���1E�,Y�����p8LGQH�9s&6m��t�:g��
D������6�Rx���x���1Xu��������
&L�����?LGQ*�n����1�|��(��s����kHHH`:J�q�����b��qLG������GX
����]c��	�/l`��u�w��_��t�PRR���g��_���&�q���.f���y��1�N(++����d��9L����h��5�1X�Z���Cjj*
���Rru�������������@�t��n�:b��1LGQ
K�.�����t��u�V���b���LG�>����v�K�5k�����r�LGaIH||<���N�����&&&X�z5�QZ\\~��W������"!��5����1{�l��|��(���T�[����S���������2���5SSS��E%��={�����(_P�Ww	�W��9�}����?�d:�B��������e�`cc�t�2r�H�m�k��e:���;w.&M��:0���e,�abb���T7n�����\.��3�-����������������h����������m��]�v!**��(J���3�����+��R#�_�����1X,�066f;)����c���L���:U���!C0z�h���
�L�Q'N�@hh(>�.A�KKKl���F�BNN�q�FRR�O��C�)�f����l���,�D��JJ���#""���c:�W���6o�������b���8u�ttt�����M����{c��I "��(����3s�����;�qj���044d:�%&&&������
������Uu��m��	�]��7n�G����/_b���� IDAT��!��};�w��t�:a��=x��5v���t�uuu,Y���(�%33L�`�$������L�`���70`��cTI�V������]�'''���a���LG�;iii4h/^���jjj8q����;;;���0I!�������E�
���]233����tK"TUU��/
����'O2�Jur������\������sL��+���������nc@����Q�F!66��8
���+�?>�\����gee�3�,�U\\���0���������-��Cpp0�������!�@t����(U���-t��/^��i���~������$������X�f
�q���% d����G����'O�D������x<�������t�����a�������\n��g���M�6�v��\�Be}���
V�^-�����R�rrr���w1`�$%%a���LGb����1p�@L�:��/g:N�������T4
=�(qqq������{�v�nu}�����h��1�QX��bdd��w�"88���8|�0������#6{����a����R2la�_m���_��������a��mr�xX�n����c�b����2e
�qX��O�>���	7o����9�����G�0d��\�R)�{��xPSSc:�Uk���000���D"F��C����LGc)!��Kf���9�����O��o��u��?�P����c��q8r�[���-[�`������'�<y�t�s��8�����3��#�M�6e:�%�����e�P�^=��1�-jYRS��$�A__���X�z5��~�9��XR���ooodgg�������`:�
.���\\\p��i���*
G�����q��q�=	�{��-K�L�>����LGa)1v��+6l���������1c�����t,��x�"��k<|��-j��I�p��A�=���c:��B!�,Y�����yS��Z�-lY��^�z�;w.5j�t�c�o4hbcc���[[[�={��H���<~~~��?�o��nPQ ��Ghh(6o���#G"//��H2���������x��!��$qla�b���"���.E���7����???8p;v�@�����Vc�7n��-[���?����PUUe:�;t��111�6mq��i�o���X2�	&`�����i���)PQQa:�Um���HJJ��W��������x<�x<"??���h��!8TUU���555������VVV���F�f���vX�0z�hL�0A!�X�#E*�VTT���Wc��9r$-Zkkk�c�+>��}��a��������;`gg�t,�����K�,��y�0�|4i���HR����%K�����

���'��j���			�r����#


PPP>����L����U�V������TUU��p��ukX[[CGG��o�U�%$$ ,,���������o���XYY�e��������*TUU����&M����D�<������Gjj*������T4o�m����������� ��S�Y~~>������ccc���+��������e�����"00L��B~~>v���m������/F��}�������8���"==;w�T���DD����o_l��&&&L��1�������������EJJ
���`mm
CCC����g�TUU��qc��|������������OHHH��7o���	kkk������	���h����*KI#$$W�^Ehh(�|>���t��
VVV�p8����			����%%%������GCKKK��::���#,,��(�����������c��������	0v�XFgQ�B!n�����`\�t	���X�x1�v��X&�l�=�����w����i�����U+O�>���233�k�.���1���>�������(�������;w�����]�///��7o��r����������022����������.g`�
!""G���3g`mm��#G���:t@�
d�#>>aaa�t�"""0h� ���`���f4)8p <==���?3�z�UkEEEt��q4h������';v�222d2�@ ���0
 ###����U�VQrr�L�g����\���#555�2e
%$$0��?~L������Ik��!�@�t�j{��
�X��,--����|}}�������-��KJJ���{�b�
���ihh����)<<��B���g)���B��e������)R||<����(--�6n�Hm��!===Z�p!}����XJ)''�TTT(33��(������A[�n��}�R��M����f��M������d�D�#77�"""h��5���J***dccC~~~)����RSSi��9���N����g��1�_��{����G:::�r�J���e:R��B:s��������h��	t��-*//g4����K�R��-����V�ZE999�fb����\Z�r%���R�~���?���7E111��?���:��=�RRR���T���G���c:F��K����<@XX������s����w}ZYYAGGjjj������:TTTPVV��������\�}�\.�^�BNN�����W/8;;���E!t�����G������{7�������1c�@[[��h�������cFNN0}�t�8N�����������������e'"���_��};BCC1c����C__��h,9����n�:������D�.]��UmIII��aN�8�1c�`�����E	puu�?��P'��������������"!!A�)$77|>���������TUU���	333X[[�������nqDDx��RSS+�b��P���b'�������_�
���/^Dpp0����`���puu��F�����q��������ooo0
�B�H��b������B`` ��������n�:���`���X�t)tuu���b���g�����;b��5h��
��������z�j�:u
��-��Y��5E�D"�;{�������`�:�����?~,.��\.6l�V�ZUj�R����|>_\��x<�y���5���lll`mm��={�k��J�bJYedd���8s�bcc�mu\\\���$���999Ghh(BCC�����={b���=z4455%:�4���`���X�~���x����+V����X�v-~��G�(�Y�������g�������_1j�(�#ILll���������G�#�d�-l����K�.����e�s���T��!,,O�>����w�[[[�R���L
�x��-���+�|����Cjj*z��ggg����K�.�W������������p�\�����(,,�~��Y�X����
]]]XYY����7o��cU��	

EXX^�x�������Z����:::�^�jjj�����Kg>|� �GY�?++�:u���;\\\��{w�;U+//��-��C�������@�8���{���E����{�n�<��Ua���X�lf�����@�<A(b��}X�t)����q�F��7��6������_c���x��=�9����Ku�G�!88'N�������������{K��`U����E����������������������yXX>|�����E������������7i�EEE�e,M��YT��_������3�����G�m����*�\.���������-**��uuu��}}}XZZ��[YYa������������S��?��>>>�����������2l���W���Y��b�
��qb�Vnn.&O�.����O�m��LG����t�����x8u��������&F��)���t�?>����[�HkWann.�[���������������X�!
���;4q�DRWW��={��������L�����n��A�&M"�p8���I��o���X***��"��RRR����4k�,�����M�R��}i��m�j�"
)''��]�-[Fs������RVVF�/&mmm:�<�q�.99��w�����{���$,**����i��	TXX�t�*//�e������'O2�%Ela+a�
"GGG��{7�����������LW�\��8����h�"���$OOO�~�:���������`rtt$SSS��c�D
6E���s�?>S���i��%���>��c�h�����Y3����S�NQqq�T���aM�6M�cH������:w�L���L�����2Z�l�����k�������� ������ ��0����dhhH.�H�M��a[)�s��o����{G�������Z]/##������I�?.���u��-���7����\�{��urrr"mmm�1c=x���H���G�����K�.���C+V��Z�����+��mTT�������������C�6mb:
����_O�t����J���4i�$*++c:K���V�222�i��TVVFw��!;;;*((��u���i�����E'NT��������G���daaAW�^e:�T�D"
		!GGG233�m���mA���S���&MMM������4�^��y�x�b�^SZBCCIKK�~��w��0.11�,,,���O�����N$�����e����r��#Wrrr�W�^���A|>��8,	b[077��w�}��OLLu�������������j��yxx(������#����C�Qii)�������S|�/_.�%
#F��H�Z�t�������g�2En���S���i��	
�<f}�����v��Qzz:�q����!C�P�=(//��8rA ����B������20l�0�?j�j������puu�����4����/^���������{��$?~��)S0l�0��1qqq�8q��Z�����=�=���H����m���q�F��+++	$��`����r�
F��t�add���0���`��(--e:�|}}���+��{FFFL��K��5����ajj�a��A 0�q�/_F��M�0&�+���������I����~��7o�K�.��o_�,,o���������S����9p������I�(++��8�&�����dhhH�F��>T�����t��M"����I�&r�q��3gHGG��>}�t�UTTD���4v�XvY��[�d	YZZ���l]VZZJ��C���5��}�v�c�
[�����;m���Z�������Wg>�+((��c�R��-)22��85���O^^^diiI���c:�������������BCC�����b���#"���S��}��VBCC����_��t����O;v�3f0�U���w����R.��&>�O=z�P��-����I***
���-le$::�8eddTy�HD�-"������������U%dk�l)�i��nlYR��eb�3���$��0$�Ge	��l	I�ED�P������~��Tt��s�N����������^�N��}����]�zU�����]����2;v��Q*%""�u���
>��k��T���LUU�-Y��R�����1���������=bjjj�����(5�������[�n�Q�7������Z�Y-G�����������-[��a��q������)S�0GG�r+,,d�'Of;v���`5��[���������?SVVf�w��:��$$$0��o�.
����n���444�r1������%�E�4KHH`��7g'O��:
��^�x�TUU��+W��R������M���� ��H\���e�"�
[	���`m��e,����<6r�Hfff�>|��Q:����S��uk���*��h�]��iii�pE�������Y�N�*����+fii��v�����/	'�1>�����������Rc3�u�Z�����������\G�	�N�b��7�U�I��s�ijj���GZA�TTTp��1��7w��������yyy

���:�)����!n����W�b���`�q	���������t����H��Q#xzzb������@\\\�c������{4k��f�� ���[���������RcYYYa���ppp���[�x14h�U�VqE&�=�����#�|>�q$"33��/�1+�|O&-C-r��1��;W�^���������'O�~��\G�:��������8/B���������x\�x��7�4�4��e6n���/���D�������022B��-��{w���������_�����_~AXX�����S����000�_��u�Z�����<y2>|�-ZpGf����W�^;v,�,Y�u"*l9��_���s����t������$���}���{c��YX�p!'c�2e
�={��/BII������K�,Ahh(���c<o����{�p��)���k���,kNN

�i�&�;���$55]�v����aoo�u�Z����022��M�0j�(�������w�����D��m��C*�
[���?��]Chh(TTT��#���O���c���o����x�"BCC���*�����]��a���u�[�.����}mmm	��?.���Oq��E�2�"ooo�]����t�.A��/��{�p����������'�t��QH%Qa���;wb��m�u�455��Sc���������?z��-�vw��	��}�Z��X�5���O�<���������-lmm�b�
���
��=C�=NCj��������#���o2��8���������������qj�'N`��Ex���D&����a���

��`�a���HJJ���WQ�^=�#	0�`kk�~��a���\��IO�>E�^����C�k���82�_�~���7��Y�u����a���x��)7n�u��*�eggc�����q#�U4v�X������Y�+%$%%a�������������������q:��<'N�@JJ
gc�k��;b���X�h�Qd���������(���������}��q�T��J�������q��I���hyyy077�����>Daee�~��I]�&�^�z�=z���c����:c���3���888pG�eff�m��		���1�qd���-�
�9s�p���~�:&M����4j���8"���%����VB>�{��a���\G�����p��q�������bi����:���NNNHII�:��������#GrE�)++��_���;�Qd���w��S�r�V���/tttp��a���Dqq1z����7orE���V���```�`��\��nnn@hh(���#�����`��Qx���Y
...HMM���/�9LMM1k�,L�4���Ezz:��o���p���qG�<�{����K��R����c��9��������?,@ll,����>N�z5Rj��������V�-Z���4�^A������T�V����������Y���/���ptt�,Cm����)S�`��
\G�9O�<��������u�Zi��APRR������Rm;v��������������_?<~����;e��k�0n�8���BMM������������d�^�N�8���O�>E�&M$����Cakk��s�J����������������iS����E����a���\G������3g�   ��(UV��arr�L����V�,,,0z�h��7��(2k��������m��u���d#((�V�������W��h�>|���i�c���c��Q�>}:�QdBqq1Z�n
�����8�VFFZ�l�����Y5}�t(((`���\G*l����k�<y�L���F��?G��]--�*�g���PVV�=�E,..���������GX;v�@`` ��=+�6�������}�p��
���������"..N�s
��F�ss��|`FFttt���C�o���8bA�Z����
�-��V���o��C�V� MLL���/�)���1b�l�"�v������$�6��1b=z���x���oooL�8��Z)����C�q�J�������lQP������a��!x��%�����#�bbb`nn�/^Ti�������u�b��]bHG`bb���hhh������� IDATO��O�>HII�KM�8������+��R����A]]�?F�6m��S�@KK7o����!�q����C��__����[1Y�n,X@E���_�~U�T�����G���Ib��C���_b�<0`�*j96l��=�FZ��s�[���VJ4l�����v��Q���[7�.j*l�"))	������_��R�,X�������y��o��#�CC��-[�]�v!77W�m���F�������EDD�����R���Y���� ((���T�����7�
eee���*�����Mqq1�9B!��Kt��~~~bm����������k;��TTT`ddD��)00�
[)��o_	��B��
[18r�MZ��������]���\��&M����L��H	'''�~>Uq��}())�]�vbm�T���-�lU�������X[[s�|E__


����:
��"v��]ddd�_�~\G��&N�___���T�x�i,Y�y�&^�~-�6BBB��V�Pa[=aaa������:�Q�7����n���V��=�	&��}�k�6m��k���Z�4++g������%��@��M1`��8qBlmDGG�R�[�nx��)�����O��S�N\� �022BLL�1�7���+W�`���\���
��W������/�k��h���R�c���8���8������D8������Crr2�Qj$z?�����1q��*?___qqq"L$z/_������!QT��PJJ
^�zsss���j�����qAAA�������������b�)���3��o�			����������:F��cTZnn.����u�V,[�7o���c\x��^�zU�����v����w��1$�
[
D���!''�u�Z������?,*h�17TUUadd�[�n���)))���C�V�D~���������������P���PH���c������G?~���x��I�����x��3>|��nB�6�EEEX�~�Pw�tuu����O�>�%ou��^^^�?>�Q$�
[���C�z�`ii��^���$%%Q�:G�5�(>>����W����]Y�5���?v���#Fp�C�n������W��T�VA^^^�~
]]]��T��������K�
��$�������3���	MMM$&&�O�>��y3


*}��
BGGGj������<xp�z���"t��
Z�EJ��� 44������`aaA���������E~�>@SSS�����
\\\��aC�����K�������#--MDij���4j��F�`��]������111����a����>��a�0v�X$%%a��1B�SMM
?~S����������x�b��H�"���������Vu5���1�>}Z�����055�`�������cjj������H���������H�Y��?��C*���-�D�Gvv6��!S������c���HLL���1i�$L�6�J;����{�n�����bhM*IHH@�f�����u���~��y^^^Uz���>����+w����8>��1k���o�g��"=������+�o�^d��x��=�]����4���a��(**���4h�q���Z?���78{�,bcc��A���`��1��|>��������	�����������HKK���

���o�^�z������������#//������Gbb"�
�Jg��kNLL��c��~�z@xx����M�������gi���v999T��PQQ8���7�C�X�f
"""����6m�`����7o�PkK�{;77[�n����Q8A����r�LLn�����t�����?�D���ErnQg���V���F�:u����l����5mB�.]�$�����+��6''G�^���?����8p�^�z��c�b��
�2e
��/
n�������~��;������L��1������/�6m���b�x����<x�f��	
���BA����ct����7���1u�TDEEa����7o��[W*��
����
6�q�����8v�,X333Aa[���}��_����lmm�������X�-Z�s����@�;�^�?�*���p��e���CMM
C�E�^�D�Z�����3g� ""<�:u��!C�;)���������CZZ���1f��R=�W�\���+���1o�<�8q?~������������x��uk��J�{�������F�>}���
FDb���l��"9�����k���2�>}�$�������Y�v���g�*u�(s���1WWW���{�c���gc��e�1VXX��������P�����v�Z���
����*��-��;�0��{���l��-"=������,Y"��6l�����'�w��1��������3c������u��m���z^nn.k��9[�`A�����0l���e�:z�(�LMM����K=��o_��qc���!�Zff&k��KMM-s��c�����*e��k�����"""X��m���������O�>�>>11��]�����0���'����1999���R��>}�iii�S�N1����3f���f?~,u��q�����x<c����o�-Z�)S�0>�_&������{,,,�u���yyy���l�����K����;p�@����������M�4��y��1����O���y�6233��u�V6h� ���������r�����sss�9D���VD��cG���{�����;bbbp��q���GJ�(���3����:��9��Y2[���S���,5[u��q�����={�:��������U���eee���U9�8zFJ�Y����uuu\�~�=B�6m��wo������U�G�2����Ev�"�����y��*z�#%���Y3@TT����3g�a���>}z��5i���={�q�F���e�Be&�hjj�����cFFF�~�:��G��O�PXX�}����?�(u���C���Z��?z��T�^=����L��s�6m���a�������y�fl��JJJ���E�6m���w��eF�
PVV�����];���a�����6r��qb���^�z���NNN���f��]�����K���;v����������G�`hhEEEA^����~���������������1C����~����jU��V�^=�UO���1���c�
��Hr�hu�(ENq�V-o}���4�yU�����u+���O�y����C����x�b899�:����������_���+W���s���222|�����K���k����#G��o�!??#G�Dvv6LLL�d��r��qttDdd$6m��}��a���5j�N�Z���L��oC��NHH��7o���+���!���


�������+������m��1����R�Z�l���?��V�.]�|�I�&P����uk���c���h���������Err2��'XK��Eq��#4	�j��~���ENNQQQ�:*s!T�wC[[�;wF���Kkii	�K)
���+�����[��C����f�*�w}��EHOO/s���M���/�6mZ����=���O�2gee��)C=�""�mll8]��d�jAA�/_���T�Z�
��M��r7�}��q�����`��eh��.\����9sF�c��sg�����o��
azT*����~�O?����<���c��a4hP��g���4EEE<�������(����h_~���Zb��eB����T�c����={�-���Gq��8p
6�����V����fQ����\PTT���k������}}!���yyy<z�H�xvv6� Dq�����+W��K�.�+611App0n��%�{t��y_�>~�q��?�l�E�B������"B�W�G\�USSS�|]�KBU�v��������k���\�6���lmm�������	?�����Q133+u��=*��*��������UPP��9����d]\


���W�����Y3xyya���GXX�9www�l�RpAZ��U��"&&����.����j��;R�EKU.�����o�>�={�7����`��(n�GFF������%�<x�A�!))Ip���^SzoK*lE���Rdd$������cc�.EU�����g�~o�����lVq�V-o�8���g�2����@�={VP�V�GE���#����p�G__


x��%
��A�2�����m�PLL>www(**�o�����//^+++���`����x��I�=FFF�:�>��Fj��k������EFF��;'X<77�&M�r���7�[�����URRB�:u���[����E�m�CclED�e�J���b���X�d	Z�j4h��Fbbb����x����011���W�h�"x{{c���pqq�-*Y����X�re��:9��:p�@|�����G�:u���*�m���B||<<<<���VT8����|'����|����P�������eI���������F�~�0~�x�9sF�#��zT$q+�<�(l������J��u�x�bddd�����c��/�vK����e6�h��F���X36o����]KdffBYY���HKKLr#�������?������k�������Y�oo�R�|��

BVVV�2CNN)))S2F�db���
��o����
���x<�N\������"I�����c�e�"R�~}�wQ���3������
0ZZZ>|8<==��m,��x��2�5cbb���&8�d�h�V����Yj,QXX�m�����%K�l�2��6+������B}OE=W���Z���������i���n��G��B!55��u�����������c���5jT��W$&&��^_���S���x��Y�1�?R�z*�pX�t),--�t�R�~���c��G�J] ������e�UR��W��<���>�z�
�6m*s��70v��je�����9������o����$������
W� ������f����G����P��_����%�;���]�p�L�Je��_���HNNFDDD�����333��*�7o�/w�3{�l�]t!11���b9e���c��E�f�&T��HUz�~��w���c���e>�[�h�����y�03Y��-Z�m���6��D1[��[D�\P[��������R�i%��R����"��-�V�Z������k������=���UUU,]�vvv��������������	��������}�v899!116l�}������e�����m�����N�����?c���PUU��}�`oo�������+������������s����YYY�S�:t����B899a��=8p�F�	��qe3V�5�000��m�p��A,X��'O����`Lxe��(U������8��S��a.�z�����"�����033���o|��/��)����o���?��gO��5���)�~��7�����.���W<�������K����kPQQ�u���D(((�|E$a�y�{����U�8� u8Y=W���[���7o����W����16x��R|���`���,''���?���`/_�d�1�����Z��{*Z4[��U�*�V�bs��-���g�2+++���}�v�Wx���k�
7�1b�`c������U����<��eK���Qj�~uuuV�~}VXXX����o3�o���1�,X ��W&���'�N�>-����sYrrr�����g�2KK�j��[]�ta���"?����G�XQQ�X�a����|���;����������<y����%������������B?W]]�����$Gm3c��~��J{��=fgg�������*k��%�����o_���u��1}}}6m�4�m�66a����������{��
<��l��m�������M�4���������qcfaa��m����y����Y�6m���������X����r�J��[7����V�Z�������������l��-L[[���9�m�������U�VU��%
���gb;eL�<���*�Ma{_�~�w���y�����f&��f�V%��Y�%;;���WwB��*�3r��5,]�������-�q	www���O���������{���������'.\�����R[HV�G�{���
=r�H������&]��p�s�:Qn�#
6�Z���Tf����:c��M��}��������m��4Om���_�������W�\����������c���x��9rss��o�����Y3�?iiiHHH���<&N�(�����	�]_�|��6���eh��5k�z�j<�999X�|�w�-��[��������c���B}fU�w"bcc���+��G���VD����*�J&�1!�
3��N�:"�-Z���f���lA���b(�����l�2<~�Xp;���e�x��"���@�~�`ii��;���044�"�����/_��-[BSSg��E~~>"""��F?x� �N���C�b��9PQQ��[�0e�L�0���G���1z�h<z����KnC����������+"�����������(����|<uma`` �(+s!���^������@0GX���������]�h\]]����YiD���hjj
�#���
��k����J��f�����			HNNF���������Q��)U�)lVqy���`���j�
������UZ�_���Z�h��~�
�>}��g�0i��
���������NNN�������Pk	��W���U+���k���pqq�yI���tD*�W�^������PHH���;��7p��]=z����M===����?EEE�x�b����=Z�[*�LVQ�6gU��Clll�W�������CRR���������s���.�UTT`jjZ��
uuu�������������P�3}��6���Z@|��z����/_�l�_R=�����hX�������7o��:
�Jrr2��}[��A�v��!,_��.v�A���Te������+W���w���a�`���?af�
;[��%���S���VPP����
�a�����%)%���i*����F��W�^���p>�����S�m5���"((���+��_���%6l�I������Y�8i[��P100@||�P�Y������������!C��Y3������~���-�����O������B���S���=�������2dtuu���shhh��|��-�L����8�E/^����!''W��@������g����Q������C�����AXyyyHII���w�n����)������
>��/^�m|���
������(����	

����H{�k#�2�6nq}'�n��b�WS�a��-$!�1())����U7�C||<rrr��cG4n�O�<Aqq1������
99�2�+�idd��[�%�v�����U�)l������_�Ua��������w�^��Ftt4v��999��WEEE�����5kJ�� �����W/���������>|8�����^#�={67n\�������������$�
�;���h����=+��H���P�:u��K���W���S�N������.�PQ��jNQ�_Y�������V�^�$2�X��������!���������������������^l��������z�*�Qj<EEE������puu�:N���
�����(���-B6664�OJ������-,,������J0)$��x������k�b/^D�����kW���'''z?K	ooo8;;WyM"^T�����
��Q�eff���G������z��I28,�����g�������4ooo��B�EC�EBBB���D�x<���0~�x���
Pa+BHLL��D���]�V8q�D�#"YO�>E^^�t�"�vttt`bb��C������K���_�������@��r���FFF�����m�&��V����`nnN�8V���vvv@qq�R��.]B��}%2�w����m��/�&mv��
;;;�l�L���I�������|���Z�������D�����0i�$H����
[2d�U�0 IDATN�:�u�Z������C�������h��BBB$��������q�$����x<^���������;�|�r����^�z�}��8t��Qj���0������Ibm�x<,^�[�l�l����
[stt���W�q�
���z����c���C�$���'HNN���%�^�z��x�b�[�N"�`������LMM��"��.]
q��Y�v-����&M�H����7�]�v���_$�fMG���5k����ncK����NNN�������2��������1c��Q#��9q�D�{���_�X��U~~>�n�J��b4p�@���J�r��.22w�����3%����/�y�fl��]bm�*l���e�Fnn.��9�	&T�9:t���������@QQ�;&��x��A,\�+V����b�s�Nt�����\G�i���;��������Rk����puu������tuu��i�`ll,�6e�b0l�0���!::��(����'��K�7��9s&�l�B���������������9s&>�OOO��][����������������sL%�F�999���?\G�����9s�H�MDFFb���kSVPa+�7����
www���|>7n���~�������'�!�l�����e��q��y����k�.,Y�������9s0a������zZZ��?���'���A����4>�OOOhjjb��HII�:�L+**��9s�a����J����h����PPP�X����n*�HOOG�v�p��=���qG��8q��'���������{����;w��!9}�4���<y�D"�|U���rrr��ogd���W������X������@�����gO>����_�vr�
�����b�
���a������AAA�����'�6n����O#,,���]D����9s��)S��!����Y�����c��|���<��E$�`D����>|��,55�������`������l��C�2?____fll�������+Yvv6G	k���@fff���o��;��|>c����t����9N(�������2����:
�b���k������"�������.+**��yv���LMMD4������+,,�:
c���'O2MMM����u���������K}����������6h� ��ys�{�n�y��/_f666LSS������9�����C�,33�������3{{{6w�\��!Q��ikkc���X�p!�QdV^^/^�5k��^�z�������'##���������"����%K�`���Rs���C�����i��j����C��;��A���!//���8q�<###:t�vQ������'��{wL�6
��
CBB\\\��A�2�O�<fff�����AZ��~�z���`���\G!�����u����E������(2i�������Loc_n#�Y��u���=y����gdd��72uuu����|||���*{������
�g�f\�(�����]�2www���X�?f��������e��{�n��3��G��U+�m�6���#��R/77������o��u���yyy��C[���l�������#���CHHSQQa111\G!U@��9r��o���x<�����/_2���S��v���Y�n������sg��}����l��LII�
8���yS���I�����%�:d��G�X��M������R�������._��u�'--������[�~���{��-[�����k�X�~����[�j{���8�J���H6k�,����,--��s���P��G�1ZM���g��������(��hU	`��o�������U���#3
cccl��A������PPP���5��oEEE|��	�����G�mmm���/�<yr�U+>|��N�:a���:t��_�L��x���'�L���s�r�B.\����P�m���������k//��.�


t����c����M�6�������6m~���
������8q���GBB���1m�4t���Z���k6o��[�n�E�"J[{�x<����S�N��g���=u������gK�MYF�������W�^�r�J�u�����DEEA^^^����4XYYa���w�^�|���\())A]]���055E�6m�{���8::���?<������o�������/�s��Q��7���000�:�T���5j������'�q����������_�x<L�2NNNBo�"�>���/�����x��`���#!'''�v.\���/#44M�6�ye��������q����	HKK������aoo/�6e��������Y���Yzz:�Qj���h�������S���G�������������������j�'N��-[�>p��6n����i���y�u�U\\�&N������>�,�v�����	���"���[�z5���[������N�8�F��������)���`��?[����l������������YR\\��N�����$>�{��Ql��mS�Q���9;;###����d��.''fff�9s&\]]�=f��}HOO���K��VQQlll`ff�-[�T�\�Ell,,,,p��9�����8BY�d	|||p��e��%���BL�:QQQ

�XO`^^�]�___�;w���2d�����O�����x�s���������F����#���#����6l5j�S�N����?��/���n��555�����a��yx���`cR}T�JXNNz����3gJ��Ci�����
/���#�I��^�~
sss,[�...�>�,KIIA���1{�l��?��8U���������������q�Bnn.���G���K���kEEE		A@@BCC	CCCXYY�O�>���+��k'���|>��=Cdd$"##q��]����m��������
���9�~���b���PPP��S�J
�"_c���8�<�����uk�����.X����k�6������������'�
�u�c���8u�����{u���\�t	+V�I�O�<���5v����S�dee	
������8������s������~����1d�������h��1��rrrp��-������[��������!:u�###�m�ZZZ���B�-��_PP���d$''#))I�/::QQQh��	�v���]��{����������^�����1a��z�
.\������FAA&M����h@[[[���7M�4��$�nm@�-G���1|�p�={���\��z{������[�nq2�+,,�b�4h�5kooo��,Vg����I��a���9��8��������acc�={���U
��}�'O� ::O�<��W�������ddd@YYjjjh��	5j��u�BYY����999����������g|��	***h��5ttt��uk�n�;vD��]��eK�_����|�������h��������Q�����3g���GGG� &T�r�����2e
�_���]�rGjI�����s�4iN�>
[[[�rH�����G���EDD`��1066���k�����1w�\�Z�
���21 //)))���#�������>}c
6���<TTT��I4n���5��[��1�X����8v����������X888������h����30����$�1��'S������Y�-*������g***,44��(�1���;�TTT��'�����?���{��C��u�<�������c����:��eee�q�����[����
6�(**�:��y{{3�j�*�����C��
[)�c����.�%�d���'k��)�z�*�QJ	c��5+�Uhm���fll�&M��
��#v�w�f���l��2[��={��i��988���L��1ILLd={�d666�f�7��\]]Y��-��7��C��
[)����TUU���?�Q��������z�k�r-**�ikk�E�����k�o�f���l��\G��g��������-[������8"����F��Z�h������C$���1��Y3v���*m�[S\�r����������I�Qa+E�\��TTT��}�������B������k�������]III�w������%%%qG����������J�.�N�<������a�Xll,�q�,++��]��)))�E����l�#	f;vd}��a�=�:�H�}��9991555��?��t�NJ����e����]�7778;;#77��H���+++<x��n����.����U�V����t����OsIl���1d�<x���pvv�:g}}}���b��1x����*-##k��A��m���oc���PPP�:�0+++<|��O?�����#==��X�����y�fBII				�>}�LL�$�C���111��G����DEEqI"�����{w���AAA����:R���_�W���#G�������HKK�:�H�8q���h��9<xccc�#qNQQx��tuuamm��C����[\G���7o�t�R�m�QQQ�r�
.\�###��5l���-CTT��y�v��a��EHMM�:�P����i�&�m�����~�:v����j&AAA����4C��u�1)_qq1��u+SVVf;w�������l��9LCC�]�p��8������O��TUU����k��,>>������]�v4��>}����[�Z�h�������kYbb"��XNN;|�0���cM�4a&L`�?�:�bO�>eNNNLAA���5K*���������Y����X����jrXFFk��5;v��Qj*l�\xx8�������:�H����e��l��!,99��8"��������T������4�d�����V�\)���CQQ�|�2�0aSPP`���l���,**Jbc�RRR��c�����������!���lx��9�1c���g666����eeeq�1�X~~>���c��gM�4a#F�`����:V)�����_~a'N�:J�C�m
����?���TTT���S������36`����-���


���[Y�������r�
��~(55�-Z��)))�Q�FI��=i���������1cX�f�X�f������w/���H�����N�>�~��7fdd�������5sssc��?�+!�Yff&;p����b���l����������K4Gnn.�|�2sqqajjj�K�.l��-R�d��-[�����\�&��X
�����"  �g����+�����Ui			pww��S���������I�&\�+�����6m���.\��C�r��ME�>}��{����C6l�.]��;rK�0����c!00QQQx��������===hkkC^^


PQQ���"����O�>!77999����������s������PVV���!~��'�������7��%���+9r.\����S'���������h��������EDD��w�BOO�����	��sg��%j������GHH�t��u�Z�
�(::�6m��s�0q�D,Y�-Z��:V��<y������+V�@�V���%Q�����={���888���	���}��=�?ooo�x�c������}{�g��������8���#55UP�~��	999(((@��M������CCC���������j��-����

E`` ���
UUU��R__�[����j�����
���k��������7o���x����������lll`kkkkk4k�����C���;V�^��'r�V���������;���0d�L�0����_�>�����???x{{#<<3g�����k�&q{��	���q��Q4l���VUUK�|>_��q��u��yvvvpvv�������R�
�$��III����PRR����PQQ�����(.)�k����~�Mp��p�
[����#G����?~��q�0~�x����n]���������=z~~~���������eee���)���q��
\�zAAA��>���`ii��;BOOB/}���,qqq�w�BCC�����������^!��N����[�n�,�e�2���{������x<���akk��WYTT�{��	�
��}m����1c�����m���=Y������P��s�T�G�F���M(**B^^JJJPVVF��u���#�����'���#))	����^��]����Z�7� �B��
[+�>�/�,�����Sf_����R��^�x���X�����x4o�\0���ZZZ�b�S\\�W�^!))I�����Dvv6������(��)))A]]:t�]�!��JT�����HLLD\\\�1P%l^^@II	YYYPj�v��mK�R=i�B!��D���H0[U^^^�K�B!����B!B����W��1�7$7e�B!D��q={����:
���B!��III=z4�m�F=�R��"B!�T�����%����~�z���rPaK!���18::�����p���J)�@!��������w���bT�B!�|��S��e���u����r�*!�B�w(**���zzz\G!?@cl	!�B�L�[B!�"��%�B!2�
[B!�"��%�B!2�
[B!��6m��m���A����%�BH�w��!l��!!!\G!�@�}B!�V�����i�p��Ut����8����B!���+W0u�T�;w��Z@cl	!�R+��}c����c���O?q��
E �BH�
+++8p���:*l	!�R��x<��yvvv\G!"D�-!�B�	4��B!��*l	!�B�L���B!��*l	!�"�������k�c	���B!2)22}���mrk*l	!�"s"""`gg7778::r�H��B�)!!!�������M��u"A��@!�"*������3������Gs�H��B!D&xzzb�����������[B!��UUU\�v
��w�:
�m�K!�Bd
E �B!2�
[B!�"��%�B!2�
[B!��aaa��k�1�����B!5����1`�(**r�H)Z��B!R�1��7b���8s������D���B�Z����6m���p��-���q�H1*l	!�"���}���GC^^���PQQ�:�r�A!�B����3����q�F��O}q����%�B�T***����
[B!�"h�/B!�"��%�B!2�
[B!�p"''�g����/��Bd��B��{�������?����q�����B!S\\�;v���...�x�"455��Ed��A!��HJJ���222p��
s����%�����������eI�"Y��1H��EhQ�(Y��0���}�d2h�1��L�d�3bPe�
cI�t	-�VZN���w�B��9�9�����<����u��y������""�;~�8:w�kkk\�z�E-)��%"""��u��?{{{���caKDDDDZ�K����H+��%""""�������*���;�8q"�����BU["""�[^^V�^�����u���Y�����
�>�DDD$��G�b���h��	.^��?�P�HT���%""�
������sq��M�^�nnn���;["""*���6�����C�P�vm�#�>�DDDT!������;Q),l����H+pW""""�
,l����Xdd$�D"v�
caKDDD�����1c0l�0�����5;Q���%""���^����G���:t��{����CCC��U��""�����g����Ls��A���g�����>z��U��'O���?����~Z�����������k����S4�����<���O�7o^���=���[�C�%�������077/q=::>���CK\/,,��?����g�F���T�8q��5C�N�J\OLL���1a��R�v��WWW��W������O���~���N����	�w�^�zrr2BBB0y��R}���C������ IDAT��Y���/_FVVK\��%���0k��RmU���1b���1s�L������b�"��D����;�j�

6;J���B�����/�(.lSSSa``P����\��s��v�����={�����s$''�������l����h��A��			����J]OKK��G�J]�o�FY�$%%�N�:��ggg#!!��\qqq���+u]"���������d�~��������{��>������S���g����V�zAAA�^Gjdd��>����e��I����i�:���F�>}��R,++FFFx���ZmR��}b��9bG)���HMM�����Q�HKq�-�D�j��g�I5�����@�R\�@D$�����V������l-��m�f9998t�~��gT�V
���;��p���H�$&&b��Mb�(%<<�����1J9x� �����Qi������D����i�&���#((H�XD*�[""-#B�/d�M�2_F[aaa�/�i��b����H$pss��s�J��ATU��1"����XNNj�����\��UK�8TEm�����=zt�m�������h^@��rrr����R{��������C������Uf��)v"��5�DDr*��U&��������20�����n�:�ch��O���_���/v"��[""9���tuuENRR��=q��Y�c���g��A� **
���FLL���1r�H��i�DDZ&''O�<A��-��RBZZ���Jy+���T������X�nnn8~�8LLL0h� |���ptt,�;"z;.E �*!!!3f����;�M��q��������������k�*�Vtt4&M�T�6��=:=z����.]�T�6<�J��+W���#GD�0b�DFF���{��m����H��%"�w�����`���:t(���{ppp��%K0}�tQr"&&7o�DDD������V�v+�a���������add���,[�}����Y��q�F�����>��mSJ�/^�@DD"##���kk���;j�(�d �jX��V�����I�0|����Z�j��k�b���������������.���e��g��K�.���G��uk�5cccl��	��76m��.]�������l?~��?��g�0f�XZZ���3�t��W�kkk����$����wg���D"ALLn�����t��	�{�F���E�GTUp)i��� H$|����>1bd2v��!W������vvv
��������O�z6  ����~�z���M�r�����U�VU��L���l��^^^������3���C|������+������_����rrr��yDD�;]]]�������������W�i�&t��I����
���V���?-Z�(����5j������Y�&�F
�J[�h�3f��l����;�}����m�p��u�~���Uln�w�����c��111��%K��eKL�8k����m���[7��������?`���[�n��/������C$%%����pvv�������1q��J�MD��^�1������[��733��������&M�T����NGG�r!���}�����������y��RRR�Y�P��@�vi(��633+.j�t��������G������� ���+\\\��Y34o�\�vr ����%"����
�������#H���*\����7ob���������G�����,22`oo/W�������{X�t�\�(�G�E�W����j����:u*�/v���r�#"q��%"�%�����W/�������*��l-Z�P������};�������W�^���C�r�k���G�9&&&�F""5�����V^^^q����E�sssU�K�*��m<==���������r�!�s�����wE "����W�bWaaa��x��VE����k9*Gjj*>������___�����
�����h�<����["�jFFF����h�.y�S-*h���MOOGTT�B�
��9s\��i���#H�R��""*�"�Vk��^�x�����9+���T�^]����v_�����u�*����W��_ 44~�a����8�i����A899���h�t���T�>���'r�OD��3�D����1}��q��?y�={��k�V]������~�TR��f�Bppp��x��V�-�n������W���b��A���B�z����?c����z�*BBB0`�>|�����9s`oo_��N#"��^�DD
����m��!<<={�,�YLL���*�nT���#""�F�����b�������K�����S����������C����������Q������n���L&���D�X,l�H������������_~	]]����m��V�Za���"&|���g%~��v��a���r�8p RRR��K���d2���c���r�=t�P��S�Y�f�����-i=???|��'9r$���Q�n]���",,AAA�����u�p��9���#66����;w.���������������
������5�1}�t���222��G������ W."��������H�:t����}�������H�={���#���*����/`jj���������0s�L��uK�(%�������/��"v"�R,l�H#(��U�����]����U���q��~�2�L�2o��A�v� "��]�������[�����\�)([aa���ELD�aaKD�e���K���~��GL�6M�����a���b� "�R"�\�P~�_�F^^�����RBAA^�~]bg
u�������s����b""-S�Z5�+j�;���:}SBD���DDr��d��D��T
OOO�c�r��I���C�D�����g""
P�Z���###�\c��Y3��&����-���vP���q��;v��1J�������H��k4&"�J�J�X�d��1�	����c��A������S���[q��i�c�p���4������/v�b�����{������gO�>���K���[�9ooo2��w/q�����z�*���W�������������o���-[b��!��������\�x��.QQQ+���������z�����{�n��[#F�(q=!!�6m��
J��h�"|�������)S����������O?���fff%���w/�W�^j�999�V����[K��l�2����c��%��>}������/J\��dpwwG@@@����iS*i&�D��/_�/^��������_���I���V�ZA*�b��
�;wn�u===X[[��L�N��,�5j���������m��
XXX�h+66,�g�}��
���A��������O�>e.h��u�kc
��G�2����;j������#///^���1RSS����U�Ve.��]�6z��Uf]�t���I���7.��j������T?(�~"�<���������q��)���o
o;88c����S�`ee���+B*�����f�����E������C��U�V��g���D�CDU�����|��R����L�8,j�A"����6668x� �Z"R�D�������gO�����'''x{{���E�mW�:�p��Y��37nT�#�H�q)i���,������g022RH����������3V�Z��6��nE-����i�+W����BaE�L&������}{x{{+�Myeff���.��9sD�BD�X��VS�2���|�����-����������������QU��D��F��!C����>;
)["�jqqq�W��Z��
233������_W%"���m[�
���[[[����bG!"*��-��D"A���agg�]�v�����DDjN"����;"##agg��3gr�Z"RK��������������'���H$ppp��G�D��!C�`��MX�h��Y�����}��L&���+LMM��A�rH�R�������5k�h9����/��������-��pW"�HHH@HHj��%Ju:Q,99iii�����9�����-i���BT�^���-[����;���abb��d��NE-�&�["�J~~~pww��3~~~8y���Em�~��p�B�DD�5�D��n�����[�����`��7�N�B��-��������z�jL�<Y�DD��3�D�������c�r�/���+++%�z�����%"����V255ETTT�fm��.`���8r���%"�������������
sss��h���@���`���,j�H�q#"�#�J��m[�����g����:u*1n�8��U
G}"�:���h����1�����h��1j��-J�� `������Ehh(:u�$J""E��-i���4|���b�x���X�����������777>|���,j�Hkp���������s'����`�&�?R�����={6\]]E�p��	$''����066%�2pW"�2���1v�X�:uJ�m���D1yOf#"Rg,l��J������v�����NE-���["�zIIIprr���7�Z""-�["�j���������3V�Z%J�
6@GGs���"����-i-�L��C����{��������TJ*����B�DD*��D��d2������_��ZA�x�b899!//O�8DD*�["�*111h�������"���|L�27n�@PP�7o.v$""���-i�	&���kb�Evv6����$�����%�*��-i�����?���(}�����/������u��APP���+Z""���%"����s����i��*�["��]�vx������J�������<===�g "R<R���������ys�����M*����X�h�(?�766�W_}�i����o""u�["�x���pqq��7`nn����_X�hf�����������%"["�p2�����S�233��E���E-��D��A���S������w#55M�4QI�,j�������Z�l�^����p��U-Z�@�F���� ���OX���@D�����-CDDZ�l���333UzDff&V�\�U�VA___e�i.E "��y��!00P���J�������#11�J
LDTQ,l�H����`������;��I$X[[����{���"����H���`��X�h��q���_#"RC��������m�0n�8��i.E "z�D��?���������S�"00�E-Q��%"*C�1����S�[:t�D"����J�%"�t,l�H+���!<<\!m���
4�_""M��������;��w����?����o�t��P��|������`,Z������?==&&&���E-�f��-����L�8�w�F�.]��Le���d������}���J�!"�*X��ZIJJ���������R�����P�n]��m��1������6<<�[���T�QU�����Fff&��������3gV�����J��������^��+"00��������E��IDT��%"� ��0z�hXZZ���������Wj�VU�l�R�G������CD�U������������r����� X�r%|}}q��it��Y�HDDZ��-�}}}�X�B�����ann��@
����O?���_GDD�)	["�
�|�M���H$������������T�V
���j=�LD��������D\�zU��6h����,j�����-U	R�������g�w\ ""������O#"�X��J���c��aHMMUI,j����D�22����044D�F������������\""��%"�S�NE~~>v��-�^����+|���J/jA���'.\�����EDDo�#� v"�~_�5�9����J}[������s��Qh������)S����8y�$��%"["R:???,[�h�����OHH@�n�������.���puuEnn.�9�����D��D�T���X�p!N�8���V,������E�������H
��%"��^�:����.]��Ea233amm
{{{:tzzzbG"""�H]"R�(�������V���{��������$"���["�h�vvv���Eff��q��HD\�@D����3f@WWW�8DD$2�D���_X�x1&M�$v""R,l�H�����5k����Y�f����D����b���X�f����wQ���X�|�B������!Cp����KDD�����*-88�����������eK��VRRR`oo���k�G�J������"Q���u�����k\\\��Si�C������a�T������4Gl"�[RR�������Emdd$�������c���,j��4gl�H.���������3V�Z%v�J����n��������������*L&����	������{Uz��2������>>>���;��G�Q�����/VZQ+��
f]]]DFFj|�NDT�qU����-[����$	�v�����r?�a�<~�X�>Y�i>�D�V����<y2���[��6o����d%&#""u�����F���-����+����222�����4["R�)j���iii�����;x������H���%"�U���_�^�x�{�FHH��1��H���%�������a������>d2�Z��xwa�a��a��M9r��}�z�v_DT&�LWWW��WfffJ��f��8�<�4iR�v���[�.
[�l���aggW�>��H���%�RA��i�����o�U��x3c���Z��� `������������s�J�ADD���-��|�r\�r����U���q�e���x��9�7E���;n�����(4k�L�tDD�
<R��J�����e���-[�Gnpvv��^�DD��X�Q���`�;�N������q���*��"Q1]]]8p@)E�D"���k�.Q�DT����Vx�E����][�maaKDJUt�����1k�,���caKDJ������~�����.i&�D��,jA���V�^��������%"��{�.����d����1c"""�-Z�k�.4k�Ph�DD�8cKT����W�VZ�M�6���[^�fgg����o�����K�p��
\�tI�}��`aKT�c���������������#�fjj*���P�vm��������=M�4��G��/i�DUHLL&N�����;����vvv8t�������U�V�w�������[�*"))	NNN��������q*���C066~�=|�["�*�G�U���������3V�Z%v�������)^�z]]]������%�r2�C����)�����-�H```����+���255Edd$��i#v""R1��%�r�_�������^�:88����
kS>����{W�DD$��Q�)�����|�d2��SG�6"##ann333��"""�����*DYEmff&F�+++|���
k����.E �rSVQ����~�������-SX�DDT���%�rQVQ����������&"���K��\���$&&��/�PX����pqq�����x�b��KDDU["-����	&����7;�{���[�n������CDDZ�'�i�L�1c����Tcv�w��9{{{������-��HHH@HHj��%v$"""Q��1"
�|�r\�r���,j�',,'N;��"i0???���!""&&&
i3==u��UH[b�_�>��=+v""R1��i���`��7���h���B��H$�����7��X��k��O�����bG!""baK�����q��XYY)�=�T����c��%����B��H$

RH[�����>�W�^Uy�DD$�D����VH[�8|�������E||�B���=z������MDD�`aKT�)��
��a��i�&|���
i��z���+W���7���-Q���v��-�:u*E=x���
QQQ��ODD��}l���#F���A!E� �B� IDATX�r%|}}q��	����Waa!����D�1�VU5� @GGG��EX�Ua�QC1��}��W8v�N�<����+�����d�Y���1�����tH�RH�R���"..���������/���K���j��CCC�N�:022B�����];�m�h��-���raaK��v�����,[�L�(����i��DTqO�>��3g��w��]������������Z�lY\����5j�@^^233�����/_"==w��).��R)�<y�����_�~ppp@���Q�vm�����X�����`�;�N�R��^DD�p��}�����J����gq���g�3�HNN�������Kdgg#++������G��ua``�:u��~��h��q�����p��9�9saaa������5&L�WWW���Oj��-���u�����k�.���������8|�0���q��5�1&L���]���G�p��Y��� ..����{�.j�������E�-K(Z����S��Y�x	B�v���K����������<y������3���0h� �-�"����H
%%%�W�^X�d	f��)v"��RSS�a������u���;F������?�,�MMJJB�>}��K��5�h��A��z��5<x�����5��/_��[���s��Ya{{{��Y>��={���,\�S�L������*��X�����L�������V��t{�s�����G���b&�:�n�:���NNN���B���QXX�3g�   G�A�.]���P�AWWW�Y���q��9���!$$O�<��������>}�xs0��+p��m��?��O���������>�DjD&�a��Qh��=���+�^�1�NNN
)j��'Q��%"���������������8x� ����p�B4i�s��A� �Hp��9�X�666J)j�n��>|86n��D���������?��~���7�k��8}�4����?���Z��/����U!����\a���B^^^������4i"l����m�~�ZX�b���I�����nO�N�>���)QUp��!�Y�f������� � ��{W�>}�``` xxx����!�!??_8v��`oo/4l�PX�f����!� ���	���B����7n���T��-�RdQ+���O?�Th��������t���U+!<<\�Dj-!!A4h�`nn.;vLAHJJ����������c@xx����$��WO���rrr���|a��5����0g�����b�$%�R"-��cr���������o����h����R����=��;'v"�u��t��
�:u����!C�`��
���a``�;w�`��-j?���'N���S���>�aaa���Dttt��d�D���$,l��HVV���OO�J�����[�������TA)U�_�~;����d�������������7n�@�n���'O���~��c��v��3g���~���S����������pwwG�^����?�����"i�DKK�J��e���w���G�j��=pjj*�������'044;�Zx��F��:u�`���h��1���;�����o�����5��>ddd������={������G���+;v,����}�v��EX�Q���{w,[���;
��$	
�	&��o����O1q�D������h����.44nnn?~<��]���,�3���8z�h����4�[1"
������#99Y�(U��!C$v"�]�r���X�`��]�.�s��h��)������GGG\�rW�\���-^�z��'O�a�����/�c-���H�d2\]]abbR�<tR�!C�����b� UPP
���f�B`` >��cl��������/vD�j��)�����O���R������`gg�{����*�*�� �6m����{�n���B={���y� ��P�fM�����3g0a�8p��m����_�������;����Q���G��-����c���������!���p��%4o�\��$'��%R����G�Axx8LLL�n�����u���[�<����~�:z��Y�v�H�EGG���~~~pqq���+�}�v�s��b������/���������1�|���������I<\�@�"~~~���_p���J����x��I��deea��a����T;D�������b���pqq������Q��Z�8q"����q������X�~=z���#F ''G�x$���@pp0&L����Pt��E�vu�Bjj*�
sss���G���UU��=���f���E�a��=X�`.\��6m��Om>|��M��3g��C>���8|�0��i�D*p���z�
�
��
E����2d����a������J#F�@��
����?���&M��S���[7����;v��o������A����?����X�iE����pqq���3��H������_ETT���[[[���optt;��������q��e$&&�O�>F�^���F����H�I$888`������/�n'88�������+������(<��
+++|����C�A0j�(��U����/��///\�~]���JX�����#$$nnn�j'11���������i���\�����H�233��G������pww���/�^�������K�X��4i^�z�C������-U98r�~��w��)���sq��}9r;w����7�_��z���Mc\�|�
Bxx8�7oKKK�����
;�["�r�����M<~����b�!R��7o���7o�D�5���"$$VVVbG�8>>>8|�0���p��A|��W����.2j��C)���;�R�h��):w��#vI����3gb���077���s1i�$�r�?>d2|}}1n�8XXX`���b�����-��c���8u��!�?��#��9��G���H!v���5k� ::�����I�ccc��i���p>���HOOG���q��5|��bG��`aK�111�����]����"Ww��A���a`` w���X������5j��������'077GBB5j$v�J),,D�v����?���}�V�\�	&�M�yxx@GG���������L�������K�*)))	NNN�������}�6lmm$w���(����e��,j��a��ppp����BTi{��E�:u���___�����U���o�����h�":t���b���`aKT	���prr���;f��)WR���%K���*WG������a����www���RA�w�}����
�����l�2�ci��
���>�w�}���c��	X�n����-��HN2�NNN�_�>���+����8Q���.����1p�@����rss�x�b�[����b�!�������K�������{7�l������{�*������uk\�~��WG��!�J��I������%�S~~>6l���s��UU��+W����/N�8���;W�
"�|vvvpww������}{���`��b��:_~�%����c�|��'h��
V�X!v,��D"P�L��'�x�b�y��
NHD� !!;vDJJ
��=�E������l�<x����x���]��������;�Z���%AHH<==�.j`����|�2�Z�*����/F�	��������Yh)I�-��o_<x���C~~>.]�$v,���i(l��VVVh��)bcc��Y3�ci�={�`������'����}�v�c�?��%""�@�.]���+<x��;w���~CHH�������/aff�������/RRRP�V-����p)�:y�$F�����c���pss;���S�F������}��h��"""��E�����=2220p�@<z�H��SSSE��*JOOGAA��1��%,,���BTT�"v�*a��a8u��_�~8s������X���L&���+�����M�V�����J��u�Vt��
/_��T;T>�
��c���A�^����v�lmmq��t�����;V���_?\�|YYY��������D�����-A��i�����
�i|��mXXX���r�����o��'N�@�:u*�U���;_!�p���o������3g��� v�*�������������+W� ;;[�X�?,l��b����|�2+�b@�1����C�-*�lAA>��3:t<xA�����;w�������;{{{��3g�O�������0������/^;�[�2������AAA011������r����
����8�|��b�###|��'��i��Q�����[���+rrrp��M���W�HU���m��]�t��[�DNDEX��Kpp0����#G��e��z666���r����������BCCajjZ��I1,X<{�L�(Do�v�����;033������D����I�&��/KKKH�Ro����SI��~,l�����@��=+�\QQ+��b2����8|�0���+�<)F�V�����%�������D�m�������PI��/_���<<<0e��������z��1U�W�V��������������*�����-��������s�&M���'���K��m��9���P��Z�����7oFNN��Q�J�s�6l###H�R��@�~�0{�lL�:�w�����������a���x��)����7��]���W���#J��F�h��U���h����A�$44T�������v���5j��������b6..m��Uj����>}:�����{w4m�;v�����_��?�D��333���!!!}�������������
�>�/^�@zz�������M� bG rvv;Q��={��
���0r�H�����t��
`nn�7n(���h��$	����]�zzz�������1e�L�:U��r������]]]�����[������aaKDD�A���`hhX�{###�����c@�z����<ttt0l�0�������Bjj*V�X�i��)}�oCCCdee��{��.E R!�L�J�HFDU������������������+1}�t<{�����������	[��[��v�����Dx{{�����,�5
����1cF�} "��w]T���������.������W�BOO��eQQQx���={�����������Y�&��_�����$=z����Y�&�u���c��z����.��!!!�5k��Y��s�b���x��v���A����999�������wa[�{gl�J
����+�������:u*A��s��������������$��������J�����G|||��^w��E||<��������w���~���7���0w�\t���-���[��~��7���
4��M��|�r;v���GZZ�\�:99�����7ottt������T������������
P��522Bff�����ca�&�������1�8p�;�\bbb0q�D���������b�����ttt��\||<lll��o_�QK��1�bl�����7���_�>f������1{�l��=��u��e�������_�����W�^h��
������r�
���E����`ll�_~���~��\�(������x��I���U5k�T��A(��������QM��5�����b��aS��3�����g��Q*$))	NNN������K���J���/TdK���(���'N���9�i���$,]�T��D��U16������&�a�����Ctt4�m�V|��3�����>�����k�����m����_W�����/�c�E�����k���$�*�kl���)S`gg�Q�F�����xL�2?��#�v���te�������t��6m�T��.1dff���	����9sf���J�ppp�pQ{��]<��m��q���Lj������4h�����CJ��q8!!>>>x��j�����,��9�����U��h``P�#y��"�{�.���g�p��5XZZB�|������5��W����C��S����u�y�&M��I�������z���688�������F�����2��DLLn�����$%%�Z�$&===�Y�S�L���7�z3{�L���G����B/���/���|�._��6m�T4.�===��7�|�
BCC���6��8|�����`���:t(���{ppp��%K0}��R�({l444���)r���m��A��o���M��j��2�Y�t)������-������zR�J�=.]�$�,���~��5��������V���!lll�p�B,X�[�l�t��6b����`��-�3g��q�����={v���������K�.��D1�����?��u�p���2g��"m����1i�$>����V�Za����<y2lmmaiiY�]e�����RY��o����k��yg�Wdee�+�%>��]���}�={iii���O�����vvvj�-���S�q�F��� ��5kb��E�Z6n���1���?OOO,Y�D�(jC����� H$|����>1bd2�;�t*kll��a�N��5+��UG000����!�����h_������ys���"==�����ZY�����z�����������E���(��a�p��}����E����+vR#3g�����q������*����'�E��>���C�F�����56�m�qqq��R�T��+R�j��h�"�������e�3a�<}��B�����X�k����h����,����j)Bdd$BCC������8			pqqA��-�����{�b���P�i4����X�.N�8�?��yyy055������K�����>}��Mgee�������������Cvv6�?�������g3f,--q��\�t	��W����{_�i����o���`8::�(��(((P����8������o����a��)u+!��1�g�_�~��.����E���~D�offf�~�:����|iIYcc�������/^�����W����=z�g>|��K�,�����d������5+�l��}h��u�lgE�S~~>��m[�>}bG��Q����]����]����(,,���{1�|XYY�e��x���������#%%���PjP�8q"��o�u��AOO=z4__��.�z�
w�����1n�8�]�S�L��!Cp��I,]���}���[����)�KEd2Y�?111���#6o��^�z��O?Ett4���0w���.�/��C\�pAE���T*��#���u��b�!7n._�����R'+i:������AAA��<�7m�_����m�������16��Y������S��mrr2<<<�z������.]���-���K�"&&�����%K����1c�`��i%��Q�BCC��������������_�KKK�]�V�{�SSS��[R����:�@FF�P�fM!55��g���"##K\[�v�@8~�x��I�R�`iiY�z@@�@��ys������!<~�X���>��#a�������9"����u�_|!N�>]�~�����
�=zW�^-�����������K�.7n��l�,22Rh����b�
��U�:������wy�k~������#����|���������Fggga���Bnn�P�F
���g
�CY�����7o

�W�:$���	� �����
�
D��b�mzz:d2~���R�����^�zj�i�����#���S�z������e>W���%))	:::j�&���*333t����g:t@NNN������WO�>����t�����?����o#""�B�=z���
���U��D�G�aU������������m;�]���}k�;u������j�B���q��y���L|�:v������W���;o����������Z�-Z�@��n�\ IDAT^��|�r4o�S�N���;���C�?��[&��S7o����/�7[rDGG�����l�.]�%���$��ITe���]�6�7������x���R���L&��1c��A��������ptt,�?�<�������`��	��%R+�4�b�=�����/,,,����x��������_Jspp���g�>�[XX��������������������:z�(������???L�6
�[����K��N7//�7oF���1a�����>HQ���W�^�>��ou��}�g��Z��X�U��i��!//�w�.�^�R���%K��;_^^^X�|9���0p�@ED'R�2�������E3�o���hK*cc�������O�>�w�RSS��_?���F]=~�			�������amm]�c�I������
���[�l�����={�`��5h���{�@�H$h��)������
������c�/�|��'O~o��@����

������B���<233Q�vm���������q������k����X8::b����5kV��x��9�������������o�J)RD)�(�`G�bL��{��F�-�DcAD,��+�����aA, �� ,�����
:����y������3�2{g�{�����H�6d��9����O�D?��uk���#--�������h��!��iSn���5k�=z����>|8���{���������PQ2GGG�Cb�C&������&=WVV����.]����W�^8v�X�e�����q���MCll,���J<�Z|��Xxx�XVl�o�UU����1����	}}}N�������?��?_����v���UNj�e���p�Kj�:����OK����2���=z�����$���+���5C�>}p��i����t��)����:$�%��E&���>|�T���qc�9�����3������u.��_G�F����P�}111�����s�����j�ZY�Ueaab_1&&&���������x<^����SHH����'N�����������q9q�D�?Y����|||��=}����pss��I�����8y�$���$�z������s��������Cnn.��v2��Db|]�n��
�^�q���������
4��[�D��~�Z4�`�=PXX�'O��x_@@�w����_^����U�h��������7��;w�����=�6q�D,^���	���V��x����oRY2]�������#G�Ty�x�@����%��X)++c�������:�Z���J\�����~�g�����@```�q�;v����	f��Ua������������5
>���/%R�Upp0z��	CCC����-�#k�?�Xi�="SSS����o����o�N{����#G���	��R���u+������si���t��1����������
h���4~�x�~�:]�v��7oN�{��;E�V�Z������3�����x+��:�������/w�o��FC�!;;;���$MMMj��
0��B��_/�=���t���J��~��HFFF���!*;**�.^�H������M��uk���eff�*���O��={V������
�pF�q�W������������C����+���h���daaAqqq�-��q������ADD������'����}���}�H �����������@����������6���������SSS4i����}��<���+s�O�>���PTT����h�K>�����j���N�Uq��!,X�IIIr�4��m����h�C���p����J�1L��/_���w�����'���������WQXX+++���Vz�N}cJJ
��k��o������4i����UD	���G��]�������c���x���a1�����>���#CCC:x� ������m����0�����"


z��!��0rh������X��MF6I��V����B��m#�PH�;w�H���h���4{�l""1b�[���������c�����kW������������|�C��PH+W�$===z����0r���/diiI\��T�$�ai��!!!dhhH�����?����%I������W���Lo�����RVV��?rS�yx��=z4����e��C���?b��i��gO��*����k��*�[XX�I�&!88�o�F�.]$SW5m�;v�����%2�#�����7���@WW�����!
q��)��[��[��~�-����f�L�2���_	�:�f��|>����.]��u(UVXXHNNN�w�^���{�n��������=#�*�=���i�����W/���Sm�d"":v����qS
�����7;~�8���Raa!��������U[1)�Z���KJHH eeeJMM�:,����h��.^����@���sN�<x������/��BBB0o�<>��}y<��K�b��������}�BII	������W�L=7r�H4k���0�jW?,������f��!88���
���k�Tc��f���~�������_������d�L���0�y��)������:��}k����������
�9�0������3gbbb���C:�������:4�u��y�����xHHH����={V�9��a�-#������W/,^���5���b�0��!C��K�Y�?���B!�K.������
~~~3f���1j�(��7����
����IYYY�������z��
�eI-�0�W/^�@��]	mmmXZZ���Cpvv�:4�������o#<<�w���m�-����,�ed�@ ��!C����C�AAA��������m�b���R��aFv�����������q��1L�6
>D�V��Mn���a���������,--�Cc*�[F�l��3g���i���^�|	��`��/_����?��f������������K�y�*HII���
v������c��������={�����2u�@ ��)S0~�x���sSO������d���x��)���q��������C���+�M�	�B8�:u��-[�i�&���������2��1U�[�������1c����3g����N�8q3f���'O����u8L=�{�n�]����HKKC����c��3���d��Y�p��\�~<��p��
t������*b�-S'���b��!022�����ys�Cbxzz�I�&�:�����ANN�;���������#8p ���???<x7o�D�
��[7,_�&L�:4��`)z������CnUu����������8z�(Kj��c��������\�"���}������y��0c�������'����M����;w���������������%�r�%�R4k�,\�p��0���g���sgdddT���;w��woxyya����A	F����a����6mK�j��������C�)++���8�<~��7��������!C������	�����q��9�n�������:v���uhL
4�:�������Q����[��_�2����PSS+w���"L�4	���;<==%2�����+<==1n�8����a��\���qzzz�|�2����������#;;8y�$����u����mV�Z�����K�.��������+W��Q#�"�#�j'��mmm�������#|}}+]|�a�����bS�12o���X�d	rss����T�m�g�������iSL�:ZZZpss���?F��u�RED���C@@�]�sss��1�����������u�L
����:"�������}����C��bUIj�����M�6��M����g�u��s���������?>���0z�h�����Enrss1y�dDGG#"":::���B||<BCC����u�L-�����+V **
h��i���er�a��W�^�q�\\\���g�^�������@hh(���[�����x;v,

�F����B����PQQ�:D����5�T���������/��,,,���{���2�0Ucii���H�9s&L���9����f��������\�(���G�^�����3g����������,��#Xb�HMHH�����'O������5j����ro���_�|�T��0u�����������]�����8|�0V�ZWWW�\�����o������-[��g�b���8{�,�v�������h���a2b�[Fj444p��t����}utt�|����g�������0L�������L�4	}�����������o���������?�u�5VXX��[����
���x��1lmm1o�<������k���uc�HMU����sC���)S��w��)*��			PUUE��-���'0k�,���`��q�t�6m��+W������8q"z�����W�����p����X�p!q��������G�8q"�7o�@__��0	`�)�\8u�
�-[�����:���m�����EEE\���3}����������c��Ell,��k��={���>�:�r	�B�8q��u���S1{�l��u����={6������G#44�%�uKl�������������q���a$f��������e�����Z�l�}��������?��wo<�������/��}{899���
.\�����,������
����>}:���1a����?�����7o���,\��-�P�����LLLV�ZU�>K�.���+q��58PJ�17�6m�c��a���8z�(��0�T�>}
8;;c��aHHH�����o_��;�;w.'Wqq��yxzzBOO����?~]�t������q���
b���2�(^&��%r@KK�n������"cn��6���pSO5j����CRRlmm1d��������X�p!bccq��ib���077���Sq��Q|��I"1�x��v��7�|===��?VVV���EXXF���� �o��V���E����K$F6)qD}1d��7^^^\�"Q{�������~��2����r�������q��())q���?>�5k���WsJ�����s�Nl��������������!p��-���!,,QQQ077���
���`nnsss�����(�eff">>qqq��x���Gdd$�����_?8::����:uDGG#((����>�.]�������)��JQ}HlCBB0v�X\�|��YXR�0UCD3f7n�C�q��a�-7BBB�s��������8p���,>��[�n���'���C||<x<RSS��E())AII	jjjh��


������?#''B�m�����,,,`nnkkkt��
6����8w�8�>����������!�kl5#6O�>������XR�0�������@$&&r
��4n����pwwGFF���q��aL�>���pttD���agg��x/��Gff&�|>������	�P�&M��]eee������[TT�/^`��=Gxx8���	������7n,��#�Xb��Err2\]]�j�*:�����888`��e��(�0LI-Z�@���a������'b��������;w�?��>>>h���h(���������EEE�������5��/_�����/_"33������]�}��aooGGG,]�;v����F�������,������S�N-sCCC���������<yJJJpvv�t��0�4m�}��E��}���?C(���W�q�qqq�u�rrr���E�Z�hEEE(++CMM
JJJ055���f��KKKhkks�9�[�VF�-z
�<M�4)3���};�/_��6b��C4hcccc��A\���#,�ejEAA�
�����u[��������w#44]�t�`��0��l.�V5j��s��I�&U~Oaa!&M����`��}�%�SMD$3�>1LMEEE���999\���!,�e�*''C���g�p��u�n����F������2e
�a0L�edd`��q���#�L�6�(#.,�e����gHJJ*w���7���MMM��0u�O?�������_~�:�����,>�{�F������s,Z��%��X��V����1�|dee�����C2;v�� 2�x�����Ds������?���f��I12��[455q����������:��1c������R�^�~�o������ 2�:�����OXYYa���PPP��s�p��Mxzz"55��9�[	�������g��������O�<�A�a�������9�P|x<��K�V������2�#���8{�,����S�Nq�����/022B�=���#��QQQ���,--�b�
#d*s��U�=�f���!�-�����+W```�����1�L��%u�`��
��{7��i���;���C8{�,������2220b����FFF%��x<8::�����(�0R�Q�F���������H����1u�T����Q�F8u��������uhL5����������:�a�}I��������@DEE����r��
xxx@WW���^,�en9::b��-1b���}}}�C���#G";;,��?�dI-�0"�����W�^���o0w�\���2"��������K�.�X������ �5�0�s��%8;;���>�~�-�7o���ws
SC��-#	,������K��-[�'N ""���%�]�p���%�������eKl��I��2SOBAA
6�:��Xb�H� E������c����}�v��\��srr0f�ddd���a�j���|1S�$���/HKK��Gvv6222�����I())AQQ���PVV������>		���sq���R��%55C����BCC��ys)D)YD���4dee!33|>|>���PTT���������MMM6�������|>���������
E����&TUU��)�@ @ZZrrr������l��|������7n�q�LY222��������|$%%�C��r�
TUUK����\���)6������G����!..���x��5Z�hEEE(**B]]���(((��~��|>
4������affKKK�������}�{��!--
...������A����[�l��$�*^�|���H���">>^��EEE%�OQQM�6ENN��d���#''�[�����:w��������zy�����7o�����6��x������D����UUUdgg�~`������	��������������������x��P(��G�p��}�����011�7���"TTT���
EEE�|>������>����B������������������Bjj*"""������D�#����������x,>Y)>333���Q���S'����%�L�Xb[MB����Cxx8���]]]����333���AII�Je�{�N�����#&&�o����*���GGG8::���@���������C�b��)����������*j���t������u��������Ry|>����������w������G���������e�/����p��MQ��:t�����������I�N.�B!���J����O�v����������������	�����022����111�c���kh��)z��%:�����C�%==]����o��P(�����O577��'�?���E�axx8^�|�=z�}���sss�n��J�_AA^�xQ")���F\\�u�&:{��]��f�Xb[e<����� 
���$:��w
,q(**�������0��y]�v���F�-�[�������(s��U�`jj
OOO��SSYYY8v��h�5;;;Q���[7���{��-���D��^^^���A����^_]GD���������E� IDAT��_�~����TGnnn�����<x0|||0x�`������CCC���[f�X�}��������{�q��XZZ��>"BLL�����W��u��������'Z�j%�:����|�;w����|�2lllDm��wo������]�&�O���o������bg���)Wnn.�����w�N������?����I(J=���l��o9::���"}��7.�z�>}J:::t��}��%)7n��q�����"988���{)33S�q�B������'���:u������O���R�E�������+����Z�nMK�,���XNbINN�
6P�N��e��4c���x��R�>}"+++�<y2'}W���B���h����E����3g�PAA��c����'N��#�E�4x�`:v�I=y���S�2e
ihh���5m���RSS9����'�p�B����v����U������������!++���_O:::��_?���(//���D^�~M���+���Q������s�����%===���?�^�4���P��}IWW�V�ZEIII\�$���
&GGG����5k�PFF�a����_��3HYY�<==),,L������3IYY���C>�:�2���S��]�����/??����C����N�:���;����R��"iii��_���%YZZR`` 	���9����#F���*��;��<y�uH"���t��%��� �;w.%''s����GVV�\��444����"""��B_�|�;v���1Y[[��'�V�<'��O��n��������_2uRR���o��������e�8��,k���h��	���D�&M�/^pR�>~�H��-#555rss��;�Nn

h��mdhhH��w�S�Nqz��2EEEL���dllL;w����B���\dd$
4�455���������B<����;RRR��~����}�uH������;r�������;EGGsN�
$###rqq����W���w���x-66�Z�j%wImBB
2�Z�nM�������a��U�Vt��!���D~~>�]��TUUi��r�����A�W�&555�:u�L]�$"���u��I�������c����gO�|������PHg��%kkk������H�C���O���$


��aeggsR�$&&���IMM�6o�����#�>�}��
<�(88��pj%77�V�\I���4s�L����p�.���
��sG�ZYI��w��������


���'555�9s&eeeqR�\�r�,,,�_�~���S�����W�R�����?~�u8����B������I;w���+�>| {{{�\OKK��3g���&����25l�����(00�Z�lI�������C�
�PH������E������h���'YYY��7����z��
�B��u+������K)77����&66��������O�<!


:u�T��G�E��m�?��#ccc����h�5���#���$z�����Mnn.�X��TTTh���2��[nn.M�4����(  �N}�K�.���
8P����8q�455i��	u��w�����ikk�����G���}K��C�z�*���MQQ����444h�������Cb$�^&����4b�277�G�q���������J��o/��@ �v����]�J���c�"##I[[�V�\)�Pkd��]���J���{�J��������}{rww���4��;�GVVV4h��:{E,//��L�B�Z����0�����|�5k�������GbN�>M-[��E�����.\ mmm�={6���s�D���P����[�n����u8�����6**���mK�F��O�GGG���)�1��x���.�<y������������������Z�nM�n��:������3g�����?�XAAA���F+W���[�Uu��q����E�����^�zE�z��~������_�~Mvvv��{wz��%����@ ��+W���:9r��p$N(��u�HMM������a$�^%�G�!UUU��g��HUff&�3�:t�@o���tRWW���)DW=�����S'9r��=�#i���2{�QB��-ZD����n���/�����.��uT������eKZ�|y�I��B ��HWWW�4�_9994x�`����LM�(
������K�����0bVo��������L?%IB��V�\Izzz>��y�f�����!			djjJ3g��W��r��]����
6pJ��������^�~�u8�������J}�����FB��J�\�r����i���R�J6�h������t���#ww�:��Iu$&&���M�:�����E�"�]�n�j��<x�u(����?�e��t���2������W��U����G:::2;�W�bbb�u��4s�L�[���=z4u���N=\T��&L�P��(����Ovvv&� 55�:� UU�>}Z.oi'''��������������'���'�1B���0_���v��dffF���\�"3���Kne���wI]]��Ef�y����oO3f��:�*���9::���+[B��
�4w�\j��-���p}����w����u���������JLX���q�455���\�R%o��!###�����cI���"ggg<x�����V��������a���Y��������.Z�������[�oy����dnnN�V��:�
���9::�iv�0w�\�������TTTD'N��={�x�������!���q���[��b������h��%\�"s�������<==��9Wg��� ���&��u(2k������/�
$''S�6mh���\�"�^�|)�����1�lmm�n�"i
���w�Q�~�d�V�P(,����[�HMM�.]��aT����+2}',77��������]�-Gff&Y[[��i�����:���;w����)**��Pd��%K���R��H���3u����r�Li< 


:q�����r�J277��cj+SPP@...4b���Z���c�����G�r��

"---���"�����
V�f�����266����s
SCu.�}��%ihh��TU�H(���7�����Y�P(��#G������$���R����:�3g��������5�����sgZ�z5���dffR�v�d�������_�c��25�|�����G�z;�Au������]�r��P��S�mAA����V�X�u(r%''���oO�6m�:""��u+�k��233�E����/��S'���z��
�l�����L��?Njjj�u(DD���E�G��:�"
i��a��?p
������f�YPBZ���IGGGf�d��N%��f��~���[-5���SRUU�||XTT�������\(**�����S9�C ���-Z���8�����K�/1�c�j������+�������9�#55�Z�jE���4y5m�4rpp`9���3�����IGG�^,�(){��%###���fgg���	���������2.�C������]���6&N�H��������RUU�{��q���q�����xO��B!����f���I�u��/_���F��1�S "�����A�����`���\�#�F�	###l��E�u/X�<g���z�u����1q�D���BEEE�u?y����x����i#������<t�����+��+���}�����+|}}�Zw]�l�2DEE����R�;  6l�����I��_W�x<���������)��0UP'�����'�p�����7o��S�N�z�*�t�"�z�={���{���011�Z�u���#��Ml��Yju1`�,Y�Dj��U!!!�0abcc���*�z�����������h��������OP��[�����KKK>|���R���Z�t)�����	
S}r����H���_���O#""


��8!rvv���K%^_}��	J@@��]�'O���HLF�l��I*���H��OPx<����L�<|>�J}u]^^:t��
6`��Q\��TB�[8;;c��e\�Rgt��,����%^_PP��Y�G���H�~��7�	��edd�����������/^�~
+++DDD�c���o��)������%^W}2|�p������~�x]QQQpqqALLtuu%^_}q��L�:qqqh����0���6,,>>>HHH`	���?��OG||<5j$�z���`aa��7b��a��>h��v��	���z�jDEE���S��>Z�bx<�9"�z^�z��;"66���y��lll���s���H��!C��������ggg���a���\��T@�['''����/�����b������X���5k���4h�@b��W��o��p��-�����all��'O�w�����JOO���1n���:H�����C `�����>���oa``�u��I��G�������PSS�X=�Uxx8������K4k���p�r�mb{��]���"))	JJJ\�S';v��-��g�$�t:w��%K���o�{����>|}���H�7o��p��e���|�1������o�D���=LMM�v��I���.66={�DBBZ�l)�:�����/)�����o���'O�:�r��:={�dO_K���
+V�����N���y����$:�����i.]�$�'z�����m[8pb/������h��=zccc���h�"��� ((H�e3�g��Q������+�^v\\lmm���---���|%�azL��eb����N�:����R��>��o����������`�����W��|>���q����������c��-�{��X�eJ�<y2����~�z������V�Z���k����X�fJ�s��
��o��=)�5k`���b-�)��N��U��s!2J.5a���,��<|�/_�k�����}���'���1z�h�L�$��3������PTT$�r��9��JA�=����K�.�����B�����X������2L.�������0�EEE6L�������=� %���

�P([������k�0f������w��PRRBxx�X�

b���7N�I������eKX[[��\�l^^^8�<�����)��%��o�Fvv6�+S������~�s�
;9���}��A��q����<p�
$�a����}���/_foJ�����9�������~|��wb+��X�V���o_s
S�Kl<///4l���P�
'''���"**J,�=x�?~������QPP��q��z����H���7�?���<��w��899I|nU������{��8y��X���������%�������f��(�Kl/]�www���W6lWWW�=U��E<�=Q*ennnbk�> &&KyL�������7o�Ky�?��������^�v
;v����X�c�f��!���BVV��0�C����$''�{��\�R����_lc���������T]�n����!��^��=z@QQQ�1����(�c�����_�����b�������b���Sn����c��b����\%�W�\���=[>�NNN�����-�����y���SdLU5j�}��EXXX��b?���Iftt4���ajj*�������3�B!bcck];�#��LF��*�e0wttt`ll���o����w�BOOFFFb���q%Eaaa�JG�������Z�
��m�����{�b��
X�x1�?�uH�(((�����'�iii��x���SdLu���_,
��������[�����"""jUkCn988���������+���CLQ1��������#22�V���cQ  --
;w���������uHe����X�S6$�#}����'O�8[#7�mAA��}{�C����o�W�2bcc��C1ET7���[bS�XZZ"%%9995.#66���lH���X>CCC,X��&M�:�
u������I�/%%%">>^bu0�'7��?�ZZZ23�?�����G����O�>������277�������x�L�_Q{�Z[���^��H���7u�6665*#..b��l��6�bccq��
���!--
�V�B����V���9���j���fffb�J�������9���!
��A��1�����=�d_Z���qqq����D�a�Nn������}���(**Bzz:>��k����g\�$q���������?�ZR�_��m�Y�f����]]]�j�
���2��W�8qBl��6)����u��'//��������i�&H�����JHH���&����Szzzh��1��yS�2�y�)�����O�c�m
���`��9���������-�PU���PPP@rrr��������p��XE��u[
�B\�xVVV		���.tuu���{{{l��Q���<%�\�Mylll�|�r���rR�<�!S>333��b$��`��,����^����1�a�����[�nI��#11e�s���rWKJJB�6m8]5�����--,,�3g�`��uh���|��a��a��	������$��LLL]��@__���en��X����\�ebb���d4n���v>���;lC�m���\�rE44���-[�Dhh(=z�6m����������|��	�>}��y�PXX���@4n������k���8y�$��������;�����������7n���{h��-���`bbR�����8u�x<7n��]�b���b��LLL���X��+W�������lrrr����6m��5&y&�����b-����b���	UUU���.\��^dgg����0a��rogeeAEEE���-���a���HLL��0~�xL�8Q�qEm����u��������E�)**�A��>���xxx 77�����O����������~~~8p�f�����|�5
������+-Z$�b������l���V�Brr2���,\���r�w�����=���������7�������{�������?>�����O?AQQ��e� J���1���BKK��V�X���O����?��TUU+<��[W���YYYh��y�'6��4�R�k�fE�-rs�6''���\�!��9�{��qR���R�����/_\�z�T{�6,[aa!����q�F��������������i�I�&a��9��^����r�?���M���
\]]���\j{vv�D~ ��SPP���"����'kll��b��)��oJl��hdd�%K��i���?>���q��IQ�VVV���������g���m��������I,^�7n�������v�������'''l��>>>��
SSSXZZBYY�bKJJ��C�D�?r�HX[[��������}�h[TT���M�6��RUU���{abb�5k�`���b��U�����K���[[�RC����Y�?���������Mb+�Sq���N9yyy8q�������'���c������$&&���C���_|]�����:z��]�O\5��?��?~�a�����%�
I�
����������MMM:�z�k=@�n�V��p��%��9k����9s��?� =={�����|||������7��sT�������Q������Z%NOP��65��<|�w����7o��S'�1BR�J*k����NNN�={66o�\�������X��[�>>>������{�����7���h������x�����K�w��)(,,���cK�ijj
{{{L�6
(5sNY�dll�#F����������|���4iRj��-Z���;v��o��V�Y�Wem��,Z��
BHHH�6��q���P|�����8p 1t��R����q@������={V4��1c`ii���p��u
6D�^��\�R�})�[Y$W���~L�;�3f`����:u*2331y�d����������)����7nz���5k�@OO����0a�����'����PRR���#��=�w������>a+
���HII��G���g�����i�u��C����� IDAT���d���������
��Y3��}�G���A��{�n����s?�����???4j�W�^����1w�\L�0��{��������?��i���"55��I������9��m���Ua*))a���5j|}}1{�l4l����(((��+��m��~gRSS1m�4���`���pwwGdd$������/��Z���2x<
�����~����������@�����<p��C�EXXN�:%Jl��wb���q��%t������v���W�����2dH�m�;������'agg�O�>!::��� "���� 77o���I���2���*<�����o��{���������]�Y�n��{�u���y��(**��C�0o�<t����g�jT����8O�>����m���={��~��������9s�`���%b�v_
|m���Q��9�#$':t�@�������A��eK���|>�����y�J�~��Y@��w�����ijj���K�C���������#t������2e
���R���+�g``@���dcc#z��-[h���b�%..����e�����m����{�k���%&&���"�����{�?N�5�#G��x��m�_���dkk[�����~��W�OUU��4iB���DD���I���Hb��E\mS����'3330`�����L�Z�"���Q��Xm]�t!''�J��U�V��iS�>}����k�.������:z�h��O�>M�����{BCC�|ODD {{�r�]�r% ??�*�r�������200�����o��%���^�����m�FU:[�lIZZZ���MDD!!!��G��B���n��1�������7������q5��<H�������Wb���5o��>�\���t_JD���K���/���:��b���X�Z�u+�:�,X�iiiX�|y�}��i���������rrr0h� �;w��}��{��������E�rf�	}}}XYY�{��%^/^&422��O�u=5�
Z�6�>}z�c�%''jjj^%___�8q'N����%������21��mS������������C:zzz�����X�����������###1b�l��?����ui�����a7

�R�����E�p��������������������v��*�S999���@xxx�����a��h��!���DWi���@FFv��U��:th�v�NW���x�]]]t�����: 44/^����/������7���[�#�Il�/�K��nEU��3g�����5o�\��I�Ve�	�������1c�`��e%��{,���b��,;;�����f>}�T�:jz�6m���'��%U�n�:\�x�o�.1d�a��h���L���I�T�;s��4l����e����������a����A�JlSRR�xZ���X(��T�S�Nh����{W�>��Tg�����bnn%%%$%%�;�Z~~�X������������6J$�����uk���+V���]������={������%��NW���s���^��� ��`��"�Jl%=@���'�~Q�w�N�%K�T:eUu�y��5������)SaUv��7�����Z@2''�����kN�:�����xz������?|�B�Pt��,�I����1d��o���022��'����O^|,������
P�����o���{����}\�8T��B�c����5kJ%���/�u58??���*1�Ae5j��3g���~Cttt����B!BBB��{�R�v��9���K���A,\�+V����g�|�l��q�������U��+���]aY��mCFF����*�Q��N�:�����������?�4i�y��a��5PPP�QW����/��*���[�#7����������������Z
>����������b"���gS�vq�ajj*���g�>}Z���������RGMn������M%���888K�.-7q������I�T�;S������***B^^^��X<KY5_?[MW���k����Yt����p�B|��������h��9@+ZZv��U�v��M���/��9"��3 
���R�_���ggg��s�;w�����%b�����+W���[[��>|���bKj���bEE9r��a0��.�hkk#00��'������H8pk������N�Z�>N}5WXb+{�&����@ZZ�D�����������m����x��
Z�n]j���<4m����F���/<<<��C�*|��KOO/wV$&&���wN�6
����|����P�)���pt���FIMn���M%��6�&%M����.�c�*j�6�������������^����t4j������o��7o��~

�RSj����S�t�R@WW�N�B~~>���E}��{��d�<}����E`` ����'�(�I�&�q�V�^
����}�Eq��"]�R��(�
�����F��E51VL�	��<�����%�
*��w�6z�������������,�s]^�03��;3���S��_�~066FXX���U�����������}����aaa���P������;U�K


�?+W���A���t��	w�����s�/.�G]m����5��FFF(++�5�z��1v�����8p �o��^^^8|�0�O�.s���Z(umCF����Z
�����uH.E�����������'� ##��r����x��Vg��RuJ�0qS���JJJ���;;���-������/x{�!<<����������L��S��~c��2���O�}
mM�Ae���{{��kii�zFm�>��6��3s��AYYN�>]m�{}V766�����0��-6�6l��
v���
u��Q\�tI*�tuu��s����dee����		���Jhjj������;w0s�L�=!!!�����Mjg����� �D"l��s��A�^��w�^����x@CC�-Btt4����`���X�p!�W_�j�u��m������-�������J�����1c�H����q����R�6d��$�������i�z,X����c��x������.EI.��}IH�r���+���b��������744"�H�r���;Z�h��W�rKIIi���`jj*��S===�i�����w��(++��i���cz���/^x�|H�MM���i?��#z������Z����]�u�*RLL�^^Qm�2���������1|�p,]�iiiR�qg=�#%&&NNNr/�������FO�E"���x=����;;;t��M�������-�y��_�SeeeHLLlP[trr��-&''c���U�~��e�7��Y�8y�jI[���NOO��k����)��&s+����7�=������L�2���011���k�_��;w�������?�5k�`��a9r$�������V�ZU�d�����������\
�0aB�_���K����t�����1m�4���{�5kD"���_L�:~~~6l<==1v�Xddd������k���\�u�*RC�"'''������jVW;�u����H����+W�����1r�H��������������}����G�Q�zih[�������?.uiCIee�/Y�$&&������r����L�����R������ZZZ8}�4z��)u6]�>N�v����O?�111011��-[p��U���O����������C���`���X�v-N�8!��111x�������5���������8��exs�����;wn��vY�����K�Z����DGG�����w_�d���HHH��-[�.c������2�aCdff">>zzzprr��������z�!!!b��;w����n��������[���@��]���w���>����
��d�6��3D���X��bt��	������DEELMMabb�����=�F���)S�.�G�X�z5��x������K,\�����1{�lXYYq��e�I~0]�rE�26n����/c�����TRR���\������W������>������U������W+���9._����*�&��o�\�t)�JAF����]�������`����

��9s��Paa!LLL���3���b�j��=:$� ��&M��.]���o�ip<�=���k���uuu��������=�g�U�?��/^`���r�q��e|��g����12���?����}���_������&t�!,,>>>
*���aaa��1�����
��-[����+.]��ST�,����������7�I[�������l��k���o���m�����|����{���g�:tS��������%�J�I%�>>>�p���a4K���@�.]T���S���0����x�k{
(�x.\�oo�_�4h�����~�),,��7�����r���������@.^��K���I%����CTT/�Jed#I��xp�����@@~~>������)�~d
���i�v���U+��u���Y��������^���G�p.^�X����4��V__={�d�@���>�%EB	���/��{xx ))���Q"��`:`���g���0��������={

��&�����/:$t�J^^��?�#F�R�����K�.!;;�����9t�o^���`�������y)�����p�����w���<��*�������#y)���
EEE����:t��g�~(�&��N�8'O�Dnn���4�B�����m[^����D�~�j|c
����;v~~~������={��VS�={���������}�]�x�����@��]Caa!og�5440~�x�l��}�8q��a0�hr����z�����J��g�����Z&K����#���+lmmy+����C|||��1�����������>��c�H���������c��}())��L�f�o�Fzz:,t(L5�\b��H����q��]|����;f�DEE)����Uc�8����G}�}���Z.S��������Ao�����?������2^�e�*))��C�x�q��w������y-����={��'��a��T�Ll?��C��w�
J���F�
^������~�m���Z.SUbb"�]���c��^��I��k�.�^6#m����4i�����&&&8y�$�e3�>����^����VH�~


�mJ�I�y��y��!##�v�:����+�o���������?~��{�Fbb"{�U#���������k�6J�}�����?����F)�n��___<y�������m�6l���o����]F�k��X�p!���{���_3o������s����A�MlSSSaoo�{�����N�pT�O?���������V��1c��kW6Z���g����������4J�N����3��n$#G����,X�(�������[�ne�
6�c��a��y��������/^���8�`n#)..���-���O^�gG�Ml`��� "l��I�PTNaa!:t���G��������w�
���$�ow`�Y�f�����~�����f���>^x���������D�F�g���8|�0{my#������+L�2������B��q��5t�����i�6m��={�����B����I'�IIIpqqi��Q�����q��9���4z]��G�~��p��F��9y��9���q��=^GC���C��d�<z��=P��1c��K�.�������_�C�8p����������S�������c���HKK���{������NNN��y3�
&t8L-�tb�g�FJJ
�9"t(*#55�:uBpp0z�����=z�}������}�F�������ann����7z]���/���y��5z}�EHH�����gk%~��w�_����c?PxR\\��n5~��F�/++NNN8t�����e��!,,/^d��+�&���������7o���J���q�`ff�
6(��Y�f�����MV<	

�����"x��!������+(<())�;���%K�`��	
����������1w�\�������{\�paaa
K�6o��
6�(<IHH@�=p��u8;;S�&�������d�DDD@GGG�p�4IB���c+��W�^���[�l�����UII	�����y
���/�kZy���?"$$�.]R���w�b������������UEB%D�(c����9sV������;����~�I�P�� 1p�@Z�p��a4i���@�v���?���lmm)??_��U��e����TQQ���sss�u����?�(�nUC���!H�3f����_��UEEE
:����/H��o�&�HDO�<�~Uq��A�������Ca�Ie���211���P�Ci��L�B����$D�G�&???��o�.]�D"��bbb����dnnN��=,��������[7Z�|�`1������m��Q�����WS���M�.\H���TRR"XMYbb"���PHH���02P�������CdaaA/^�:�&g���dmmM�����C:t�m��	GS���NVVV�g��C����?��_?*--:�&��/�$*++4��H$�;w�GSt��
266���HA�(--�~�����s��)*))�>}����K����J%�DD_�5y{{~PhJbcc�����\�"t(DDt��M244����J�QQQA#G���?�\�P���A����-Z$t(M�_�E���K�C!"����������	J����M�����;w

=}��Z�jEG�:�&e��Y����r�&H����"���}��7B��$deeQ�N�h���B�"��_%�� 7�/�w�y�
�����255���J����266��/
��?��F����PRRBC��I�&	����O���)EEE	J��w�^�������
#�Kl���={F��������B���
�o�����'�}�5�9s&��������i�&���R��D���������;'t(J-11�,--i��uB�REAAyxx������P4y�d������_N6l +++JJJ:�J"�����_�Ca����-Q\\YXX��;�E)�������O���J{dYY}���4p�@***:�t��Q211Q��6�?N&&&t��]�CQJ���H?������(33����i���B������K]�t���l�C��w�}G�:u���,�CQJ7o�$ccc:}����0
���-����I$��S��E�����������C��0y��5yyy��	��������H$���/J�~��w������8�CQ*yyy���J��O:�:%''����R�UZPP�o�^�/]WTT��)S����]	{KTT���������i �Nl����=K"�����/t(J����>��c���G������K�z��1c�(�%>!>|�D"�<yR�P�m���diiI���:����K������Qyy����KDDYZZ
:�2����E������C��������Knnn���.t8J���dnn�~���Ol�����Z�j�����b6l���4����b1
>����(77W�p�c�233�K�.	��v��I���������D�����3g6��V"11�����nr���������rvv���d���IYY}���dkkK���B�#���P266fCL��f��EFFR��mi��E�����T���'}��GM�~������O�[�n�r����
Z�l�i��<x t8r;z�(�D"�����E�o�&�����En�����G7n\��O����F�E������)t8r$+++z�����b��=dllLg��:�G�&�%"JII!���m��������M�64k��&��������K���t��y��Q���l=z49;;+����t��j�����[�}x�1����ddd�������!C�g�������������F�Ib�X�pl��M$��f�]E(**���j��5]�~]�p�5������Hdmm�$�i���
Z�f
�����}Y��� IDAT���W����������u�:v�H���*�����O�o�����F���B���^�zE�|�	�����k���7�l�c��{7�D"
l�'	*�y�&u������U"Y�MRR��������?�����%�����~R�3FO�>���S���)66V�pEBB������O����>JKKi��UdddD��o:�FQZZJ���'333�}���7����>��C��?���diiI_}��J�������)S�P��m��
�|�����#GR�N�T��}�����	��	����&�Do.)����\\\T��mII	�^�����h��Y*?�@QQ��;����(((�JJJ��W�^�n��Q��=)""B�p��3g����|}}U��mvv6}���$�h���B���RSSi���dmmM�:^TTT���{�u��4v�X���Mr�������C�5������S���-l�U�Nl��4�]�vQ�V���������In������B=z��7n�B=x��<==������=+t8r������211�5k�4��
HFFF�d�I�sss�������CR�'NP�������I��5&&��B����n,�������?�n��v���d�.,,���@200�������T��[���t�<y2�D"Z�x1eddR���y��{�=255�-[����_�����m��������6�{���h���dllL'N���T�CLDD����:t�@�7on2O������#G�G�����������������&��cll,M�:�

����o�?��p��i���%www����L�[XXH���#kkk<xp�c��Kl����C���'CCC
�g��	R�._�L���dffF���J�*GEz���Y��,--����N�8!tH5JOO���@266&___�y���!)���������SPP���%����N�8A=z���;��5k�L2�����(  ����h���J}7""����IOO�>��sz����!)���b��k988������Ki�$�����5k�M�6J��3��%�5x��1M�8����i���t��)�x�,33�6l�@�z����[���������b���_�M�6��gOZ�v�R�i�������i��	���O~~~)tXJ���4`�233����I����(00�:t�@...��~�=�����4g�244�w�}����G���B�Eb�����CC�!###�?~���1����������������~P�3�W�^�������1
6Le��a���:�����+����,,,h���t��u��������C4j�(j��%�1������/���������/���%]]]9r$<x�rrrCYY��y����C������H?��#%%%),�����{4{�l��� gggZ�b��/1>��6n�Hd``@�&M����7�K�B����
6���;��)S(44T�g�)88�&N�H���I�7oVh��������g��������_�~�u�Vz���B�������������M�64o�<z���Bc`���z�u������G�B,�������sg����ROaa!�^��.����w��w��q��a����������(==����q��]t�������������"BTT�
/]���-[b������G���y��9*++��s��g�C__���>>>h��oueff���K�vLNN���7&L����-[�����&66{����C����OOOn;�����SZZ�[�nq����k������c�����;�ROs����#G���?�����akk�mC///�V��'Op��En;��w����?uuu��b�6���)66�kdaaa��ppp������sssBOO���044Dyy9^�z���<@,#))	111���Fll,������,�A�D"�����������/"22�������������:p���������W������+ddd ::111���ELLZ�l	���`��ptt�+����r��{�k�W�\�������###�D"���C__-[�Dqq1�b1�������X���Xn�EGG#++�z���b�>}���-��V9��?���/�������������m�zzz\{466!77b�b�HII������h��-��g��h����_Y��~��;!s��E��u\ttt���=���```�H===hkks}iAArrr���+�
cccQ^^�~��qm�k��h����_�QB,��������&::���HMM��X,Fnn.455�NY�A�m��;K:��R�#���aLLRRR���������������K����aaa;;;�mhmm-�Wjv����~(��� !!���������X,���.���a``�mO[[[n�I�ZZZB�f'33����/_r�.??yyy###B__zzz����N28;;�������������v��&&&���yyyx���b1���``` u���vvvR�EvV����2�0�0*���g�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�Q	,�e�a�aTKl�a�a��[�a�aF%���a�a�HII���C���#�C�����1|�p<{�L�P�:h(��K�.�����.z��%���/_b��
ptt��q�����G��b1���T���%Z�x�����HIIAAA


0t�P<��P���I.\����O�>�����I�&q�WC)��,..���;������|���`��eh��e�����3l�����pwwop<�����};rss!�QTT��K������e�6l��QAA���8::6�{
�)ccc���
???����L���333���!$$]�t:$�&� fffdffFzzz��gjj�M311!


��FFFU�ruu��/^�XQ_�������K�����V��%K���<�bcc��&M�D������� �}�����I�dggS���	}���t��i���%�b��z�A���5NW�m���@C�%333@ZZZ���k�����F�{��5����]�xRRRh���dnnNH]]�^�zU�e�������

��*��R&M�8���A������Ceee5�WW����������������B���@a�"ddd ##+W���{rr27-++%%%x��1�����CNN��2�?�>GGG7~�MD||<n��������B����?���#
�!==`cc���#))	999���E�6m��>��3���"33QQQX�|9���iii�|;w���'�"��wR6S�N��7�����������_���u�^eTTT�G�

�qe��;vDpp0,--������QH���<v�X^�i��-���accpuu���ZI,��]��+d�
J�)�|�RSSq��n�x[}���tttp��A���b��)B���@���USS�����������'O��	�����m��3g
�R���������������\������H��7ob��1����H$������_mmm������X�h�m�HMM�*SWWW��AT�;)���R���
555���a��������[�r���PRRR�|��-333���VX����HJJ��x�'??w���kY@���<��q�����)S`nn^�|�msB���#�����P����B��TC���.\

�*��7�|���l$%%���E�|���QPP�{��a����������c���y���O>�����[��Uzz:


�;;�����;w��o�z��u��F�O����AD��jjjrgW�����+(//�kYU�T�����X�`�����U5i*mn������s�3�<�*������%K �pvv����H$��U��#--���~��������W9c�0�v��Y���oB��`aaa---�!.!I�����9������;�&�)O�<���d����������R����3������$���L�Q������,_�3f����>`��y066����u+n���X����3���.QQQ8|�0�������V�Z���C���m�
555���/pss!..�{j������o�2����M�6m�����
��9b�b����8y�$<x����#--
����5kV�Kab��w���G��-Z�}���2e
���k5W+33k�����>f��)�����������q�1�^���������x��	�������i���x�_�Z��+?a�|�r�������HHH���:w�///������rrr�n�:��y���������
�����}��U������m�p��m��b�D"���#--
��
�G}���&O�)))��}�p��}DEE���������&M�Te���1���������o�L�4������_��U�p��)����M�����u����P���$];;;�Z�
��]Cii)���1g����J�����e������pqqA``��Yo��c�����w����$������W�b���x��1��������/z��Y��kkBD8�<�fE":u��A��w��U�����z\�u�����W
9�������>}�T;]�6'k��w���o_DGGc����z���s��q#�������c���8v����|��W��m��������������o��w��2���.}}}L�8C����q��q$''�C��9sf�mD�(�i�
6H=/�������>��3@���5.�~�z���o�O����:�������)$$������������U�}��'R�I��@�'O�*w��idgg�M_�f
�����c���ttt����dkkK+W�����:u�Ty�N���m��3g�����'h��Q�F�I���r�����s�����9��!C���O�.w��������1cF�������[�bM�:�L���n������u���.//'???������
9::�/��B����K�����q��QVV��������������h��>�\�����ICC�V�^-���]��e���q�Fz������������?'�|���7y����+W�������)((����O�=�M�6���.YYY��#G�����oi��i�������=�f��M��]�����P�={6yzzre�1�+c��U�Q������LRSS�b�{������I[[���m+�offf���-X��~��7@}���*���s\y����.�q��j��O```�1WTT���K	�=�?~L.\�v��q���?_�uAD��pe�k���t�B+V�������}��s�����F�&M�z*_��&�qA���:��_�{�Kii)�D"@����vy��<}_}����;	YXX��Ndq��
244���/S�V�HCC�����w��t��i���"ooo@�w�����IF���kW�u������u�����9C��?�~�����6=z����3Ol
D���dee�������(>>��������ZF��9::Rnn.��;��_�.5����kLl��oG���Jl���Rg��t��]�������77oDDiiiq��JKK�O�>��.]Z���������
7�����������M�64g���+W���_�z������%�[�	HM?}�47������;���r�<==��-\������T"��U+���G�8***�����X��7Y��MRR��������L��w/o�}�q����g��q�g��y������ �������y�q�$":r�H���$����o��}��g\?%���n1  ����.W���E��OXXX�1O�8�����T2/I�Ppp����H:�9r$JMONN���q��q���I�r\�u����D��W��[���d.�[�n�:o}�\C����Q��[�����|o�K|=z4�������0y{����jyy9���?���lll(;;���>�-�c��F��|��4��F����i��g�r���I�?&&������[�tz]��6]2���&&&���;

�a�����

���>}:w���O?�R���S�7oV���,���:tuu1o�<��)����*C��n���)5���u�}a���Un�>|8�=zg����,Y����=��+++��?���&��HD��eee����>���[\�z�����B����W�E@��&O������{���We��1c������r.e�,�'��!�����/���&�Lr�F~~>v���3f����~�r��L�2������@��*�_[����g�b����%K�H����$��_;b��*����k�w�}����%�Y�[e�d������������������6DC���n�sJJ��_�������0j�(���r/>�<y��m<���������z�#---�[Cj�k����vk��%�����}{�1����'����5k����z�j��%;v�>K�EEE�<`%����>��}�6m�M�&���W�9�w���������7Ow?{�m��m�x��/���q������7�����J�^yLD�������w���q��7�\>���d�N����>K�������������������c���X�z5444����!C�����C�V����]o��Q���2�q,;t�Pe]]]XZZ"99���x��e��9��L�g��Y��������#&&��zzz8�<<<<p��U����?��[.''�{
j�����/^Drr2�7������O��k��{�������S����+��Ec��6���p:�l��&���_���J��+����q�UT�P���r��������

q��%���sCaU0V��\VVV�v���&�����*�Eq��a������>455���OW������)S�py�Ol+���i���F���E�����#G�p���W�p��y�W_}��#��->>eee��;99U;�������s)�.yU>�U�����5���3u����$�q�F\�p���pssC�n�PZZZ�������q��1o:���DDD`���8r����]o��Q���x��im�	�<����J��*�������x�*��>|�%��>�E��|��9���0j�(n���pTTT�>�[y�;v�����������UmR,����x3�p�����s�N������z�x���dio�������|�W��_���Z���LQ}C}����Q���W�-�����������~�:�7WB��������S�.�U�������Z�����F�Q��EQ�����aaaR��eaii�I�&���c����KKK\�~���X�lY�'yCmO��k�jjj�����X�?����:33��\��l����c���())���/N�<	+++��7��lD"�=���x�;ww���������\L�4���&�z����T~R��F����~���DFF���fff
.�1���r��}�|���������|||�����6T7�_~~>���	&H%u�_+Iz����"���|�O�f�io����o��%�������U�8//O�vZ��)�o�O�]�������H������\��A�^��M���T���������N��P�qlutt���MMM��/++��-[p��$%%a����8q"���������@�Kr����������DD�%��T��[\\����>���KjM���:66������K�yyy���OQRRkkk<xP�S���/--��A����;;;L�>��mCdd$n��	sss�tD IDAT<}�����[o��Q�V�Zq"���Y�;I�SMMMt����r���������������D���'9����,u�r�m�=��I�>}�@[[_�5~��Gn�_����B��)S����.]����;U����w��e�����z%�J��=p���%R>=}�����gO�������*�����&��mNQ}C}���������?��q�0}�t�$XVqqqx��%����?���%���-�w;��������se��������w�^����+�N������@AA��]===���C����C�~}V��(�Y*�|oOC�����}��kW������g��
{-���?8�?����M�"������q��i@�N�0~�x��~[vv6�<���U����+�g�>ZXX����c��U�sss������&u+���M�:j��?p�+?*�=4�p�B�_�Z�@%y�x���<;�X���`���.��/_��k��V�\)u�x�Kn7�������,�����;�}�v��t>���;�v�� --
����u��7g�ttt�m�6�3a��������7+)W__��oo�����������\<������)e9����r������:o}��}CC����o�cu���;��M��c��$	)��j����#F����������mG�_6�����������#��(�7o�������Y��'O��������9EDDp�+)U��dl�I�&��S�j,�g����w�NEEED�fx�~������O<���r����������u�V����W�^�X����ICC����h��u��9����q�F�D�n����^""z��)�.���O.����s�����We���<x�L������R�ZXXH�����rE">>��=�-7j�(��#""�������?�"""�aO�g]W:HMM�V�^�m���n_i��
=|����$oYSS�N�<��{��E0`u��������q��<y��$�����C������_�;���rss���6_~�% CCC�x�"���r��9�JJJ�iO�<��o���A/^���������&4v�X*--�s�����!���s�)��I�Cz��y����G'''����?��������	���/DDTPP��}
�v��I;w��v��I
%���Ch������NVVV���|@h������@���R�������V�O���S�z?��#JII!---�{����C�f���������]KeeeDD����
��v����I�>��� ��u�d���9������	��?��u���9"��������P���D$5.~�-�=���'�|�����?s��R�F�����v���G@����
Kl555�����������LMM�����������ttt�5>���e��$�����HGG����/�T����o��%�����sz���HGG�D"999���)}���t���*�dee���&���	������iiiIu�������c�R���IKK����H]]�<==)<<\�Lo��k��%U��
HKK�JHDt��	��� ;;;�@�P�|�
�������T<��D"���6]�r��2z��I���dllL���dddD����8�:::R�����455�X'�]W����C�F�"]]]�|gggZ�h��������(  �����kGm���#FPzz:������������$-Z���S���1c����:u��-�b�
�DK��&����6���4d�j��5����H$�V�ZQ������cU�2d����D���K3g���n�z@zzzdmm]�G����Do�2___222�!C������������Z���� WWW����A����
-Z����������������J��~�:YYY���-�i��~��WnZbb"���;dbbBNNN�����J�qqq4h� ���!ooo����/���?~L}��!�HD����j�*����At��yz��9�7��������kl�����������d:.�:]�A���W��/�c��rww�s���9	Y������u����X�����[7�����e�i��
o�����'WWW���3�n���/_^�_mH;���O	�~|��D�H���4�_|�-[������G}��~@D(**��'Op��ADFFBMM
5^V,--EVV���`eeMMM#--
���������n�����������	333�/�2��X���m�����y3���"33m���m��KNN�����U�Z�K^^wI���������y���k��QGm���PQQ��x��������"����w_������4XZZ���������#77666��	D����m�V��p���R$%%�u��U^i*Y�U�V�)�������*�����e����j���SS�z����7e$�1���VVV���Bll,lmm�\F�6'K��G�ggg�k�111�>�STT���������=`��-�:u*�<y�
iV]�����������>�,A�j=~���\T��o+,,$sss@g��U`��*������B��0����_O@���	���[rBm��H8p�>������u+kll�\e4G*��X���a``���Rn`��<}����h���v����a���>}:z�������2�������{�nxzz��Ppjj*,X����U���1KKK��-S7�e��-:>hhh���8}�4�o��g������^�Bjj*n���m��a��� "<x={�:l��������q��E�)���RDFF�����KC�0��������k�.\�r&LPx_�G�]^^�Q�F���!!!�����k<�G���	d�����X�f
v�����"XXX ??���)U�T/hh(OOO������38s�~��7���ACC�������������vFniii����?9--M���a�Q&���8u��
�o�������chh��`�DDD ,,�����
��5K�8_�z���D�?���(..F||<7S;�zx�a�a����'��_������������p�B���;v:�,�e�a�aT�!�a�a�Q	,�e�a�aTKl�a�a��[�a�yKJJ
��G�	���|�2��g��	
�B�~��g��a������m��|���,##���CAA�o����������b���������GII	�-[V��8I��c����HII����C�b�����MD��a�T����/����K�Bz��%6l�GGG�7ZZZB�����Xx{{���...
�[������>�;vqqq�t///�����=�_�~033���BBB��K���L�<22��gD)))t��9*//�q777@��wo�r�����&777����^���)WY			4t�P233#���U���������5����L�"""(77����&M"KKKn�

�����2rww'CCC����P�����+��/^,t8���� [[[������2��/�zmH�[�e���k����}��~��\]]�����>}�K�����!#�nE���C��]1d��9s������c��m�r��stt���7������:v����`XZZ��������r�������3UUTT�G�

�q��;w����R���:�]��+V4J�Bz��1�9::Z�H�CD�������p�
E�w�6�����6l@HH��e�EGGDjj*�L��{�B��x��F����������Z�����$,X��Q�a�����K9������x{{�R&�_}�q����8����9_��P�!00jjjh��-f��)t8�8p����1e����CC�kC����m���c��?~<BCC���6JBQ����Kl/]�022B���k�OSS666�^�|����W*cb������3Um��U�T�7�|���l$%%���B��`���X�`����W�
A��k}��?�x�b�zr�AOl===t���r����R��$�ikk7j|l����g��o�	�J�Dh�B5�9y�$������
{{{AcQ��Z_�;w�������>�a���Qv����W����QQQ��O����>C�v��d�o�&\�l���r�2�YNe/^���}�����"55���+f��	333�y��;��7BGG~~~���EVV~��7�?eeepvv�����)����[�7o�Djj*444`cc|���h�����AAA����X,FAA����������K8u������eKxxx`��i000�����`��y�?���������=R������V���k�PZZ
www��3��������;v�@ZZ�������W�\AZZ���1~�x�7���*�_�������8�<�u��_~�U�YJJ
����k��!##�[���	�{�����***
�F\\�����U+x{{c�����mBCC����_~�nnn������3!�!�Q\\��'O���X�~=�������Y�fI]r+))��}�p��}DEE���������&M�$�_]�v
���������P^^��=�����-[�����a��E�+W�`������FEE,,,����U�V���S�m�6mBpp0�7���[W��
�����������M�����8~�8 ���S'4�{��2��m\�m&�6��u+n����#c������b1v���G�!22-Z�@���1e�xyy��DDD�m����oC,C$���iii6l>��#�����G}���q������p�:u
���������'f��]]]�;��g�"99���:t(��_e����W������w�w�W�o��������;��
&k[�;&6�:������7������_�\@fdP�Y'������os�4+��JrJ�L�MMIz+b��@Nhj�D��Q@�����?�p��;1d��x�x��g����������H�y��a������BLL�b1\\\�`����)�����~=����1c����S�N!;;�:u��%K��VEs�T�5k��o��v	��?���YC�&"�g��Q�=h���J����I��r��	277'www:~�8=z����?O666diiI7o�dy�]�F���t��E���%���_���+}������L����������GM��D555��S'@'N��w�RRRm���D"������[9��[��E�@4{�l=z4EDDPll,���:t(I$�z���h���,�����)..�6m�DNNNdgg��.�g���@ `�,]�����O:u��D"���������k���>�<+����
����$rss��'O��������"t��A���[��������_�~�s�N��e	:�<����Z��{7���R�����eff����	8p��T����n�:
����B����X����X�s���-[��6m����� ruu%dddDw�����;�����n�Y�f�z.]�D^^^$
i��M���D�o����w���19::Rdd$���u
�6m�����%K���G�(%%��������P���9s���K4f�@����-[�P\\���/k���c)88����i���r}#�Y����5k�Z:�aaa�|ggg���;���P||<���S�n�H P`` '��&:���i2��~�-���)�!M:t �l�2JHH������O����b��I��"


���\*))���$�7o�
6�5>��,--	����J�)��#G�������#OOO@>>>T\\L�F��������S�N���5�3f���X�ig���YYY
����+����������Q�&�B������a}�C__�|||h��t��JMM�a����A��FQ=B���N]�v��g���G�h��!$�����j��9i�p_���'djj*7I���K��
#"���W233k�r��]K���En��[��-�R&L�@AAADDdaa�BQ]�t�����`���#�v������z|}}9i�V�"$��������$v]��}i��e����7��+W�p�JKK��4hUTTp�sssY�6��������q����+��;��v[XXp�Y�t) ccc�����O:��s^^���Z�p�R�.\�@iii���M���t��Y���?p��;w.�N�:QQQ'�����L��9��W���8&�/���I���'���I����|�rJLL����g��#F��[�nQII	��YYY�����+99�9BH(��k�8i���>�������E�rrr��I���r!�6m���;~�x��#���o�^-�PY����������l�XM�:���T��T3M�gdd(tr�b1q�t�R�5��
Dh����okkK}���ksmm-���QHH�\ZCdgg�����
��o??��N��m�X���}��w�t�
@O�>�+_Y�igua�rl5wY.\����/_ch�+�����*�9�	/��?�uO6$�:���z\\\������nJ����������E�.]�3f�|ii)��������\\\�B��$&&��n���+���l ��������B!�<y�����*���wYZxx�&]�2���(�p�;w����_p�dq9����C,}��}�4���P��w��ql?������|�����o_@���k�������W�^�F�)W��k�HOOOn������H(RBB�B�D"��q�z��M���DD��/��P($777f�����<y�S��Azzzr��9�.+V�`u���q�/^������u�&O��9?q�D��;������+����-~��u�����_��7�x����gO�v��	N��Q�h���rui����� �{��Q�g��i,OLL;�������1�4�2'g����|rr��\���#dggG���j�/�H�������h��t��e������{�����W�^eugdd4�Wv�X[[����G������]��g���.��7�<jcua��M�q�E�({�����������2�c����|{�������7����c�����$
�c��
��&���cO�<a����C��M���c����p����AAAMR����AD�����I������`�EEEpww������b���,����/��K�.����{s�"""��&tpp�����0M����X�����7n�`��>}��z�w@e7(���s�d�����K-Y�A�1k����D�|MM
������X_�r<��������"�YLE�m-\���������WWW��s����B�����`�?~�;w�7O�>���D�����������4��w�N��?��i����?du44���:�\]]����JN��/_���`ii��,Y��������1{�l@uu5g~��3����v��!;;)))x��1{�g�������K����L�������HMMec��)--
�����}{�r���:�+d�p�����_��:(3]��RYY�+W��v�*��g��L���\t��A��������o�����u+�n�
}}}t��������Oakk���R���ov��H����se���r�h3����Mi�u5�VVV�8;;[�/��BW����^���������v\SS��z���/0�3���055���222p���B�3g�l�/�5�c+u�������!C�m���m�*�l���dgg������Y&&&pww���|}}���!{{{t���s��3g��������;vQQQruuN��������_�)))���A���!�HT����A��$	s*4��-**Brr2�q�����K�=8c-���M�?�]������Z��������7oP<<<<��+,,d�UTT�����2e
&M��?�&&&����\��_1��M�6�2e
D"�����{w$&&��jh�KQu>�?�W�Faa!"##�UZZ���x��`jj��,Y��o��|FFs���lZrr2g���E�p��%v����[�"44�����������������v���!C��������.���4>2�����LW��RG� IDATddd�����_�6Jqss�H$RjC�?,,555l�WWWC,C,����������U�[ ��W����.��6���m���]6�:�[�.tE�1k��P�����|��"������z��o#��c��-J�)�;V������[SSSx{{+����sDFF���h������$v�(V`QQ���uw
��^��_��x��9sl'O�,W���
�����n@��AAA�����q�p��i8::�]�������F~~>0gQ�$''�_��Q�/���r������9FF��FFF���?��?����w��!�V�%��� �Y����W��������O?�|�h=��qU�S�v����(|������E�v�������B�_���h�(���l����&�^o��6�������`���8~�8bbb0l�0xxx ==�����q#<��{��$��������E;iid��K�TW:��W�4�����3����t�����������'�����������HLLDjj*������\�l�����y����6�����K?D��sUyU�C)�|���bv�N�A����z�cjj*w3�����N-�ql������n����O'���~BEE`���())A�����5]�S\\��I��r��	���@ �}3##�=��?�?��{�;m�4����g���1MXXrrr��;wN�����s��AUU����1���U������$u�����~��q��wh���8�TTT ==��o_�5RGs��A�DX�h���K@AA����$iy"����9r$/^���}��	�����������Qe��:�����w�^�={YYYX�v-f�����`��u�W>4����9dD�y�+E"��G����'���s��Pwg|��	���3��@�:��������8q�Zr����8u����kjd������t\�����&"���H_R�D�Q�F!33nnnX�p!������\�~vvv���Aff��e�:��kCkC����[W�.���<5x��C����? �s���/����_��f�
��oS������?��������r}ME�:����l�K��UVVb���;s'N�����z���c��������E9�NL�;�/_��������U?��������qu����7�?����\[
������y�	p�����6�Z���W�����rM����P(���;��E\�z�y�f�{Oeee��l����vw���8p�{�@v��C)�~�-�m����:����gw�^�x�d����X,��?��_��=Y�)���l=��qU���Gyy9����i�C����?<<<4�;��/���+�			��V�Z��s����c}����E����� �������~�)�����5"��0���������#��NbMM
N�>
���+ZL������f��R�'66���9���������9r�H��h�������6���m�.�]z����F���_�����&���X��;#F���z#�!��Es�T���f1	�9B���O�N�
������[�j=}��),,L��L�<��G}��={���x�
��'���""�>}:��Yi����`*,,��;��]���;EHc�p�#]�p�F�A]�v%�.���k�����222����l�����I,Syy9����q#K���OH,sB��[��p��������������R�m��^��_'"���S�.]H$���G^���Eh��mDDT^^��'u�h<H����]�&L ����IIKK�i������7EEE,��g�}��J�����Q]�����!�����9���.W��s\���8c#����
���h���b1}����]�b��JKK�#
Qfnn������L����E(���R*���	�sVRR�I���������\�e<|��D"�w�y�$	�?����9�zu��!��oeeEm���o��������1cu��dw�k��R��3u�?x����|��y$�Y��
H__�������������P������V����b�B7m�������dccC���^�cR������il�������[Y����I,Suu5UUU�X,����]�v��;wT�W"���6�*�M6|���^�����RMuE[�o��P6b����yi����SYY�u�)R�F�8���f�I666��K������@��o������H�;w�������������2Z�r%������7�=����������9��
s��!@q���7oR��S�N���H�7oV�{������.]��ggg����;��>}J�����G266&�`����&SSS���"��� �HD������9Y[[���5�������\��+W����#����:t�@�;w�=z���{i���e7n��m{���7�,,,����,,,h��!t��e����b�����Q�����V�^M���������;���sb�x��V�\Im���>}������{��dooOS�L���)(( ����������s��@  ___0`�\�UVV�������z����������H�9���5��u��������3',,,���P.��,			���OdjjJ���dkkKC�����Fe�|�2	�B�N�X,&�HD3g�l���6m��������+�h���0������xz��M�:�<<<����LMM����V�^-�8i�����&c<b�211!KKK���&333222��IMM�w�y�:v�H���daaAB��|}}9�����������h��Y4i�$�����]���			Q�G����(@T����bjjJfffrs���g���E����v�������Z�J�������#Gr�fffFr��TwE�����d#�����F��z=l��=�~�����;�����u�F�a���]����a��������aUUU!++vvvJC�H$dee���A�'�tUP�������W�HZJMM
?~�t�Nuu5<x{{{���7X��(**����akk���nS���333�H���'���������!�4��yqq1�����];������(..���{o�����Ct���AY


������Z�����b(�[\\���Bt��������������E��$T�������c�������)S���""�|�<@DDRRR �������%%%������U���"�����\�c6E�_�|����-E^^lll~v�>-������<{�m�����%%%�U���
������X�
��H$8::������,|_kG����Po�������ggg���i�����fdd����w�^��5<`�U)K���1���B�8�<<<����w������*}�������#�>}�s��qb������s'�,Y��K���o�iiq�U,X�{�����G1m������6����3'�G9�����y���#��� �Hp��5��rrr���s���5��7xxZ+.D���q��<{���������������--N�B�q�]�v�S�"�c����cdd��g����o��&,X���(\�~7o���?���?��P(Ddd$���[Zl�fGOOG�����N���(�4555���N�8���2^5?~�/������������p�<��_E���� �Hp��Y�={())���>���`oo����c��q*}}���U����3ff��)�G�|���8x� ~��7���������M�6���B�����H$		�����x�����������

�����b�����/b��U8t�\]][Z�W�����������y%������������y%�[�W�����������y%�[�1>�������o��(�:.^��7�x���--
�+C��q�QJnn.����q��i�kVW�4'D��;w������������li��������s'<==1u�T��HMBzz:�
�����G�^�qmm2m�����bcc��{������S)���	\]]��S�C;v>ds���_����u%���_[�Z#��l"�G!>����SMM��<>>>�����q�����������9 ��b��~���6�Y����i����s��4|�p���f�[����b*..�y����/�_�~���D999-&���������+wv����@;vd��
�3g�(,/00���k��n����[�j��k�@�5�1���g��������������8{���|B���;�h\Fc��V�B!�^������E���s���{�%i�o��6�<y�c������q���E��}����
###DDD���'�9sf��q��E\�x��-c�lll���/"11<@RR<==q��U������e�\y��?���M�W��k�@�5B���g��;�
8w������O�&$$ +++W������i���:g��u����,Y�����c��!!!3g������<-=����CUU����F\]]���8=z���i�^�z��o�a�����|��\���C�*|��<����%~<u��*���XXX�O�>J����E�2+���Y�b
�����C���8:���+W��@ ���K[Z�����I��V>����5k@��o�������=��U��W�.�S�[H�R___�c��.������������O�Fvv6���ww��G!�����]�t��5��[7t��YYY�v�f�o����i!IxxZ����W�.�Si�����Ghh(D"�����#G"**
111��pqq��������+W������s����0}�t>7n���o��1���LMM1c����#""�N�Bvv6:u��%K�`������q�����"55@���;w.�����g�����~�z$%%�G�X�n��k*��X9��������/���'���G�^��d��m�Va�J�f��q(((��]����jxyy!88X�������8u����KKKt���F�����a���~�:�<y}}}������s��A��9�kkk�d����������8}�4���/|���������/>�������}��5�������&M�{������������===t��3g��k�����R�b1����7n������8p ���0f�L�2E�1:y�$`��A*_���J���Bxx8���������Jxyy�{�����'bb"�l����h�o������P��n��j��F�M�6!==���O>�C�EBB������}}}���b���066!**
���Cvv6�������#  ����~~~�{�.<�a��52*-��g�8���d#!!x��LMM1x�`��=[����
R��UuY��UE�rU�W)�����WCCC�����>�����w/'�m��X�z5���K���!�P[[{{{���2��������T���4���h*�Z#4�K���*h�S�1NMBs�T�v������������������@g�����T6l���s������k��0a��s�~��Wrvv&}}}@�RZ�P(����S��]�������#2d�D"�}�6�����5k��7�`;���Ok��a�<{��z��A+W����P@~~~�NU�P�YN�8A������N���G���������,--����J�����kruu�/������)22����=z�H�1
cmuvv����SHH���Sxx8u���rv����P�N�M�8����KIII�y�f�D���O[�n��USSCAAAl������s�:w�L�7of;�g���Q~"�o��������x����:Z�l%$$��?�L���'��[o�D"���C����	���Rnn.���PRR��7���
4+�DB����~����j:�R.]�D^^^$
i��M���D�o����w���19::Rdd$����8
&___V���c)88����i�����F�u����%(""�f��M#G�������#OOO@>>>T\\L�F��������S�N���5�3f4��$doo�`��d�����J�}��,���'����,OHH��5�F�MKnnn���t�H3�@���������*���i�JQG�_�N�����M@zzz�d�z�����Ppp0������;g\.]�Dc��!����eKS�W���1�J���M�����
��Ts�SS�����	(((���,,,
0�^�x������,,,8a�f��A�_�~���:�(>>���\\\������F�u��=�n����LMM�i���4l�0""Z�z5 333�v6T�:�Hyz��'m��uL!j���!]�t�����`�>r��\��"����[TQQ�I���f����S����tv���/��U�Vt��U�:�����6b��u�������`}�i����FK,���!��K�r��H$4h� @k����~[[[����\�kkk����BBB��T%;;����?�h0���JD���E�������+���9BH(��k���7m���>~�x�r��W����X}���>����m�6����A�}�'}���,����Je�p��W���Y�����n�������S�����Oi�2��}���l�2N����Y��+W�yMm�:���.7�n�[���J����������Os�Y�h '''N�@"���H255U����^��uh
���R��a����h��6�8��fsl���H(���')--�u����9�����������(&&��;u�'�����b���;v����=KB��:v��Yl�t�Bh��1�zJKK�����?N���������(+C�rI :v��\9�P^^��6�W��w�����p�r�E���g��<��Mcybbb����rtt�S�s����_|�E�uN�<�s~�������U���,��7t�Pv>99YN�}��������Z���H$dllLzzz�b�
�|�2�|�������{�����*W�^erddd4�W�q;v,;���)w]EEs*�u�&����62�.<���r?V�=��,W�g�}��/\��T�������{�n��n*d�
ruu%777���K�������sn$(B��lll�����C,}��}�4um�����.7�njR�6������7�x�sM��=Y��'8i�F�����+l�6�P���]�!ES��)�A������%��;������;�z�-���o�|�w�RRR�qMM
���������c9��e�������%�E�1c� ??������<y�����/W�6m�	&������q�5T�:�,^�D+++L�4I����v\TT������9�]�t����[���@�U+���!)��������o����B��uqqq�q����������g��g�Fddd��}��_Jee%�\�����\��={2��}&���������o���[�n���/LMM��G,_�=z����[��*����f�����#E��VWWs�6v��I�:ccc�>yJJ
?~��,
�K����}}��������F6���\��VVV�XjZ���d��w����s�������1b������i�������A��D��J7�-W�~�Fz�������� 33p��e����y��JKKC||<.\�h?�;?���e�%M��Xo�R>]�l����� u������KN���D�H$���;�������0j�(N'>�7o�����uIw+����
���n===2B���=�m��7n'_Ce�ZNvv6�l����H�������*����3gggxyy�������c�X����������O�>ppp��%Kp��Idee�\vC���E~)���f�w�����������pssC�n���M����	���������};<<<p�����q]�h\322PYY	@~��,�i���:��>��������Ko���D�rZ#���&�AU��T��J7�)W�~�V-Z "���@�38~��2�� IDATx�_��n����C����E;4�)e�%M��Xo�z�tE�GE������3�Nzg����,}��!���.]BMM�������������V��������Pw7���P����IJJb��v��?�8P.���6?��9��'OV*���Sprr����

BUU�����O���p��5�c�%����8;;C �����9���oii��'O"##������7������T#00>��
���KJJ`cc�Q9R��l�
9g���U�#%%���r�@���2��]0]�7��mPUw4�������yY�����~���������x�b?~1116l<<<������Pl�����{��[����a�DW��?�f�y��=�x�����/�0GU�+J��i��}9�����>�c��q^7���`����������?�����O?����
���3QRR�����;����X9���,����,'N�@MM
���Oj�O?���/_�M����r����=�k*dc\z{{���s��AUU����Y�[��*333v�������4���1u�H$5j233�����b���HII����agg����(M]d[�9�)��lmm��KD��"�H�#/t��M���}�]�:uJ��M)�.�Ew���������;��G��T4�
���&��T���:/��z```��s�
1a�t�����@ ����w�}cccL�8Qk�uAk�]�+�����4�c+��^6V-�����;���%�������?�&���m����8&��1�����8�����J�X������'X��z���c����OOO��h��^�z�|���|��7oP�����9�
�����///x{{���������"���BMM
N�>
�n,PXX��z777�#m��0���0I�'Pgooo����
�����X��m9r$,,,�.���bjj
���vc�:�R���v|��9�k�����U��>))��%%%����P�N��y���9��>��q���/�{���c��!,,~�as��,hj��uu��t��u�>����y����III�?P�O���������O1o�<�����)�:6������Z����dwRo�������?~<�����/^���]���:^�|I�f�b�L�2�>|H���t��-v����	P-.duu5�+z���H$4}�t4h'����	�Z���>}J����V��CD4y�d@}�;���3z��7H �'�|"�D��vvvri������TXXH;v�]�v5�7
!�=oeeEm���o����URR����o����X��������4b�6�>>>t��5'S,������)����T�|����g���y�H,��
6���>	��cUVVQff&������%'��:�Pve��M���7o�$z������0a�?���|���i�;sssN$���drtt$�.HUU���>$�HD��w�!�DB���'sss�pY���D���:y�$�����X,���r""JII��[�������X,���j���"�XL.d��v��;w�(�s�|��}����@�G�V�GS�b1��bf����_'�X�4��2�7�XL7nd��|�	��b�����6h�;��rS����j��R��M"��'P������&
m���O���J���vh�.dol� R�.5W?h����8iK�;����'�.����;�����u�F�a��r��=5j��a��s��4�|�s�
4�,--����D��h��9(������H����.]����'���LLL$GGG���3�o���o��v��SVVF+W�$333������G��������3g����6��y�:t�@�:u"GGG��y�J��aaa���O������#�:u*yxx����������^���c���9Z�t)3������C;v,=}��bcc�G�dllLh��T]]MdnnN���dmmMdhh(�����OD4b�211!KKK���&333222��IMM�w�y�:v�H���daaAB��|}})!!A�����HOO�f��E�&M"kkk���+�����
FTT��6�O�q�%!!��������LMM����lmmi����`���@m��!'''����:��2y{{���)YYY���
YXX�H$��~����LMM��������9��g�(++�

9�off����{�&J����&{{{rss����7��bhhHfffdeeE���dccC���diiIm��i���i�����8�"����b�l�����.7�n�[�6�*�6�y��e
�
��b�D4s����U;�E���F�f���4����O�����sFF�>���{1k�,<x���Q��e)���(**�S���S������Rjjj���c�^�*TUU!++vvvJC"I$dee���A�'�T)C�r��������@����#���6WWW���������y�eiC^^lll�B�(�����?���m�<��/^���gh���Nd/))a�+**���ccc���i]6P7�QPP���tt��Y���WYJJJP[[�	i�
EEEx�����Mk�W�����4xyy���iii�D--R�@����4��M��M������)�/
?)��5����k����z�*�����������������|���K�,���K��7���8<,X�={������6mZK��������Y��������h�����<<<MOmm-
���T<x���C��p������+�����/�<�0���f�����c|������P�=$$O�<i��yxxd�����#G`dd��S��{<�OMM
`gg�'N�N-��4�JKK�������BTVV"##����Q=O=����1c����?��m�ZZ�%+W��X,�o��{{�������O��������HOOGPP�o�.��i�x�"V�Z�C�����������y%�[�W�f��OS�;�<<<<<<<<<��c����������J�;�<<<<<<<<<����������s�Nxzzb���044T�"���;Q^^����}xzz6��<���_�/������������~Z��F~~>���9:�6m��\�G����K���p��=6v�������2����R�E,Sqqq����_?@h��5�Q]]M$sssVV\\��%�iN
i����}�]:s�
		ii�Zw��%244d:���3����H=ta�t��E�����U�����:y%o
����o�����kQ9���������QB�W�^EHH����iaf���k�����?��#������������><==q��u���{����z��v���;w"66��������J:����CUUUK��u��A �C�X�d�Ve�H*��D"��z��Qpss������o_,_���%l��Bx=R
]�.]���*���������E�X�s�����9��$����(//�k������o[J$9x�����O��sl��;�]�v��KK������Gmx�����O�Y���"�����_��'O���xxx`��9�������b1����7n������8p ���0f�L�2�����e����k�w�FLL���X;v��+�����������===t��3g��k�������b��%(++CYY*++q��i���_���o���___|��066��}�p��5�������&M���3�n�*��� ??���������-V�^�����;>����}�*R9dw�o��%%%8u�����6m��[�nx���0t�P�e5�|����������?������@���������$������^^^���;aff��8l��	���ln~��':t(����������/���1�QQQ8w����aee��_Jw�k:�111�~�:����/^���SNwt!>>��KKKt���F���X�[�n�������!jkkQUU���{��o���(**�P(DUU�.]
����>��:��!��l��������Fjj*LLL0x�`��=[n�JIMM��'p��=<}����6l^�u���qqq��m|||Tngk�-��G@} Kuu5~���?999(++���5����%K���#u�L�uKW���4�.��������'���w)))�6o�L"�����i���r�:t�LLL(44�rss�������h��y�6l�@DDqqqL���l����c)88����i���reGGGS�-[���������z���H"�0�������������s�:w�L�7of��g��EDD�~�-���)���j�����)��=�|@"��&O�L7nl��Q�O��sud�>}:�������'m������h���dddDh���TPP WNS�"��?��f���d���/��W�^%"�K�.���	�B��i%%%����i���dllL�����8�[��|||�4{�l9r$EDDP\\yzz������b5jPTT�:u����	��1C��h2�iii4|�p@}�����S\\m���������N��Rd������w�N!!!O�����[7���$%%Qpp0����k'O�L7n����v�Z233#�7o��wOe�4������i�v)�;�G�������%777@C�U�����#�PH...t��a�����>���9g���e�i�����������l�&6�H3 %99����K���_���(JLL�e���5�������sI��<<������tf|}}9i�V�"$�/�������+W^mm-�����G��i�����J���,|���K9i��
Dh�����={�244�#F��[������a����J
���R����u�:w�L^^^��.����}�i���T�����rN��3gX���9i�1��rss�}�'-++�LMM	}��Wr�;r� �PH��]S�~UdIJJ�8�|���m���t����8�s��e�O�>��/KKK��0h� �����7Y�B��[o�%WOvv6YZZ2'E���k���/W�������bbb��K�kum
Q�����Y�l'}���,���+����8���/�p����	yzzRqq1-_��YzC�mk�-���66����lll
0�*++YZpp0��������sI�����-��6  ���s��1����/�y�DB������G+V����/���/Yz||��]U��C��|���r����#dggG�������8y�d���'�d�5i�"�v��}dddD������)m���;>�dk�O4�sU��c��=
�H���3g����1�vl����233�d���`Q�n�lc���b����Z�N���GY����������X��8i�����K�5���r��3F����92m�4�G�I�H$���D�����n��������\D��_Chbk�w"�i666rs���C,}��}��+V����4N����YZNN�Z2�f���^jc-Z��=r�'��?�$8p �����}��\�t���hK�nw
Gnn.�~�m���[���c�u��������7�Dmm-�n�
___����G�X�|9z��777�������+W�]�v����gO&Onn��r���������y�N���������;w.������&e�;>�P�'��sm����-?����d�.w��I.���1��������+-OY���}}���B��<X��ti�@���m{�^����9���;���No?��Su���u+K{��	�����g�i\�.��>MeC����48wd��������JN���/zzzjm\k���>
���6������o����z�����4\�zfff���s����2�u������_�)))���A���!�H�^���DEE�S~�X�X� 22��WK���TWW���t��0���D"�R��}��j�+�6�
dFll,���0g��e�����GY�������������T6m�CFF[��|�lZrr2'd���888h�.�&})�H������j�U������bNZPP���K���b���X�j������_���S����B��6T�:s�����W�������GDii)���,�����e�f�R���R �H�����7�FM�L����s��G�������

BUU�����O���p��5��g---q��Iddd�����y�&������b���������{{{�m���� "@zz:��m222R�)��k��1��u+�����,\����1b���h:>�Q�'��smy��;�.D�a>���������^�KY�A�����F~~>����-���DYg�s*>��c,]�/^�������Ga��=8x���sZW��]�P]��];"**
��9bcc��];$&&������gw�U�5���4�����m�����~�P����s�5�=���*BII	������*899!""�m@�K$�5
���pss�����~����������CNN233���w���S�fff�*q�������4U%�m��_
'''DGG�����'OFzz�F�h:>���}.E������jd���e�!������#�H��e``�n��5�,��i_�������4��* [����\���s�����P�Y�����4i�F�5���������j���g��EVV��]�3f &&X�nD"�Ze���u����~������/^���@�>Sw.i2���������;W��nxx�4�c[XX���
u�6d���K����$TTT >>^���}||0r�HXXX����zJJJ82��"�������C��ooo7�Fu��]�pqq���'!�PTT��c�r�������.������r�233q��@��]�"�)��/�`�����KOHH`wbV�Z�j?1�I_�Z���1R����R���<���NQMM
N�>
@~�H122�G}x��9���;�^�Z�/t5���������|�����o�A�6m0t�P������C�������66`��������������Z���;�~��;�4�{����;���0|���
e���������8���9n��=�SC0���BR4(i-��BBI���.��(�����D�� 2z�Z��a�Eu���R��aNT���������������lg�|��~��|���9l^+�J-Z�PE��ySy���eee(,,�L����|��
?�T������VT>{�������|��z�D���P(�����GY���OC�t:���)�Q>|����vX�V���)�����'O�V�����2�mhhH������,�����q������!����aKJJ����|>-���h��x�\����u:Z[[�v����� "8����^�xfbbv�����C�e|��Y�&Z��l6��
�x�YYY �)SU��������ne[��Y��F���hmmU>?v�dYF8F0�,�hhhP>�p�^�~���f���t:���������[��s������_�9�h��l6����������������1511���4����}�+��o>���X�k���eg��Q>?q�dY��_���ggg��2������on����6�.i�s������2}� �h��W�8���C]]����>�K��^�2���b�a,�����~>|X917m�����������{�.���`4AD8x� &&&������Z���v�����w���U	3*�/"Bjj*����H�Q�^����Fnn.RRR`�X������R���)���a���������������(���6l��j��n�$I0��w��a����������R9���@jj*l6,�z=ZZZ�}|����>�j������p�\0��q


����4�r�0S�3:��V�F��Rm������Jl��&�	V������e�]���~�����X��h�<|�`|����IDAT2� I��/��Q166���a�����}(A�}9[?���a��������<�����PUU���8���N�����cdd{��E~~>


`2�#Q��� "tuuin���9�"�+w�;�A���>�P�H��jjjR�S^^��II� �"�^���k)����9`��/_��r!++III�X,HMMEmm�_K�-����R<�w��udffb���x��i����\t�������(==}���~�_uk�����h����gzzz����������1JKK[�����]�M��,�R�yWW�R����T__O���466FN����D+��x��~�D"d��V��K%����|$I�r����/�D�`0��h$�^����}�����9{�,������%Q��DK���\S__O�s�N��g�2�hzz��������488H:��|>_�E�������br���8MNNRFF������Lk,���c��U��2��v�al���Nn��A�+W��$I(??�������a���.�y��


HE��?�SSS���K���t��U��������cE��c���7�����x����DDt��qJOO����Un�����K�$Q(����9����JJJZ��u0���}@c�!�Pcc#=�\y����������S�z��%������$�A����G�Qoo/����zzzh����}�v����m��������d���Sgg'%''���W)33sU������������H$B ���\h��0MMM��K����������O����@ @���t���$i���.�B!�������z����I������L��u+UUUiz��r������[�c�1��?��1�c,!���1�c�%��2�c����[�c�1�xb�c�1�Olc�1�XB��-c�1�K<�e�1�c	�'��1�c,!���1�c�%��2�c����!��6IEND�B`�
v6-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchtext/x-patch; charset=US-ASCII; name=v6-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchDownload
From 1581cf6412a3107136b9ace6d3d8dc171fd7d682 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v6 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

Back-patch to all supported releases.

Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 47 ++++++++++++++++++++---------
 src/backend/executor/nodeHashjoin.c | 40 ++++++++++++++----------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 58 insertions(+), 32 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index c5f2d1d22b..c41c86ab51 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
 	 * there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3048,14 +3055,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3175,9 +3179,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3193,17 +3205,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 510bdd39ad..a9c263c071 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -317,6 +323,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +336,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1106,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d74034f64f..d8edd39923 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.30.1

v6-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchtext/x-patch; charset=US-ASCII; name=v6-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From be00a279cb02e8076a5159f25f515de191ca5ed8 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v6 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.
---
 src/backend/executor/nodeHash.c     | 68 +++++++++++------------
 src/backend/executor/nodeHashjoin.c | 83 +++++++++++++++--------------
 src/backend/postmaster/pgstat.c     |  8 +--
 src/include/executor/hashjoin.h     | 38 ++++++-------
 src/include/pgstat.h                |  4 +-
 5 files changed, 102 insertions(+), 99 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index c41c86ab51..ef4e5d7568 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
 	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1067,7 +1067,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1076,7 +1076,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1194,13 +1194,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1213,7 +1213,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1268,7 +1268,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1508,7 +1508,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1517,7 +1517,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1546,13 +1546,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1708,7 +1708,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2862,7 +2862,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2982,7 +2982,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3057,7 +3057,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
 	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_DONE phase.
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3140,7 +3140,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3183,12 +3183,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3211,7 +3211,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index a9c263c071..3b1553fefe 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -322,10 +325,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -336,7 +339,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -347,7 +350,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1139,7 +1142,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1147,13 +1150,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1173,7 +1176,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1183,13 +1186,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1516,7 +1519,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1535,7 +1538,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index f75b52719d..137bc6eb32 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -4041,8 +4041,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -4056,8 +4056,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d8edd39923..176fbef149 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 724068cf87..5b9ae6fd56 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -971,12 +971,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.30.1

v6-0003-Parallel-Hash-Full-Right-Outer-Join.patchtext/x-patch; charset=US-ASCII; name=v6-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From 288bcf40acbb08d9f9f098ab7fc2782988093337 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v6 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 205 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 283 insertions(+), 92 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index ef4e5d7568..0b4658d5a4 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2053,16 +2054,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2076,60 +2133,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3135,13 +3242,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3288,6 +3388,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 3b1553fefe..db80bdf80f 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -379,9 +381,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -474,25 +486,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -550,7 +550,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1184,13 +1185,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 57ce97fd53..dd9e26dcd3 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1845,15 +1845,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -1887,9 +1881,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 176fbef149..fb0f1339d3 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 3fbe02e80d..7460dfff64 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.30.1

#11Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#10)
Re: Parallel Full Hash Join

On Fri, Mar 5, 2021 at 8:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

Feedback on
v6-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patch

I like renaming DONE to FREE and ALLOCATE TO REALLOCATE in the grow
barriers. FREE only makes sense for the Build barrier if you keep the
added PHJ_BUILD_RUN phase, though, I assume you would change this patch
if you decided not to add the new build barrier phase.

I like the addition of the asterisks to indicate a phase is executed by
a single arbitrary process. I was thinking, shall we add one of these to
HJ_FILL_INNER since it is only done by one process in parallel right and
full hash join? Maybe that's confusing because serial hash join uses
that state machine too, though. Maybe **? Maybe we should invent a
complicated symbolic language :)

One tiny, random, unimportant thing: The function prototype for
ExecParallelHashJoinPartitionOuter() calls its parameter "node" and, in
the definition, it is called "hjstate". This feels like a good patch to
throw in that tiny random change to make the name the same.

static void ExecParallelHashJoinPartitionOuter(HashJoinState *node);

static void
ExecParallelHashJoinPartitionOuter(HashJoinState *hjstate)

#12Zhihong Yu
zyu@yugabyte.com
In reply to: Thomas Munro (#10)
Re: Parallel Full Hash Join

Hi,
For v6-0003-Parallel-Hash-Full-Right-Outer-Join.patch

+ * current_chunk_idx: index in current HashMemoryChunk

The above comment seems to be better fit
for ExecScanHashTableForUnmatched(), instead
of ExecParallelPrepHashTableForUnmatched.
I wonder where current_chunk_idx should belong (considering the above
comment and what the code does).

+       while (hashtable->current_chunk_idx <
hashtable->current_chunk->used)
...
+       next = hashtable->current_chunk->next.unshared;
+       hashtable->current_chunk = next;
+       hashtable->current_chunk_idx = 0;

Each time we advance to the next chunk, current_chunk_idx is reset. It
seems current_chunk_idx can be placed inside chunk.
Maybe the consideration is that, with the current formation we save space
by putting current_chunk_idx field at a higher level.
If that is the case, a comment should be added.

Cheers

On Fri, Mar 5, 2021 at 5:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

Show quoted text

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com>
wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

#13Melanie Plageman
melanieplageman@gmail.com
In reply to: Zhihong Yu (#12)
Re: Parallel Full Hash Join

On Fri, Apr 2, 2021 at 3:06 PM Zhihong Yu <zyu@yugabyte.com> wrote:

Hi,
For v6-0003-Parallel-Hash-Full-Right-Outer-Join.patch

+ * current_chunk_idx: index in current HashMemoryChunk

The above comment seems to be better fit for ExecScanHashTableForUnmatched(), instead of ExecParallelPrepHashTableForUnmatched.
I wonder where current_chunk_idx should belong (considering the above comment and what the code does).

+       while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
...
+       next = hashtable->current_chunk->next.unshared;
+       hashtable->current_chunk = next;
+       hashtable->current_chunk_idx = 0;

Each time we advance to the next chunk, current_chunk_idx is reset. It seems current_chunk_idx can be placed inside chunk.
Maybe the consideration is that, with the current formation we save space by putting current_chunk_idx field at a higher level.
If that is the case, a comment should be added.

Thank you for the review. I think that moving the current_chunk_idx into
the HashMemoryChunk would probably take up too much space.

Other places that we loop through the tuples in the chunk, we are able
to just keep a local idx, like here in
ExecParallelHashIncreaseNumBuckets():

case PHJ_GROW_BUCKETS_REINSERTING:
...
while ((chunk = ExecParallelHashPopChunkQueue(hashtable, &chunk_s)))
{
size_t idx = 0;

while (idx < chunk->used)

but, since we cannot do that while also emitting tuples, I thought,
let's just stash the index in the hashtable for use in serial hash join
and the batch accessor for parallel hash join. A comment to this effect
sounds good to me.

#14Zhihong Yu
zyu@yugabyte.com
In reply to: Melanie Plageman (#13)
Re: Parallel Full Hash Join

On Tue, Apr 6, 2021 at 11:59 AM Melanie Plageman <melanieplageman@gmail.com>
wrote:

On Fri, Apr 2, 2021 at 3:06 PM Zhihong Yu <zyu@yugabyte.com> wrote:

Hi,
For v6-0003-Parallel-Hash-Full-Right-Outer-Join.patch

+ * current_chunk_idx: index in current HashMemoryChunk

The above comment seems to be better fit for

ExecScanHashTableForUnmatched(), instead of
ExecParallelPrepHashTableForUnmatched.

I wonder where current_chunk_idx should belong (considering the above

comment and what the code does).

+ while (hashtable->current_chunk_idx <

hashtable->current_chunk->used)

...
+       next = hashtable->current_chunk->next.unshared;
+       hashtable->current_chunk = next;
+       hashtable->current_chunk_idx = 0;

Each time we advance to the next chunk, current_chunk_idx is reset. It

seems current_chunk_idx can be placed inside chunk.

Maybe the consideration is that, with the current formation we save

space by putting current_chunk_idx field at a higher level.

If that is the case, a comment should be added.

Thank you for the review. I think that moving the current_chunk_idx into
the HashMemoryChunk would probably take up too much space.

Other places that we loop through the tuples in the chunk, we are able
to just keep a local idx, like here in
ExecParallelHashIncreaseNumBuckets():

case PHJ_GROW_BUCKETS_REINSERTING:
...
while ((chunk = ExecParallelHashPopChunkQueue(hashtable,
&chunk_s)))
{
size_t idx = 0;

while (idx < chunk->used)

but, since we cannot do that while also emitting tuples, I thought,
let's just stash the index in the hashtable for use in serial hash join
and the batch accessor for parallel hash join. A comment to this effect
sounds good to me.

From the way HashJoinTable is used, I don't have better idea w.r.t. the
location of current_chunk_idx.
It is not worth introducing another level of mapping between HashJoinTable
and the chunk index.

So the current formation is fine with additional comment
in ParallelHashJoinBatchAccessor (current comment doesn't explicitly
mention current_chunk_idx).

Cheers

#15Greg Nancarrow
gregn4422@gmail.com
In reply to: Thomas Munro (#10)
Re: Parallel Full Hash Join

On Sat, Mar 6, 2021 at 12:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

Patches 0002, 0003 no longer apply to the master branch, seemingly
because of subsequent changes to pgstat, so need rebasing.

Regards,
Greg Nancarrow
Fujitsu Australia

#16vignesh C
vignesh21@gmail.com
In reply to: Greg Nancarrow (#15)
Re: Parallel Full Hash Join

On Mon, May 31, 2021 at 10:47 AM Greg Nancarrow <gregn4422@gmail.com> wrote:

On Sat, Mar 6, 2021 at 12:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

Patches 0002, 0003 no longer apply to the master branch, seemingly
because of subsequent changes to pgstat, so need rebasing.

I am changing the status to "Waiting on Author" as the patch does not
apply on Head.

Regards,
Vignesh

#17Melanie Plageman
melanieplageman@gmail.com
In reply to: vignesh C (#16)
3 attachment(s)
Re: Parallel Full Hash Join

On Sat, Jul 10, 2021 at 9:13 AM vignesh C <vignesh21@gmail.com> wrote:

On Mon, May 31, 2021 at 10:47 AM Greg Nancarrow <gregn4422@gmail.com> wrote:

On Sat, Mar 6, 2021 at 12:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so
I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

Patches 0002, 0003 no longer apply to the master branch, seemingly
because of subsequent changes to pgstat, so need rebasing.

I am changing the status to "Waiting on Author" as the patch does not
apply on Head.

Regards,
Vignesh

Rebased patches attached. I will change status back to "Ready for Committer"

Attachments:

v7-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchtext/x-patch; charset=US-ASCII; name=v7-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From 8771e5fe531023d86da67b539ff57d4845171cae Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v7 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.
---
 src/backend/executor/nodeHash.c         | 68 ++++++++++----------
 src/backend/executor/nodeHashjoin.c     | 83 +++++++++++++------------
 src/backend/utils/activity/wait_event.c |  8 +--
 src/include/executor/hashjoin.h         | 38 +++++------
 src/include/utils/wait_event.h          |  4 +-
 5 files changed, 102 insertions(+), 99 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index db5d46b23f..3ba688e8e0 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
 	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1086,7 +1086,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1095,7 +1095,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1211,13 +1211,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1230,7 +1230,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1285,7 +1285,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1525,7 +1525,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1534,7 +1534,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1563,13 +1563,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1725,7 +1725,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2879,7 +2879,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2999,7 +2999,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3074,7 +3074,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
 	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_DONE phase.
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3157,7 +3157,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3200,12 +3200,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3228,7 +3228,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index a9c263c071..3b1553fefe 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -322,10 +325,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -336,7 +339,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -347,7 +350,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1139,7 +1142,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1147,13 +1150,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1173,7 +1176,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1183,13 +1186,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1516,7 +1519,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1535,7 +1538,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index ef7e6bfb77..2f3c1a241b 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -361,8 +361,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -376,8 +376,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d8edd39923..176fbef149 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 6007827b44..a9c6a9b108 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -96,12 +96,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.27.0

v7-0003-Parallel-Hash-Full-Right-Outer-Join.patchtext/x-patch; charset=US-ASCII; name=v7-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From 954bc84ca79e217c216c0ed8160853c49c19b609 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v7 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 205 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 283 insertions(+), 92 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 3ba688e8e0..e7d420ee12 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2070,16 +2071,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2093,60 +2150,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3152,13 +3259,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3305,6 +3405,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 3b1553fefe..db80bdf80f 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -379,9 +381,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -474,25 +486,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -550,7 +550,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1184,13 +1185,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 6407ede12a..06cee346d1 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2091,15 +2091,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2133,9 +2127,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 176fbef149..fb0f1339d3 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 3fbe02e80d..7460dfff64 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.27.0

v7-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchtext/x-patch; charset=US-ASCII; name=v7-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchDownload
From 783e83d52a9fd80cdd389308201e2b0824efb600 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v7 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

Back-patch to all supported releases.

Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 47 ++++++++++++++++++++---------
 src/backend/executor/nodeHashjoin.c | 40 ++++++++++++++----------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 58 insertions(+), 32 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 73eb074cbf..db5d46b23f 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
 	 * there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3065,14 +3072,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3192,9 +3196,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3210,17 +3222,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 510bdd39ad..a9c263c071 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -317,6 +323,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +336,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1106,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d74034f64f..d8edd39923 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.27.0

#18Jaime Casanova
jcasanov@systemguards.com.ec
In reply to: Melanie Plageman (#17)
Re: Parallel Full Hash Join

On Fri, Jul 30, 2021 at 04:34:34PM -0400, Melanie Plageman wrote:

On Sat, Jul 10, 2021 at 9:13 AM vignesh C <vignesh21@gmail.com> wrote:

On Mon, May 31, 2021 at 10:47 AM Greg Nancarrow <gregn4422@gmail.com> wrote:

On Sat, Mar 6, 2021 at 12:31 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Mar 2, 2021 at 11:27 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Feb 12, 2021 at 11:02 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I just attached the diff.

Squashed into one patch for the cfbot to chew on, with a few minor
adjustments to a few comments.

I did some more minor tidying of comments and naming. It's been on my
to-do-list to update some phase names after commit 3048898e, and while
doing that I couldn't resist the opportunity to change DONE to FREE,
which somehow hurts my brain less, and makes much more obvious sense
after the bugfix in CF #3031 that splits DONE into two separate
phases. It also pairs obviously with ALLOCATE. I include a copy of
that bugix here too as 0001, because I'll likely commit that first, so

Hi Thomas,

Do you intend to commit 0001 soon? Specially if this apply to 14 should
be committed in the next days.

I rebased the stack of patches that way. 0002 includes the renaming I
propose (master only). Then 0003 is Melanie's patch, using the name
SCAN for the new match bit scan phase. I've attached an updated
version of my "phase diagram" finger painting, to show how it looks
with these three patches. "scan*" is new.

0002: my only concern is that this will cause innecesary pain in
backpatch-ing future code... but not doing that myself will let that to
the experts

0003: i'm testing this now, not at a big scale but just to try to find
problems

--
Jaime Casanova
Director de Servicios Profesionales
SystemGuards - Consultores de PostgreSQL

#19Thomas Munro
thomas.munro@gmail.com
In reply to: Jaime Casanova (#18)
Re: Parallel Full Hash Join

On Tue, Sep 21, 2021 at 9:29 AM Jaime Casanova
<jcasanov@systemguards.com.ec> wrote:

Do you intend to commit 0001 soon? Specially if this apply to 14 should
be committed in the next days.

Thanks for the reminder. Yes, I'm looking at this now, and looking
into the crash of this patch set on CI:

https://cirrus-ci.com/task/5282889613967360

Unfortunately, cfbot is using very simple and old CI rules which don't
have a core dump analysis step on that OS. :-( (I have a big upgrade
to all this CI stuff in the pipeline to fix that, get full access to
all logs, go faster, and many other improvements, after learning a lot
of tricks about running these types of systems over the past year --
more soon.)

0003: i'm testing this now, not at a big scale but just to try to find
problems

Thanks!

#20Justin Pryzby
pryzby@telsasoft.com
In reply to: Melanie Plageman (#17)
Re: Parallel Full Hash Join

Rebased patches attached. I will change status back to "Ready for Committer"

The CI showed a crash on freebsd, which I reproduced.
https://cirrus-ci.com/task/5203060415791104

The crash is evidenced in 0001 - but only ~15% of the time.

I think it's the same thing which was committed and then reverted here, so
maybe I'm not saying anything new.

https://commitfest.postgresql.org/33/3031/
/messages/by-id/20200929061142.GA29096@paquier.xyz

(gdb) p pstate->build_barrier->phase
Cannot access memory at address 0x7f82e0fa42f4

#1 0x00007f13de34f801 in __GI_abort () at abort.c:79
#2 0x00005638e6a16d28 in ExceptionalCondition (conditionName=conditionName@entry=0x5638e6b62850 "!pstate || BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN",
errorType=errorType@entry=0x5638e6a6f00b "FailedAssertion", fileName=fileName@entry=0x5638e6b625be "nodeHash.c", lineNumber=lineNumber@entry=3305) at assert.c:69
#3 0x00005638e678085b in ExecHashTableDetach (hashtable=0x5638e8e6ca88) at nodeHash.c:3305
#4 0x00005638e6784656 in ExecShutdownHashJoin (node=node@entry=0x5638e8e57cb8) at nodeHashjoin.c:1400
#5 0x00005638e67666d8 in ExecShutdownNode (node=0x5638e8e57cb8) at execProcnode.c:812
#6 ExecShutdownNode (node=0x5638e8e57cb8) at execProcnode.c:772
#7 0x00005638e67cd5b1 in planstate_tree_walker (planstate=planstate@entry=0x5638e8e58580, walker=walker@entry=0x5638e6766680 <ExecShutdownNode>, context=context@entry=0x0) at nodeFuncs.c:4009
#8 0x00005638e67666b2 in ExecShutdownNode (node=0x5638e8e58580) at execProcnode.c:792
#9 ExecShutdownNode (node=0x5638e8e58580) at execProcnode.c:772
#10 0x00005638e67cd5b1 in planstate_tree_walker (planstate=planstate@entry=0x5638e8e58418, walker=walker@entry=0x5638e6766680 <ExecShutdownNode>, context=context@entry=0x0) at nodeFuncs.c:4009
#11 0x00005638e67666b2 in ExecShutdownNode (node=0x5638e8e58418) at execProcnode.c:792
#12 ExecShutdownNode (node=node@entry=0x5638e8e58418) at execProcnode.c:772
#13 0x00005638e675f518 in ExecutePlan (execute_once=<optimized out>, dest=0x5638e8df0058, direction=<optimized out>, numberTuples=0, sendTuples=<optimized out>, operation=CMD_SELECT,
use_parallel_mode=<optimized out>, planstate=0x5638e8e58418, estate=0x5638e8e57a10) at execMain.c:1658
#14 standard_ExecutorRun () at execMain.c:410
#15 0x00005638e6763e0a in ParallelQueryMain (seg=0x5638e8d823d8, toc=0x7f13df4e9000) at execParallel.c:1493
#16 0x00005638e663f6c7 in ParallelWorkerMain () at parallel.c:1495
#17 0x00005638e68542e4 in StartBackgroundWorker () at bgworker.c:858
#18 0x00005638e6860f53 in do_start_bgworker (rw=<optimized out>) at postmaster.c:5883
#19 maybe_start_bgworkers () at postmaster.c:6108
#20 0x00005638e68619e5 in sigusr1_handler (postgres_signal_arg=<optimized out>) at postmaster.c:5272
#21 <signal handler called>
#22 0x00007f13de425ff7 in __GI___select (nfds=nfds@entry=7, readfds=readfds@entry=0x7ffef03b8400, writefds=writefds@entry=0x0, exceptfds=exceptfds@entry=0x0, timeout=timeout@entry=0x7ffef03b8360)
at ../sysdeps/unix/sysv/linux/select.c:41
#23 0x00005638e68620ce in ServerLoop () at postmaster.c:1765
#24 0x00005638e6863bcc in PostmasterMain () at postmaster.c:1473
#25 0x00005638e658fd00 in main (argc=8, argv=0x5638e8d54730) at main.c:198

#21Melanie Plageman
melanieplageman@gmail.com
In reply to: Justin Pryzby (#20)
3 attachment(s)
Re: Parallel Full Hash Join

On Sat, Nov 6, 2021 at 11:04 PM Justin Pryzby <pryzby@telsasoft.com> wrote:

Rebased patches attached. I will change status back to "Ready for Committer"

The CI showed a crash on freebsd, which I reproduced.
https://cirrus-ci.com/task/5203060415791104

The crash is evidenced in 0001 - but only ~15% of the time.

I think it's the same thing which was committed and then reverted here, so
maybe I'm not saying anything new.

https://commitfest.postgresql.org/33/3031/
/messages/by-id/20200929061142.GA29096@paquier.xyz

(gdb) p pstate->build_barrier->phase
Cannot access memory at address 0x7f82e0fa42f4

#1 0x00007f13de34f801 in __GI_abort () at abort.c:79
#2 0x00005638e6a16d28 in ExceptionalCondition (conditionName=conditionName@entry=0x5638e6b62850 "!pstate || BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN",
errorType=errorType@entry=0x5638e6a6f00b "FailedAssertion", fileName=fileName@entry=0x5638e6b625be "nodeHash.c", lineNumber=lineNumber@entry=3305) at assert.c:69
#3 0x00005638e678085b in ExecHashTableDetach (hashtable=0x5638e8e6ca88) at nodeHash.c:3305
#4 0x00005638e6784656 in ExecShutdownHashJoin (node=node@entry=0x5638e8e57cb8) at nodeHashjoin.c:1400
#5 0x00005638e67666d8 in ExecShutdownNode (node=0x5638e8e57cb8) at execProcnode.c:812
#6 ExecShutdownNode (node=0x5638e8e57cb8) at execProcnode.c:772
#7 0x00005638e67cd5b1 in planstate_tree_walker (planstate=planstate@entry=0x5638e8e58580, walker=walker@entry=0x5638e6766680 <ExecShutdownNode>, context=context@entry=0x0) at nodeFuncs.c:4009
#8 0x00005638e67666b2 in ExecShutdownNode (node=0x5638e8e58580) at execProcnode.c:792
#9 ExecShutdownNode (node=0x5638e8e58580) at execProcnode.c:772
#10 0x00005638e67cd5b1 in planstate_tree_walker (planstate=planstate@entry=0x5638e8e58418, walker=walker@entry=0x5638e6766680 <ExecShutdownNode>, context=context@entry=0x0) at nodeFuncs.c:4009
#11 0x00005638e67666b2 in ExecShutdownNode (node=0x5638e8e58418) at execProcnode.c:792
#12 ExecShutdownNode (node=node@entry=0x5638e8e58418) at execProcnode.c:772
#13 0x00005638e675f518 in ExecutePlan (execute_once=<optimized out>, dest=0x5638e8df0058, direction=<optimized out>, numberTuples=0, sendTuples=<optimized out>, operation=CMD_SELECT,
use_parallel_mode=<optimized out>, planstate=0x5638e8e58418, estate=0x5638e8e57a10) at execMain.c:1658
#14 standard_ExecutorRun () at execMain.c:410
#15 0x00005638e6763e0a in ParallelQueryMain (seg=0x5638e8d823d8, toc=0x7f13df4e9000) at execParallel.c:1493
#16 0x00005638e663f6c7 in ParallelWorkerMain () at parallel.c:1495
#17 0x00005638e68542e4 in StartBackgroundWorker () at bgworker.c:858
#18 0x00005638e6860f53 in do_start_bgworker (rw=<optimized out>) at postmaster.c:5883
#19 maybe_start_bgworkers () at postmaster.c:6108
#20 0x00005638e68619e5 in sigusr1_handler (postgres_signal_arg=<optimized out>) at postmaster.c:5272
#21 <signal handler called>
#22 0x00007f13de425ff7 in __GI___select (nfds=nfds@entry=7, readfds=readfds@entry=0x7ffef03b8400, writefds=writefds@entry=0x0, exceptfds=exceptfds@entry=0x0, timeout=timeout@entry=0x7ffef03b8360)
at ../sysdeps/unix/sysv/linux/select.c:41
#23 0x00005638e68620ce in ServerLoop () at postmaster.c:1765
#24 0x00005638e6863bcc in PostmasterMain () at postmaster.c:1473
#25 0x00005638e658fd00 in main (argc=8, argv=0x5638e8d54730) at main.c:198

Yes, this looks like that issue.

I've attached a v8 set with the fix I suggested in [1]/messages/by-id/20200929061142.GA29096@paquier.xyz included.
(I added it to 0001).

- Melanie

[1]: /messages/by-id/20200929061142.GA29096@paquier.xyz

Attachments:

v8-0003-Parallel-Hash-Full-Right-Outer-Join.patchapplication/octet-stream; name=v8-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From 05b543dfc54a30538e408ed898e7682a954df6b9 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v8 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 205 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 283 insertions(+), 92 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 3ba688e8e0..e7d420ee12 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2070,16 +2071,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2093,60 +2150,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3152,13 +3259,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3305,6 +3405,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 8d2d0f4070..145c075151 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -394,9 +396,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -489,25 +501,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -565,7 +565,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1199,13 +1200,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 0f3ad8aa65..07726e84c8 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2106,15 +2106,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2148,9 +2142,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 176fbef149..fb0f1339d3 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 3fbe02e80d..7460dfff64 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.32.0

v8-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchapplication/octet-stream; name=v8-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From e4c52dcca63e746e4afa6965df1c5163f6bbd1e1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v8 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.
---
 src/backend/executor/nodeHash.c         | 68 +++++++++---------
 src/backend/executor/nodeHashjoin.c     | 91 +++++++++++++------------
 src/backend/utils/activity/wait_event.c |  8 +--
 src/include/executor/hashjoin.h         | 38 +++++------
 src/include/utils/wait_event.h          |  4 +-
 5 files changed, 106 insertions(+), 103 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index db5d46b23f..3ba688e8e0 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
 	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1086,7 +1086,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1095,7 +1095,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1211,13 +1211,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1230,7 +1230,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1285,7 +1285,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1525,7 +1525,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1534,7 +1534,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1563,13 +1563,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1725,7 +1725,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2879,7 +2879,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2999,7 +2999,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3074,7 +3074,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
 	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_DONE phase.
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3157,7 +3157,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3200,12 +3200,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3228,7 +3228,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 6db150b230..8d2d0f4070 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -306,12 +309,12 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (parallel)
 					{
 						/*
-						 * Advance the build barrier to PHJ_BUILD_RUNNING
-						 * before proceeding to cleanup to comply with build
-						 * barrier safety requirements.
+						 * Advance the build barrier to PHJ_BUILD_RUN before
+						 * proceeding to cleanup to comply with build barrier
+						 * safety requirements.
 						 */
 						Barrier *build_barrier = &parallel_state->build_barrier;
-						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUN)
 							BarrierArriveAndWait(build_barrier, 0);
 
 						BarrierDetach(build_barrier);
@@ -337,10 +340,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -351,7 +354,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -362,7 +365,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1154,7 +1157,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1162,13 +1165,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1188,7 +1191,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1198,13 +1201,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1531,7 +1534,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1550,7 +1553,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 4a5b7502f5..7eb1d8a739 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -361,8 +361,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -376,8 +376,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d8edd39923..176fbef149 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index c22142365f..c9cdc51a3b 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -96,12 +96,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.32.0

v8-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchapplication/octet-stream; name=v8-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchDownload
From 1bcc0528a3d9a0278810858eb11d541a762e2ea2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v8 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

The build barrier must make it to PHJ_BUILD_DONE before shared resources
can be safely destroyed. This works fine in most cases with the addition
of another synchronization point. However, when the inner side is empty,
the build barrier will only make it to PHJ_BUILD_HASHING_INNER before
workers attempt to detach from the hashtable. In the case of the empty
inner optimization, advance the build barrier to PHJ_BUILD_RUNNING
before proceeding to cleanup. See batch 0 batch barrier fast forward in
ExecParallelHashJoinSetUpBatches() for precedent.

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

Back-patch to all supported releases.

Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 47 ++++++++++++++++--------
 src/backend/executor/nodeHashjoin.c | 55 ++++++++++++++++++++---------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 73eb074cbf..db5d46b23f 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
 	 * there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3065,14 +3072,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3192,9 +3196,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3210,17 +3222,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 510bdd39ad..6db150b230 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -296,7 +302,22 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * outer relation.
 				 */
 				if (hashtable->totalTuples == 0 && !HJ_FILL_OUTER(node))
+				{
+					if (parallel)
+					{
+						/*
+						 * Advance the build barrier to PHJ_BUILD_RUNNING
+						 * before proceeding to cleanup to comply with build
+						 * barrier safety requirements.
+						 */
+						Barrier *build_barrier = &parallel_state->build_barrier;
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+							BarrierArriveAndWait(build_barrier, 0);
+
+						BarrierDetach(build_barrier);
+					}
 					return NULL;
+				}
 
 				/*
 				 * need to remember whether nbatch has increased since we
@@ -317,6 +338,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +351,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1121,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d74034f64f..d8edd39923 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.32.0

#22Melanie Plageman
melanieplageman@gmail.com
In reply to: Melanie Plageman (#21)
3 attachment(s)
Re: Parallel Full Hash Join

small mistake in v8.
v9 attached.

- Melanie

Attachments:

v9-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchapplication/octet-stream; name=v9-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From 55b5745ca76cc0dca130b2a77144f5ece3c80e79 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v9 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.
---
 src/backend/executor/nodeHash.c         | 68 +++++++++---------
 src/backend/executor/nodeHashjoin.c     | 91 +++++++++++++------------
 src/backend/utils/activity/wait_event.c |  8 +--
 src/include/executor/hashjoin.h         | 38 +++++------
 src/include/utils/wait_event.h          |  4 +-
 5 files changed, 106 insertions(+), 103 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index db5d46b23f..3ba688e8e0 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
 	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1086,7 +1086,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1095,7 +1095,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1211,13 +1211,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1230,7 +1230,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1285,7 +1285,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1525,7 +1525,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1534,7 +1534,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1563,13 +1563,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1725,7 +1725,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2879,7 +2879,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2999,7 +2999,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3074,7 +3074,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
 	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_DONE phase.
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3157,7 +3157,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3200,12 +3200,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3228,7 +3228,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 065294c3f7..464d2e33fb 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -306,12 +309,12 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (parallel)
 					{
 						/*
-						 * Advance the build barrier to PHJ_BUILD_RUNNING
-						 * before proceeding to cleanup to comply with build
-						 * barrier safety requirements.
+						 * Advance the build barrier to PHJ_BUILD_RUN before
+						 * proceeding to cleanup to comply with build barrier
+						 * safety requirements.
 						 */
 						Barrier *build_barrier = &parallel_state->build_barrier;
-						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUN)
 							BarrierArriveAndWait(build_barrier, 0);
 					}
 					return NULL;
@@ -335,10 +338,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -349,7 +352,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -360,7 +363,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1152,7 +1155,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1160,13 +1163,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1186,7 +1189,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1196,13 +1199,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1529,7 +1532,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1548,7 +1551,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 4a5b7502f5..7eb1d8a739 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -361,8 +361,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -376,8 +376,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d8edd39923..176fbef149 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index c22142365f..c9cdc51a3b 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -96,12 +96,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.32.0

v9-0003-Parallel-Hash-Full-Right-Outer-Join.patchapplication/octet-stream; name=v9-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From cf095d361e0e50d76b7a9f8273d8cf31e1f45f0a Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v9 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 205 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 283 insertions(+), 92 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 3ba688e8e0..e7d420ee12 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2070,16 +2071,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2093,60 +2150,110 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(hashtable->current_chunk) +
+													   hashtable->current_chunk_idx);
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again. Instead, all workers except the last will detach and the last
+	 * will conduct this unmatched inner tuple scan.
+	 */
+	Assert(BarrierParticipants(&accessor->shared->batch_barrier) == 1);
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(accessor->current_chunk) +
+													   accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+															  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area, accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3152,13 +3259,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3305,6 +3405,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 464d2e33fb..a1b345aad0 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -392,9 +394,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -487,25 +499,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -563,7 +563,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1197,13 +1198,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 0f3ad8aa65..07726e84c8 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2106,15 +2106,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2148,9 +2142,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 176fbef149..fb0f1339d3 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index 3fbe02e80d..7460dfff64 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.32.0

v9-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchapplication/octet-stream; name=v9-0001-Fix-race-condition-in-parallel-hash-join-batch-cl.patchDownload
From 03500cdf223b67b65d0c433e9198b4bb5e5a8e3b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v9 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

The build barrier must make it to PHJ_BUILD_DONE before shared resources
can be safely destroyed. This works fine in most cases with the addition
of another synchronization point. However, when the inner side is empty,
the build barrier will only make it to PHJ_BUILD_HASHING_INNER before
workers attempt to detach from the hashtable. In the case of the empty
inner optimization, advance the build barrier to PHJ_BUILD_RUNNING
before proceeding to cleanup. See batch 0 batch barrier fast forward in
ExecParallelHashJoinSetUpBatches() for precedent.

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

Back-patch to all supported releases.

Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 47 +++++++++++++++++--------
 src/backend/executor/nodeHashjoin.c | 53 ++++++++++++++++++++---------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 73eb074cbf..db5d46b23f 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
 	 * there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3065,14 +3072,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3192,9 +3196,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3210,17 +3222,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 510bdd39ad..065294c3f7 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -296,7 +302,20 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * outer relation.
 				 */
 				if (hashtable->totalTuples == 0 && !HJ_FILL_OUTER(node))
+				{
+					if (parallel)
+					{
+						/*
+						 * Advance the build barrier to PHJ_BUILD_RUNNING
+						 * before proceeding to cleanup to comply with build
+						 * barrier safety requirements.
+						 */
+						Barrier *build_barrier = &parallel_state->build_barrier;
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+							BarrierArriveAndWait(build_barrier, 0);
+					}
 					return NULL;
+				}
 
 				/*
 				 * need to remember whether nbatch has increased since we
@@ -317,6 +336,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +349,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1119,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d74034f64f..d8edd39923 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.32.0

#23Justin Pryzby
pryzby@telsasoft.com
In reply to: Melanie Plageman (#21)
Re: Parallel Full Hash Join

On Wed, Nov 17, 2021 at 01:45:06PM -0500, Melanie Plageman wrote:

On Sat, Nov 6, 2021 at 11:04 PM Justin Pryzby <pryzby@telsasoft.com> wrote:

Rebased patches attached. I will change status back to "Ready for Committer"

The CI showed a crash on freebsd, which I reproduced.
https://cirrus-ci.com/task/5203060415791104

The crash is evidenced in 0001 - but only ~15% of the time.

I think it's the same thing which was committed and then reverted here, so
maybe I'm not saying anything new.

https://commitfest.postgresql.org/33/3031/
/messages/by-id/20200929061142.GA29096@paquier.xyz

Yes, this looks like that issue.

I've attached a v8 set with the fix I suggested in [1] included.
(I added it to 0001).

This is still crashing :(
https://cirrus-ci.com/task/6738329224871936
https://cirrus-ci.com/task/4895130286030848

--
Justin

#24Thomas Munro
thomas.munro@gmail.com
In reply to: Justin Pryzby (#23)
Re: Parallel Full Hash Join

On Sun, Nov 21, 2021 at 4:48 PM Justin Pryzby <pryzby@telsasoft.com> wrote:

On Wed, Nov 17, 2021 at 01:45:06PM -0500, Melanie Plageman wrote:

Yes, this looks like that issue.

I've attached a v8 set with the fix I suggested in [1] included.
(I added it to 0001).

This is still crashing :(
https://cirrus-ci.com/task/6738329224871936
https://cirrus-ci.com/task/4895130286030848

I added a core file backtrace to cfbot's CI recipe a few days ago, so
now we have:

https://cirrus-ci.com/task/5676480098205696

#3 0x00000000009cf57e in ExceptionalCondition (conditionName=0x29cae8
"BarrierParticipants(&accessor->shared->batch_barrier) == 1",
errorType=<optimized out>, fileName=0x2ae561 "nodeHash.c",
lineNumber=lineNumber@entry=2224) at assert.c:69
No locals.
#4 0x000000000071575e in ExecParallelScanHashTableForUnmatched
(hjstate=hjstate@entry=0x80a60a3c8,
econtext=econtext@entry=0x80a60ae98) at nodeHash.c:2224

#25Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#24)
3 attachment(s)
Re: Parallel Full Hash Join

On Fri, Nov 26, 2021 at 3:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Sun, Nov 21, 2021 at 4:48 PM Justin Pryzby <pryzby@telsasoft.com> wrote:

On Wed, Nov 17, 2021 at 01:45:06PM -0500, Melanie Plageman wrote:

Yes, this looks like that issue.

I've attached a v8 set with the fix I suggested in [1] included.
(I added it to 0001).

This is still crashing :(
https://cirrus-ci.com/task/6738329224871936
https://cirrus-ci.com/task/4895130286030848

I added a core file backtrace to cfbot's CI recipe a few days ago, so
now we have:

https://cirrus-ci.com/task/5676480098205696

#3 0x00000000009cf57e in ExceptionalCondition (conditionName=0x29cae8
"BarrierParticipants(&accessor->shared->batch_barrier) == 1",
errorType=<optimized out>, fileName=0x2ae561 "nodeHash.c",
lineNumber=lineNumber@entry=2224) at assert.c:69
No locals.
#4 0x000000000071575e in ExecParallelScanHashTableForUnmatched
(hjstate=hjstate@entry=0x80a60a3c8,
econtext=econtext@entry=0x80a60ae98) at nodeHash.c:2224

I believe this assert can be safely removed.

It is possible for a worker to attach to the batch barrier after the
"last" worker was elected to scan and emit unmatched inner tuples. This
is safe because the batch barrier is already in phase PHJ_BATCH_SCAN
and this newly attached worker will simply detach from the batch
barrier and look for a new batch to work on.

The order of events would be as follows:

W1: advances batch to PHJ_BATCH_SCAN
W2: attaches to batch barrier in ExecParallelHashJoinNewBatch()
W1: calls ExecParallelScanHashTableForUnmatched() (2 workers attached to
barrier at this point)
W2: detaches from the batch barrier

The attached v10 patch removes this assert and updates the comment in
ExecParallelScanHashTableForUnmatched().

I'm not sure if I should add more detail about this scenario in
ExecParallelHashJoinNewBatch() under PHJ_BATCH_SCAN or if the detail in
ExecParallelScanHashTableForUnmatched() is sufficient.

- Melanie

Attachments:

v10-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchtext/x-patch; charset=US-ASCII; name=v10-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From 998a1cc5bbbe26ce4c0bf23be22867fd1635e2c6 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v10 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.
---
 src/backend/executor/nodeHash.c         | 68 +++++++++---------
 src/backend/executor/nodeHashjoin.c     | 91 +++++++++++++------------
 src/backend/utils/activity/wait_event.c |  8 +--
 src/include/executor/hashjoin.h         | 38 +++++------
 src/include/utils/wait_event.h          |  4 +-
 5 files changed, 106 insertions(+), 103 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 049d718425..4e233f07c4 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
 	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1086,7 +1086,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1095,7 +1095,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1211,13 +1211,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1230,7 +1230,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1285,7 +1285,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1525,7 +1525,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1534,7 +1534,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1563,13 +1563,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1725,7 +1725,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2879,7 +2879,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2999,7 +2999,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3074,7 +3074,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
 	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_DONE phase.
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3157,7 +3157,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3200,12 +3200,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3228,7 +3228,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 3fd97ab067..f321d70dfb 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -306,12 +309,12 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (parallel)
 					{
 						/*
-						 * Advance the build barrier to PHJ_BUILD_RUNNING
-						 * before proceeding to cleanup to comply with build
-						 * barrier safety requirements.
+						 * Advance the build barrier to PHJ_BUILD_RUN before
+						 * proceeding to cleanup to comply with build barrier
+						 * safety requirements.
 						 */
 						Barrier *build_barrier = &parallel_state->build_barrier;
-						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUN)
 							BarrierArriveAndWait(build_barrier, 0);
 					}
 					return NULL;
@@ -335,10 +338,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -349,7 +352,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -360,7 +363,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1152,7 +1155,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1160,13 +1163,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1186,7 +1189,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1196,13 +1199,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1529,7 +1532,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1548,7 +1551,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 0f5f18f02e..fb9b736233 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -367,8 +367,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -382,8 +382,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d7e90bc0e2..534f818bd7 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index e0b2f56f47..beb1e578e0 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -98,12 +98,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.30.2

v10-0001-Fix-race-condition-in-parallel-hash-join-batch-c.patchtext/x-patch; charset=US-ASCII; name=v10-0001-Fix-race-condition-in-parallel-hash-join-batch-c.patchDownload
From 033ab3a8f68d823e8b2836d2a1b7b3684e6dfe2a Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v10 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

The build barrier must make it to PHJ_BUILD_DONE before shared resources
can be safely destroyed. This works fine in most cases with the addition
of another synchronization point. However, when the inner side is empty,
the build barrier will only make it to PHJ_BUILD_HASHING_INNER before
workers attempt to detach from the hashtable. In the case of the empty
inner optimization, advance the build barrier to PHJ_BUILD_RUNNING
before proceeding to cleanup. See batch 0 batch barrier fast forward in
ExecParallelHashJoinSetUpBatches() for precedent.

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

Back-patch to all supported releases.

Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 47 +++++++++++++++++--------
 src/backend/executor/nodeHashjoin.c | 53 ++++++++++++++++++++---------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 4d68a8b97b..049d718425 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it isn't
 	 * there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3065,14 +3072,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3192,9 +3196,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3210,17 +3222,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 88b870655e..3fd97ab067 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -296,7 +302,20 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * outer relation.
 				 */
 				if (hashtable->totalTuples == 0 && !HJ_FILL_OUTER(node))
+				{
+					if (parallel)
+					{
+						/*
+						 * Advance the build barrier to PHJ_BUILD_RUNNING
+						 * before proceeding to cleanup to comply with build
+						 * barrier safety requirements.
+						 */
+						Barrier *build_barrier = &parallel_state->build_barrier;
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+							BarrierArriveAndWait(build_barrier, 0);
+					}
 					return NULL;
+				}
 
 				/*
 				 * need to remember whether nbatch has increased since we
@@ -317,6 +336,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +349,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1119,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 5d72243022..d7e90bc0e2 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.30.2

v10-0003-Parallel-Hash-Full-Right-Outer-Join.patchtext/x-patch; charset=US-ASCII; name=v10-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From e60b91be1e550c1b8908bd6f140bcf146830f842 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v10 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 214 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 +++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  56 ++++++-
 src/test/regress/sql/join_hash.sql      |  23 ++-
 7 files changed, 292 insertions(+), 92 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 4e233f07c4..6bcdabc62b 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2070,16 +2071,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2093,60 +2150,119 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
-		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple)
+				(HASH_CHUNK_DATA(hashtable->current_chunk) +
+				 hashtable->current_chunk_idx);
+
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again.
+	 *
+	 * In order to ensure this, when probing has been completed for this
+	 * batch, all workers except one will detach from the batch barrier. The
+	 * last worker advances the batch barrier to phase PHJ_BATCH_SCAN before
+	 * conducting this unmatched inner tuple scan. Workers attaching to the
+	 * batch barrier once it is in phase PHJ_BATCH_SCAN will simply detach.
+	 */
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple)
+				(HASH_CHUNK_DATA(accessor->current_chunk) +
+				 accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+					HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+						hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area,
+				accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3152,13 +3268,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3305,6 +3414,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index f321d70dfb..f0a51ecfec 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -392,9 +394,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -487,25 +499,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -563,7 +563,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1197,13 +1198,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index f96fc9fd28..63374766fb 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2136,15 +2136,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2178,9 +2172,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 534f818bd7..627ba1b1ff 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index e1e0dec24b..03f2f8ee81 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3a91c144a2..4ca0e01756 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -767,8 +767,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -788,6 +789,31 @@ select  count(*) from simple r full outer join simple s using (id);
  20000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- An full outer join where every record is not matched.
 -- non-parallel
@@ -812,8 +838,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -833,6 +860,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 68c1a8c7b6..504b3611ca 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -418,7 +418,16 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
+savepoint settings;
+set enable_parallel_hash = off;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- parallelism is possible with parallel-aware full hash join
 savepoint settings;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
@@ -436,14 +445,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.30.2

#26Thomas Munro
thomas.munro@gmail.com
In reply to: Melanie Plageman (#25)
3 attachment(s)
Re: Parallel Full Hash Join

On Wed, Jan 12, 2022 at 10:30 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

On Fri, Nov 26, 2021 at 3:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

#3 0x00000000009cf57e in ExceptionalCondition (conditionName=0x29cae8
"BarrierParticipants(&accessor->shared->batch_barrier) == 1",
errorType=<optimized out>, fileName=0x2ae561 "nodeHash.c",
lineNumber=lineNumber@entry=2224) at assert.c:69
No locals.
#4 0x000000000071575e in ExecParallelScanHashTableForUnmatched
(hjstate=hjstate@entry=0x80a60a3c8,
econtext=econtext@entry=0x80a60ae98) at nodeHash.c:2224

I believe this assert can be safely removed.

Agreed.

I was looking at this with a view to committing it, but I need more
time. This will be at the front of my queue when the tree reopens.
I'm trying to find the tooling I had somewhere that could let you test
attaching and detaching at every phase.

The attached version is just pgindent'd.

Attachments:

v11-0001-Fix-race-condition-in-parallel-hash-join-batch-c.patchtext/x-patch; charset=US-ASCII; name=v11-0001-Fix-race-condition-in-parallel-hash-join-batch-c.patchDownload
From e7453cae9b2a686d57f967fd41533546d463dd0c Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 2 Oct 2020 15:53:44 +1300
Subject: [PATCH v11 1/3] Fix race condition in parallel hash join batch
 cleanup.

With unlucky timing and parallel_leader_participation off, PHJ could
attempt to access per-batch state just as it was being freed.  There was
code intended to prevent that by checking for a cleared pointer, but it
was racy.  Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard.  This mirrors the way per-batch
hash tables are freed (see phases PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

The build barrier must make it to PHJ_BUILD_DONE before shared resources
can be safely destroyed. This works fine in most cases with the addition
of another synchronization point. However, when the inner side is empty,
the build barrier will only make it to PHJ_BUILD_HASHING_INNER before
workers attempt to detach from the hashtable. In the case of the empty
inner optimization, advance the build barrier to PHJ_BUILD_RUNNING
before proceeding to cleanup. See batch 0 batch barrier fast forward in
ExecParallelHashJoinSetUpBatches() for precedent.

Revealed by a build farm failure, where BarrierAttach() failed a sanity
check assertion, because the memory had been clobbered by dsa_free().

This should eventually be back-patched to all supported releases, but
the failure is rare and the previous attempt at this was reverted, so
let's do this in master only for now, ahead of some other changes that
will move things around a bit.

Author: Thomas Munro <thomas.munro@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Reported-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
---
 src/backend/executor/nodeHash.c     | 49 +++++++++++++++++---------
 src/backend/executor/nodeHashjoin.c | 54 ++++++++++++++++++++---------
 src/include/executor/hashjoin.h     |  3 +-
 3 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 3510a4247c..d7d1d77ed1 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -333,14 +333,21 @@ MultiExecParallelHash(HashState *node)
 	hashtable->nbuckets = pstate->nbuckets;
 	hashtable->log2_nbuckets = my_log2(hashtable->nbuckets);
 	hashtable->totalTuples = pstate->total_tuples;
-	ExecParallelHashEnsureBatchAccessors(hashtable);
+
+	/*
+	 * Unless we're completely done and the batch state has been freed, make
+	 * sure we have accessors.
+	 */
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_DONE (if it isn't
-	 * there already).
+	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it
+	 * isn't there already).
 	 */
 	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 }
 
@@ -624,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_DONE.  The caller must not return control from this
+		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -3065,14 +3072,11 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 	}
 
 	/*
-	 * It's possible for a backend to start up very late so that the whole
-	 * join is finished and the shm state for tracking batches has already
-	 * been freed by ExecHashTableDetach().  In that case we'll just leave
-	 * hashtable->batches as NULL so that ExecParallelHashJoinNewBatch() gives
-	 * up early.
+	 * We should never see a state where the batch-tracking array is freed,
+	 * because we should have given up sooner if we join when the build
+	 * barrier has reached the PHJ_BUILD_DONE phase.
 	 */
-	if (!DsaPointerIsValid(pstate->batches))
-		return;
+	Assert(DsaPointerIsValid(pstate->batches));
 
 	/* Use hash join memory context. */
 	oldcxt = MemoryContextSwitchTo(hashtable->hashCxt);
@@ -3192,9 +3196,17 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 void
 ExecHashTableDetach(HashJoinTable hashtable)
 {
-	if (hashtable->parallel_state)
+	ParallelHashJoinState *pstate = hashtable->parallel_state;
+
+	/*
+	 * If we're involved in a parallel query, we must either have got all the
+	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 */
+	Assert(!pstate ||
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
 	{
-		ParallelHashJoinState *pstate = hashtable->parallel_state;
 		int			i;
 
 		/* Make sure any temporary files are closed. */
@@ -3210,17 +3222,22 @@ ExecHashTableDetach(HashJoinTable hashtable)
 		}
 
 		/* If we're last to detach, clean up shared memory. */
-		if (BarrierDetach(&pstate->build_barrier))
+		if (BarrierArriveAndDetach(&pstate->build_barrier))
 		{
+			/*
+			 * Late joining processes will see this state and give up
+			 * immediately.
+			 */
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+
 			if (DsaPointerIsValid(pstate->batches))
 			{
 				dsa_free(hashtable->area, pstate->batches);
 				pstate->batches = InvalidDsaPointer;
 			}
 		}
-
-		hashtable->parallel_state = NULL;
 	}
+	hashtable->parallel_state = NULL;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 88b870655e..ba4895e44d 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -45,7 +45,8 @@
  *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
  *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
  *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_DONE                  -- building done, probing can begin
+ *   PHJ_BUILD_RUNNING               -- building done, probing can begin
+ *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
  *
  * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
@@ -73,7 +74,7 @@
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_DONE is reached, backends then split up and process
+ * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
@@ -95,11 +96,16 @@
  *
  * To avoid deadlocks, we never wait for any barrier unless it is known that
  * all other backends attached to it are actively executing the node or have
- * already arrived.  Practically, that means that we never return a tuple
- * while attached to a barrier, unless the barrier has reached its final
- * state.  In the slightly special case of the per-batch barrier, we return
- * tuples while in PHJ_BATCH_PROBING phase, but that's OK because we use
- * BarrierArriveAndDetach() to advance it to PHJ_BATCH_DONE without waiting.
+ * finished.  Practically, that means that we never emit a tuple while attached
+ * to a barrier, unless the barrier has reached a phase that means that no
+ * process will wait on it again.  We emit tuples while attached to the build
+ * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * respectively without waiting, using BarrierArriveAndDetach().  The last to
+ * detach receives a different return value so that it knows that it's safe to
+ * clean up.  Any straggler process that attaches after that phase is reached
+ * will see that it's too late to participate or access the relevant shared
+ * memory objects.
  *
  *-------------------------------------------------------------------------
  */
@@ -296,7 +302,21 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * outer relation.
 				 */
 				if (hashtable->totalTuples == 0 && !HJ_FILL_OUTER(node))
+				{
+					if (parallel)
+					{
+						/*
+						 * Advance the build barrier to PHJ_BUILD_RUNNING
+						 * before proceeding to cleanup to comply with build
+						 * barrier safety requirements.
+						 */
+						Barrier    *build_barrier = &parallel_state->build_barrier;
+
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+							BarrierArriveAndWait(build_barrier, 0);
+					}
 					return NULL;
+				}
 
 				/*
 				 * need to remember whether nbatch has increased since we
@@ -317,6 +337,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 
 					build_barrier = &parallel_state->build_barrier;
 					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
 						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
 					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
 					{
@@ -329,9 +350,18 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					{
+						/*
+						 * If we attached so late that the job is finished and
+						 * the batch state has been freed, we can return
+						 * immediately.
+						 */
+						return NULL;
+					}
 
 					/* Each backend should now select a batch to work on. */
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1090,14 +1120,6 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 	int			start_batchno;
 	int			batchno;
 
-	/*
-	 * If we started up so late that the batch tracking array has been freed
-	 * already by ExecHashTableDetach(), then we are finished.  See also
-	 * ExecParallelHashEnsureBatchAccessors().
-	 */
-	if (hashtable->batches == NULL)
-		return false;
-
 	/*
 	 * If we were already attached to a batch, remember not to bother checking
 	 * it again, and detach from it (possibly freeing the hash table if we are
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 5d72243022..d7e90bc0e2 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -258,7 +258,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BUILD_ALLOCATING			1
 #define PHJ_BUILD_HASHING_INNER			2
 #define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_DONE					4
+#define PHJ_BUILD_RUNNING				4
+#define PHJ_BUILD_DONE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
 #define PHJ_BATCH_ELECTING				0
-- 
2.30.2

v11-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchtext/x-patch; charset=US-ASCII; name=v11-0002-Improve-the-naming-of-Parallel-Hash-Join-phases.patchDownload
From 008dfa76f9bea487b025af3790c398ddce9d06af Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 6 Mar 2021 12:06:16 +1300
Subject: [PATCH v11 2/3] Improve the naming of Parallel Hash Join phases.

Commit 3048898e dropped -ING from some wait event names.  Update the
corresponding barrier phases names to match.

While we're here making cosmetic changes, also rename "DONE" to "FREE".
That pairs better with "ALLOCATE", and describes the activity that
actually happens in that phase (as we do for the other phases) rather
than describing a state.  As for the growth barriers, rename their
"ALLOCATE" phase to "REALLOCATE", which is probably a better description
of what happens then.

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 72 +++++++++----------
 src/backend/executor/nodeHashjoin.c     | 91 +++++++++++++------------
 src/backend/utils/activity/wait_event.c |  8 +--
 src/include/executor/hashjoin.h         | 38 +++++------
 src/include/utils/wait_event.h          |  4 +-
 5 files changed, 108 insertions(+), 105 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index d7d1d77ed1..6a57ac8c98 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -246,10 +246,10 @@ MultiExecParallelHash(HashState *node)
 	 */
 	pstate = hashtable->parallel_state;
 	build_barrier = &pstate->build_barrier;
-	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATING);
+	Assert(BarrierPhase(build_barrier) >= PHJ_BUILD_ALLOCATE);
 	switch (BarrierPhase(build_barrier))
 	{
-		case PHJ_BUILD_ALLOCATING:
+		case PHJ_BUILD_ALLOCATE:
 
 			/*
 			 * Either I just allocated the initial hash table in
@@ -259,7 +259,7 @@ MultiExecParallelHash(HashState *node)
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ALLOCATE);
 			/* Fall through. */
 
-		case PHJ_BUILD_HASHING_INNER:
+		case PHJ_BUILD_HASH_INNER:
 
 			/*
 			 * It's time to begin hashing, or if we just arrived here then
@@ -271,10 +271,10 @@ MultiExecParallelHash(HashState *node)
 			 * below.
 			 */
 			if (PHJ_GROW_BATCHES_PHASE(BarrierAttach(&pstate->grow_batches_barrier)) !=
-				PHJ_GROW_BATCHES_ELECTING)
+				PHJ_GROW_BATCHES_ELECT)
 				ExecParallelHashIncreaseNumBatches(hashtable);
 			if (PHJ_GROW_BUCKETS_PHASE(BarrierAttach(&pstate->grow_buckets_barrier)) !=
-				PHJ_GROW_BUCKETS_ELECTING)
+				PHJ_GROW_BUCKETS_ELECT)
 				ExecParallelHashIncreaseNumBuckets(hashtable);
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -338,17 +338,17 @@ MultiExecParallelHash(HashState *node)
 	 * Unless we're completely done and the batch state has been freed, make
 	 * sure we have accessors.
 	 */
-	if (BarrierPhase(build_barrier) < PHJ_BUILD_DONE)
+	if (BarrierPhase(build_barrier) < PHJ_BUILD_FREE)
 		ExecParallelHashEnsureBatchAccessors(hashtable);
 
 	/*
 	 * The next synchronization point is in ExecHashJoin's HJ_BUILD_HASHTABLE
-	 * case, which will bring the build phase to PHJ_BUILD_RUNNING (if it
-	 * isn't there already).
+	 * case, which will bring the build phase to PHJ_BUILD_RUN (if it isn't
+	 * there already).
 	 */
-	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-		   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
+	Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+		   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
 }
 
 /* ----------------------------------------------------------------
@@ -596,7 +596,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBING phase, because batch 0 is allocated up front
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
 		 * and then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
@@ -610,7 +610,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * SharedHashJoinBatch objects and the hash table for batch 0.  One
 		 * backend will be elected to do that now if necessary.
 		 */
-		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECTING &&
+		if (BarrierPhase(build_barrier) == PHJ_BUILD_ELECT &&
 			BarrierArriveAndWait(build_barrier, WAIT_EVENT_HASH_BUILD_ELECT))
 		{
 			pstate->nbatch = nbatch;
@@ -631,7 +631,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		/*
 		 * The next Parallel Hash synchronization point is in
 		 * MultiExecParallelHash(), which will progress it all the way to
-		 * PHJ_BUILD_RUNNING.  The caller must not return control from this
+		 * PHJ_BUILD_RUN.  The caller must not return control from this
 		 * executor node between now and then.
 		 */
 	}
@@ -1086,7 +1086,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	ParallelHashJoinState *pstate = hashtable->parallel_state;
 	int			i;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1095,7 +1095,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BATCHES_PHASE(BarrierPhase(&pstate->grow_batches_barrier)))
 	{
-		case PHJ_GROW_BATCHES_ELECTING:
+		case PHJ_GROW_BATCHES_ELECT:
 
 			/*
 			 * Elect one participant to prepare to grow the number of batches.
@@ -1211,13 +1211,13 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_ALLOCATING:
+		case PHJ_GROW_BATCHES_REALLOCATE:
 			/* Wait for the above to be finished. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
-								 WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_REPARTITIONING:
+		case PHJ_GROW_BATCHES_REPARTITION:
 			/* Make sure that we have the current dimensions and buckets. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1230,7 +1230,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 								 WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION);
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_DECIDING:
+		case PHJ_GROW_BATCHES_DECIDE:
 
 			/*
 			 * Elect one participant to clean up and decide whether further
@@ -1285,7 +1285,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BATCHES_FINISHING:
+		case PHJ_GROW_BATCHES_FINISH:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_batches_barrier,
 								 WAIT_EVENT_HASH_GROW_BATCHES_FINISH);
@@ -1525,7 +1525,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	HashMemoryChunk chunk;
 	dsa_pointer chunk_s;
 
-	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+	Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 	/*
 	 * It's unlikely, but we need to be prepared for new participants to show
@@ -1534,7 +1534,7 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 	 */
 	switch (PHJ_GROW_BUCKETS_PHASE(BarrierPhase(&pstate->grow_buckets_barrier)))
 	{
-		case PHJ_GROW_BUCKETS_ELECTING:
+		case PHJ_GROW_BUCKETS_ELECT:
 			/* Elect one participant to prepare to increase nbuckets. */
 			if (BarrierArriveAndWait(&pstate->grow_buckets_barrier,
 									 WAIT_EVENT_HASH_GROW_BUCKETS_ELECT))
@@ -1563,13 +1563,13 @@ ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable)
 			}
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_ALLOCATING:
+		case PHJ_GROW_BUCKETS_REALLOCATE:
 			/* Wait for the above to complete. */
 			BarrierArriveAndWait(&pstate->grow_buckets_barrier,
-								 WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE);
+								 WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE);
 			/* Fall through. */
 
-		case PHJ_GROW_BUCKETS_REINSERTING:
+		case PHJ_GROW_BUCKETS_REINSERT:
 			/* Reinsert all tuples into the hash table. */
 			ExecParallelHashEnsureBatchAccessors(hashtable);
 			ExecParallelHashTableSetCurrentBatch(hashtable, 0);
@@ -1725,7 +1725,7 @@ retry:
 
 		/* Try to load it into memory. */
 		Assert(BarrierPhase(&hashtable->parallel_state->build_barrier) ==
-			   PHJ_BUILD_HASHING_INNER);
+			   PHJ_BUILD_HASH_INNER);
 		hashTuple = ExecParallelHashTupleAlloc(hashtable,
 											   HJTUPLE_OVERHEAD + tuple->t_len,
 											   &shared);
@@ -2879,7 +2879,7 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	if (pstate->growth != PHJ_GROWTH_DISABLED)
 	{
 		Assert(curbatch == 0);
-		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASHING_INNER);
+		Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_HASH_INNER);
 
 		/*
 		 * Check if our space limit would be exceeded.  To avoid choking on
@@ -2999,7 +2999,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		{
 			/* Batch 0 doesn't need to be loaded. */
 			BarrierAttach(&shared->batch_barrier);
-			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBING)
+			while (BarrierPhase(&shared->batch_barrier) < PHJ_BATCH_PROBE)
 				BarrierArriveAndWait(&shared->batch_barrier, 0);
 			BarrierDetach(&shared->batch_barrier);
 		}
@@ -3073,8 +3073,8 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
-	 * because we should have given up sooner if we join when the build
-	 * barrier has reached the PHJ_BUILD_DONE phase.
+	 * because we should have given up sooner if we join when the build barrier
+	 * has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3157,7 +3157,7 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 			 * longer attached, but since there is no way it's moving after
 			 * this point it seems safe to make the following assertion.
 			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_DONE);
+			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
@@ -3200,12 +3200,12 @@ ExecHashTableDetach(HashJoinTable hashtable)
 
 	/*
 	 * If we're involved in a parallel query, we must either have got all the
-	 * way to PHJ_BUILD_RUNNING, or joined too late and be in PHJ_BUILD_DONE.
+	 * way to PHJ_BUILD_RUN, or joined too late and be in PHJ_BUILD_FREE.
 	 */
 	Assert(!pstate ||
-		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUNNING);
+		   BarrierPhase(&pstate->build_barrier) >= PHJ_BUILD_RUN);
 
-	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUNNING)
+	if (pstate && BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_RUN)
 	{
 		int			i;
 
@@ -3228,7 +3228,7 @@ ExecHashTableDetach(HashJoinTable hashtable)
 			 * Late joining processes will see this state and give up
 			 * immediately.
 			 */
-			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_DONE);
+			Assert(BarrierPhase(&pstate->build_barrier) == PHJ_BUILD_FREE);
 
 			if (DsaPointerIsValid(pstate->batches))
 			{
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index ba4895e44d..a45c657550 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -39,27 +39,30 @@
  *
  * One barrier called build_barrier is used to coordinate the hashing phases.
  * The phase is represented by an integer which begins at zero and increments
- * one by one, but in the code it is referred to by symbolic names as follows:
+ * one by one, but in the code it is referred to by symbolic names as follows.
+ * An asterisk indicates a phase that is performed by a single arbitrarily
+ * chosen process.
  *
- *   PHJ_BUILD_ELECTING              -- initial state
- *   PHJ_BUILD_ALLOCATING            -- one sets up the batches and table 0
- *   PHJ_BUILD_HASHING_INNER         -- all hash the inner rel
- *   PHJ_BUILD_HASHING_OUTER         -- (multi-batch only) all hash the outer
- *   PHJ_BUILD_RUNNING               -- building done, probing can begin
- *   PHJ_BUILD_DONE                  -- all work complete, one frees batches
+ *   PHJ_BUILD_ELECT                 -- initial state
+ *   PHJ_BUILD_ALLOCATE*             -- one sets up the batches and table 0
+ *   PHJ_BUILD_HASH_INNER            -- all hash the inner rel
+ *   PHJ_BUILD_HASH_OUTER            -- (multi-batch only) all hash the outer
+ *   PHJ_BUILD_RUN                   -- building done, probing can begin
+ *   PHJ_BUILD_FREE*                 -- all work complete, one frees batches
  *
- * While in the phase PHJ_BUILD_HASHING_INNER a separate pair of barriers may
+ * While in the phase PHJ_BUILD_HASH_INNER a separate pair of barriers may
  * be used repeatedly as required to coordinate expansions in the number of
  * batches or buckets.  Their phases are as follows:
  *
- *   PHJ_GROW_BATCHES_ELECTING       -- initial state
- *   PHJ_GROW_BATCHES_ALLOCATING     -- one allocates new batches
- *   PHJ_GROW_BATCHES_REPARTITIONING -- all repartition
- *   PHJ_GROW_BATCHES_FINISHING      -- one cleans up, detects skew
+ *   PHJ_GROW_BATCHES_ELECT          -- initial state
+ *   PHJ_GROW_BATCHES_REALLOCATE*    -- one allocates new batches
+ *   PHJ_GROW_BATCHES_REPARTITION    -- all repartition
+ *   PHJ_GROW_BATCHES_DECIDE*        -- one detects skew and cleans up
+ *   PHJ_GROW_BATCHES_FINISH         -- finished one growth cycle
  *
- *   PHJ_GROW_BUCKETS_ELECTING       -- initial state
- *   PHJ_GROW_BUCKETS_ALLOCATING     -- one allocates new buckets
- *   PHJ_GROW_BUCKETS_REINSERTING    -- all insert tuples
+ *   PHJ_GROW_BUCKETS_ELECT          -- initial state
+ *   PHJ_GROW_BUCKETS_REALLOCATE*    -- one allocates new buckets
+ *   PHJ_GROW_BUCKETS_REINSERT       -- all insert tuples
  *
  * If the planner got the number of batches and buckets right, those won't be
  * necessary, but on the other hand we might finish up needing to expand the
@@ -67,27 +70,27 @@
  * within our memory budget and load factor target.  For that reason it's a
  * separate pair of barriers using circular phases.
  *
- * The PHJ_BUILD_HASHING_OUTER phase is required only for multi-batch joins,
+ * The PHJ_BUILD_HASH_OUTER phase is required only for multi-batch joins,
  * because we need to divide the outer relation into batches up front in order
  * to be able to process batches entirely independently.  In contrast, the
  * parallel-oblivious algorithm simply throws tuples 'forward' to 'later'
  * batches whenever it encounters them while scanning and probing, which it
  * can do because it processes batches in serial order.
  *
- * Once PHJ_BUILD_RUNNING is reached, backends then split up and process
+ * Once PHJ_BUILD_RUN is reached, backends then split up and process
  * different batches, or gang up and work together on probing batches if there
  * aren't enough to go around.  For each batch there is a separate barrier
  * with the following phases:
  *
- *  PHJ_BATCH_ELECTING       -- initial state
- *  PHJ_BATCH_ALLOCATING     -- one allocates buckets
- *  PHJ_BATCH_LOADING        -- all load the hash table from disk
- *  PHJ_BATCH_PROBING        -- all probe
- *  PHJ_BATCH_DONE           -- end
+ *  PHJ_BATCH_ELECT          -- initial state
+ *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
+ *  PHJ_BATCH_LOAD           -- all load the hash table from disk
+ *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
- * PHJ_BATCH_PROBING; populating batch 0's hash table is done during
- * PHJ_BUILD_HASHING_INNER so we can skip loading.
+ * PHJ_BATCH_PROBE; populating batch 0's hash table is done during
+ * PHJ_BUILD_HASH_INNER so we can skip loading.
  *
  * Initially we try to plan for a single-batch hash join using the combined
  * hash_mem of all participants to create a large shared hash table.  If that
@@ -99,8 +102,8 @@
  * finished.  Practically, that means that we never emit a tuple while attached
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
- * barrier in phase PHJ_BUILD_RUNNING, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBING.  These are advanced to PHJ_BUILD_DONE and PHJ_BATCH_DONE
+ * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
  * respectively without waiting, using BarrierArriveAndDetach().  The last to
  * detach receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
@@ -306,13 +309,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (parallel)
 					{
 						/*
-						 * Advance the build barrier to PHJ_BUILD_RUNNING
-						 * before proceeding to cleanup to comply with build
-						 * barrier safety requirements.
+						 * Advance the build barrier to PHJ_BUILD_RUN before
+						 * proceeding to cleanup to comply with build barrier
+						 * safety requirements.
 						 */
 						Barrier    *build_barrier = &parallel_state->build_barrier;
 
-						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUNNING)
+						while (BarrierPhase(build_barrier) < PHJ_BUILD_RUN)
 							BarrierArriveAndWait(build_barrier, 0);
 					}
 					return NULL;
@@ -336,10 +339,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					Barrier    *build_barrier;
 
 					build_barrier = &parallel_state->build_barrier;
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING ||
-						   BarrierPhase(build_barrier) == PHJ_BUILD_DONE);
-					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASHING_OUTER)
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_RUN ||
+						   BarrierPhase(build_barrier) == PHJ_BUILD_FREE);
+					if (BarrierPhase(build_barrier) == PHJ_BUILD_HASH_OUTER)
 					{
 						/*
 						 * If multi-batch, we need to hash the outer relation
@@ -350,7 +353,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 						BarrierArriveAndWait(build_barrier,
 											 WAIT_EVENT_HASH_BUILD_HASH_OUTER);
 					}
-					else if (BarrierPhase(build_barrier) == PHJ_BUILD_DONE)
+					else if (BarrierPhase(build_barrier) == PHJ_BUILD_FREE)
 					{
 						/*
 						 * If we attached so late that the job is finished and
@@ -361,7 +364,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					}
 
 					/* Each backend should now select a batch to work on. */
-					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUNNING);
+					Assert(BarrierPhase(build_barrier) == PHJ_BUILD_RUN);
 					hashtable->curbatch = -1;
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
 
@@ -1153,7 +1156,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 
 			switch (BarrierAttach(batch_barrier))
 			{
-				case PHJ_BATCH_ELECTING:
+				case PHJ_BATCH_ELECT:
 
 					/* One backend allocates the hash table. */
 					if (BarrierArriveAndWait(batch_barrier,
@@ -1161,13 +1164,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 						ExecParallelHashTableAlloc(hashtable, batchno);
 					/* Fall through. */
 
-				case PHJ_BATCH_ALLOCATING:
+				case PHJ_BATCH_ALLOCATE:
 					/* Wait for allocation to complete. */
 					BarrierArriveAndWait(batch_barrier,
 										 WAIT_EVENT_HASH_BATCH_ALLOCATE);
 					/* Fall through. */
 
-				case PHJ_BATCH_LOADING:
+				case PHJ_BATCH_LOAD:
 					/* Start (or join in) loading tuples. */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					inner_tuples = hashtable->batches[batchno].inner_tuples;
@@ -1187,7 +1190,7 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 										 WAIT_EVENT_HASH_BATCH_LOAD);
 					/* Fall through. */
 
-				case PHJ_BATCH_PROBING:
+				case PHJ_BATCH_PROBE:
 
 					/*
 					 * This batch is ready to probe.  Return control to
@@ -1197,13 +1200,13 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * this barrier again (or else a deadlock could occur).
 					 * All attached participants must eventually call
 					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_DONE can be reached.
+					 * PHJ_BATCH_FREE can be reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
 
-				case PHJ_BATCH_DONE:
+				case PHJ_BATCH_FREE:
 
 					/*
 					 * Already done.  Detach and go around again (if any
@@ -1530,7 +1533,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/*
 	 * It would be possible to reuse the shared hash table in single-batch
 	 * cases by resetting and then fast-forwarding build_barrier to
-	 * PHJ_BUILD_DONE and batch 0's batch_barrier to PHJ_BATCH_PROBING, but
+	 * PHJ_BUILD_FREE and batch 0's batch_barrier to PHJ_BATCH_PROBE, but
 	 * currently shared hash tables are already freed by now (by the last
 	 * participant to detach from the batch).  We could consider keeping it
 	 * around for single-batch joins.  We'd also need to adjust
@@ -1549,7 +1552,7 @@ ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt)
 	/* Clear any shared batch files. */
 	SharedFileSetDeleteAll(&pstate->fileset);
 
-	/* Reset build_barrier to PHJ_BUILD_ELECTING so we can go around again. */
+	/* Reset build_barrier to PHJ_BUILD_ELECT so we can go around again. */
 	BarrierInit(&pstate->build_barrier, 0);
 }
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 87c15b9c6f..28fd376f9e 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -364,8 +364,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
 			event_name = "HashBuildHashOuter";
 			break;
-		case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE:
-			event_name = "HashGrowBatchesAllocate";
+		case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
+			event_name = "HashGrowBatchesReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
 			event_name = "HashGrowBatchesDecide";
@@ -379,8 +379,8 @@ pgstat_get_wait_ipc(WaitEventIPC w)
 		case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
 			event_name = "HashGrowBatchesRepartition";
 			break;
-		case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE:
-			event_name = "HashGrowBucketsAllocate";
+		case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
+			event_name = "HashGrowBucketsReallocate";
 			break;
 		case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
 			event_name = "HashGrowBucketsElect";
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index d7e90bc0e2..534f818bd7 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -254,32 +254,32 @@ typedef struct ParallelHashJoinState
 } ParallelHashJoinState;
 
 /* The phases for building batches, used by build_barrier. */
-#define PHJ_BUILD_ELECTING				0
-#define PHJ_BUILD_ALLOCATING			1
-#define PHJ_BUILD_HASHING_INNER			2
-#define PHJ_BUILD_HASHING_OUTER			3
-#define PHJ_BUILD_RUNNING				4
-#define PHJ_BUILD_DONE					5
+#define PHJ_BUILD_ELECT					0
+#define PHJ_BUILD_ALLOCATE				1
+#define PHJ_BUILD_HASH_INNER			2
+#define PHJ_BUILD_HASH_OUTER			3
+#define PHJ_BUILD_RUN					4
+#define PHJ_BUILD_FREE					5
 
 /* The phases for probing each batch, used by for batch_barrier. */
-#define PHJ_BATCH_ELECTING				0
-#define PHJ_BATCH_ALLOCATING			1
-#define PHJ_BATCH_LOADING				2
-#define PHJ_BATCH_PROBING				3
-#define PHJ_BATCH_DONE					4
+#define PHJ_BATCH_ELECT					0
+#define PHJ_BATCH_ALLOCATE				1
+#define PHJ_BATCH_LOAD					2
+#define PHJ_BATCH_PROBE					3
+#define PHJ_BATCH_FREE					4
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
-#define PHJ_GROW_BATCHES_ELECTING		0
-#define PHJ_GROW_BATCHES_ALLOCATING		1
-#define PHJ_GROW_BATCHES_REPARTITIONING 2
-#define PHJ_GROW_BATCHES_DECIDING		3
-#define PHJ_GROW_BATCHES_FINISHING		4
+#define PHJ_GROW_BATCHES_ELECT			0
+#define PHJ_GROW_BATCHES_REALLOCATE		1
+#define PHJ_GROW_BATCHES_REPARTITION	2
+#define PHJ_GROW_BATCHES_DECIDE			3
+#define PHJ_GROW_BATCHES_FINISH			4
 #define PHJ_GROW_BATCHES_PHASE(n)		((n) % 5)	/* circular phases */
 
 /* The phases of bucket growth while hashing, for grow_buckets_barrier. */
-#define PHJ_GROW_BUCKETS_ELECTING		0
-#define PHJ_GROW_BUCKETS_ALLOCATING		1
-#define PHJ_GROW_BUCKETS_REINSERTING	2
+#define PHJ_GROW_BUCKETS_ELECT			0
+#define PHJ_GROW_BUCKETS_REALLOCATE		1
+#define PHJ_GROW_BUCKETS_REINSERT		2
 #define PHJ_GROW_BUCKETS_PHASE(n)		((n) % 3)	/* circular phases */
 
 typedef struct HashJoinTableData
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index b578e2ec75..73e9b690a8 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -97,12 +97,12 @@ typedef enum
 	WAIT_EVENT_HASH_BUILD_ELECT,
 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
+	WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
 	WAIT_EVENT_LOGICAL_SYNC_DATA,
-- 
2.30.2

v11-0003-Parallel-Hash-Full-Right-Outer-Join.patchtext/x-patch; charset=US-ASCII; name=v11-0003-Parallel-Hash-Full-Right-Outer-Join.patchDownload
From 687bf603dd82d052552c160e0661c01858001591 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 4 Nov 2020 14:25:33 -0800
Subject: [PATCH v11 3/3] Parallel Hash {Full,Right} Outer Join.

Previously, parallel full and right outer joins were not supported due
to a potential deadlock hazard (see discussion).

For now, sidestep the problem by terminating parallelism for the
unmatched inner tuple scan. The last process to arrive at the barrier
prepares for the unmatched inner tuple scan in HJ_NEED_NEW_OUTER and
transitions to HJ_FILL_INNER, scanning the hash table and emitting
unmatched inner tuples.  Other processes are free to go and work on
other batches, if there are any.

To make parallel and serial hash join more consistent, change the serial
version to scan match bits in tuple chunk order, instead of doing it in
hash table bucket order.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 222 ++++++++++++++++++------
 src/backend/executor/nodeHashjoin.c     |  59 ++++---
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |  15 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  58 ++++++-
 src/test/regress/sql/join_hash.sql      |  25 ++-
 7 files changed, 298 insertions(+), 98 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 6a57ac8c98..4da05259bb 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->current_chunk_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -596,8 +597,8 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		 * Attach to the build barrier.  The corresponding detach operation is
 		 * in ExecHashTableDetach.  Note that we won't attach to the
 		 * batch_barrier for batch 0 yet.  We'll attach later and start it out
-		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front
-		 * and then loaded while hashing (the standard hybrid hash join
+		 * in PHJ_BATCH_PROBE phase, because batch 0 is allocated up front and
+		 * then loaded while hashing (the standard hybrid hash join
 		 * algorithm), and we'll coordinate that using build_barrier.
 		 */
 		build_barrier = &pstate->build_barrier;
@@ -2070,16 +2071,72 @@ void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
 	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
+	 * During this scan we use the HashJoinTable fields as follows:
 	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
 	 *----------
 	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
 	hjstate->hj_CurBucketNo = 0;
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
+	hashtable->current_chunk = hashtable->chunks;
+	hashtable->current_chunk_idx = 0;
+}
+
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	/*----------
+	 * During this scan we use the ParallelHashJoinBatchAccessor fields for the
+	 * current batch as follows:
+	 *
+	 * current_chunk: current HashMemoryChunk to scan
+	 * current_chunk_idx: index in current HashMemoryChunk
+	 *----------
+	 */
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *batch_accessor = &hashtable->batches[curbatch];
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+	bool		last = false;
+
+	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_CurSkewBucketNo = 0;
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+	last = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+	if (!last)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track the largest batch we've been attached to.  Though each
+		 * backend might see a different subset of batches, explain.c will
+		 * scan the results from all backends to find the largest value.
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak, batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+	}
+	else
+	{
+		batch_accessor->shared_chunk = batch->chunks;
+		batch_accessor->current_chunk = dsa_get_address(hashtable->area, batch_accessor->shared_chunk);
+		batch_accessor->current_chunk_idx = 0;
+	}
+	return last;
 }
 
 /*
@@ -2093,60 +2150,119 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
+	HashMemoryChunk next;
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
 
-	for (;;)
+	while (hashtable->current_chunk)
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		while (hashtable->current_chunk_idx < hashtable->current_chunk->used)
 		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
-		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(hashtable->current_chunk) +
+			 hashtable->current_chunk_idx);
+
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
+
+			/* next tuple in this chunk */
+			hashtable->current_chunk_idx += MAXALIGN(hashTupleSize);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
-		else
-			break;				/* finished all buckets */
 
-		while (hashTuple != NULL)
+		next = hashtable->current_chunk->next.unshared;
+		hashtable->current_chunk = next;
+		hashtable->current_chunk_idx = 0;
+
+		/* allow this loop to be cancellable */
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+
+	/*
+	 * Only one worker should execute this function. Since tuples have already
+	 * been emitted, it is hazardous for workers to wait at the batch_barrier
+	 * again.
+	 *
+	 * In order to ensure this, when probing has been completed for this
+	 * batch, all workers except one will detach from the batch barrier. The
+	 * last worker advances the batch barrier to phase PHJ_BATCH_SCAN before
+	 * conducting this unmatched inner tuple scan. Workers attaching to the
+	 * batch barrier once it is in phase PHJ_BATCH_SCAN will simply detach.
+	 */
+	while (accessor->current_chunk)
+	{
+		while (accessor->current_chunk_idx < accessor->current_chunk->used)
 		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(accessor->current_chunk) +
+			 accessor->current_chunk_idx);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			accessor->current_chunk_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													HJTUPLE_MINTUPLE(hashTuple)->t_len);
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
-		/* allow this loop to be cancellable */
+		accessor->shared_chunk = accessor->current_chunk->next.shared;
+		accessor->current_chunk = dsa_get_address(hashtable->area,
+												  accessor->shared_chunk);
+		accessor->current_chunk_idx = 0;
+
 		CHECK_FOR_INTERRUPTS();
 	}
 
@@ -3073,8 +3189,8 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 
 	/*
 	 * We should never see a state where the batch-tracking array is freed,
-	 * because we should have given up sooner if we join when the build barrier
-	 * has reached the PHJ_BUILD_FREE phase.
+	 * because we should have given up sooner if we join when the build
+	 * barrier has reached the PHJ_BUILD_FREE phase.
 	 */
 	Assert(DsaPointerIsValid(pstate->batches));
 
@@ -3152,13 +3268,6 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		/* Detach from the batch we were last working on. */
 		if (BarrierArriveAndDetach(&batch->batch_barrier))
 		{
-			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
-			 */
-			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
-
 			/* Free shared chunks and buckets. */
 			while (DsaPointerIsValid(batch->chunks))
 			{
@@ -3305,6 +3414,9 @@ ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, int batchno)
 	hashtable->current_chunk = NULL;
 	hashtable->current_chunk_shared = InvalidDsaPointer;
 	hashtable->batches[batchno].at_least_one_chunk = false;
+	hashtable->batches[batchno].shared_chunk = InvalidDsaPointer;
+	hashtable->batches[batchno].current_chunk = NULL;
+	hashtable->batches[batchno].current_chunk_idx = 0;
 }
 
 /*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index a45c657550..35206d38df 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- full/right outer scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -393,9 +395,19 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					/* end of batch, or maybe whole join */
 					if (HJ_FILL_INNER(node))
 					{
-						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							/* set up to scan for unmatched inner tuples */
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -488,25 +500,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -564,7 +564,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1198,13 +1199,15 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
 					return true;
+				case PHJ_BATCH_SCAN:
+					/* Fall through. */
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 9a8c5165b0..d8630ef934 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2136,15 +2136,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2178,9 +2172,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 534f818bd7..627ba1b1ff 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -205,6 +205,15 @@ typedef struct ParallelHashJoinBatchAccessor
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
 
 	bool		done;			/* flag to remember that a batch is done */
+
+	/*
+	 * While doing the unmatched inner scan, the assigned worker may emit
+	 * tuples. Thus, we must keep track of where it was in the hashtable so it
+	 * can return to the correct offset within the correct chunk.
+	 */
+	dsa_pointer shared_chunk;
+	HashMemoryChunk current_chunk;
+	size_t		current_chunk_idx;
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
 } ParallelHashJoinBatchAccessor;
@@ -266,7 +275,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -352,6 +362,9 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index e1e0dec24b..03f2f8ee81 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3ec07bc1af..027f3888b0 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -784,8 +784,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -806,7 +807,32 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
+rollback to settings;
+-- A full outer join where every record is not matched.
 -- non-parallel
 savepoint settings;
 set local max_parallel_workers_per_gather = 0;
@@ -829,8 +855,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -850,6 +877,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 77dbc182d5..ba1b3e6e1b 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -435,15 +435,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- A full outer join where every record is not matched.
 
 -- non-parallel
 savepoint settings;
@@ -453,14 +462,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.30.2

#27Ian Lawrence Barwick
barwick@gmail.com
In reply to: Thomas Munro (#26)
Re: Parallel Full Hash Join

2022年4月8日(金) 20:30 Thomas Munro <thomas.munro@gmail.com>:

On Wed, Jan 12, 2022 at 10:30 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

On Fri, Nov 26, 2021 at 3:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

#3 0x00000000009cf57e in ExceptionalCondition (conditionName=0x29cae8
"BarrierParticipants(&accessor->shared->batch_barrier) == 1",
errorType=<optimized out>, fileName=0x2ae561 "nodeHash.c",
lineNumber=lineNumber@entry=2224) at assert.c:69
No locals.
#4 0x000000000071575e in ExecParallelScanHashTableForUnmatched
(hjstate=hjstate@entry=0x80a60a3c8,
econtext=econtext@entry=0x80a60ae98) at nodeHash.c:2224

I believe this assert can be safely removed.

Agreed.

I was looking at this with a view to committing it, but I need more
time. This will be at the front of my queue when the tree reopens.
I'm trying to find the tooling I had somewhere that could let you test
attaching and detaching at every phase.

The attached version is just pgindent'd.

Hi Thomas

This patch is marked as "Waiting for Committer" in the current commitfest [1]https://commitfest.postgresql.org/40/2903/
with yourself as committer; do you have any plans to move ahead with this?

[1]: https://commitfest.postgresql.org/40/2903/

Regards

Ian Barwick

#28Thomas Munro
thomas.munro@gmail.com
In reply to: Ian Lawrence Barwick (#27)
Re: Parallel Full Hash Join

On Thu, Nov 17, 2022 at 5:22 PM Ian Lawrence Barwick <barwick@gmail.com> wrote:

This patch is marked as "Waiting for Committer" in the current commitfest [1]
with yourself as committer; do you have any plans to move ahead with this?

Yeah, sorry for lack of progress. Aiming to get this in shortly.

#29Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#28)
2 attachment(s)
Re: Parallel Full Hash Join

Here is a rebased and lightly hacked-upon version that I'm testing.

0001-Scan-for-unmatched-hash-join-tuples-in-memory-order.patch

* this change can stand on its own, separately from any PHJ changes
* renamed hashtable->current_chunk[_idx] to unmatched_scan_{chunk,idx}
* introduced a local variable to avoid some x->y->z stuff
* removed some references to no-longer-relevant hj_XXX variables in
the Prep function

I haven't attempted to prove anything about the performance of this
one yet, but it seems fairly obvious that it can't be worse than what
we're doing today. I have suppressed the urge to look into improving
locality and software prefetching.

0002-Parallel-Hash-Full-Join.patch

* reuse the same umatched_scan_{chunk,idx} variables as above
* rename the list of chunks to scan to work_queue
* fix race/memory leak if we see PHJ_BATCH_SCAN when we attach (it
wasn't OK to just fall through)

That "work queue" name/concept already exists in other places that
need to process every chunk, namely rebucketing and repartitioning.
In later work, I'd like to harmonise these work queues, but I'm not
trying to increase the size of this patch set at this time, I just
want to use consistent naming.

I don't love the way that both ExecHashTableDetachBatch() and
ExecParallelPrepHashTableForUnmatched() duplicate logic relating to
the _SCAN/_FREE protocol, but I'm struggling to find a better idea.
Perhaps I just need more coffee.

I think your idea of opportunistically joining the scan if it's
already running makes sense to explore for a later step, ie to make
multi-batch PHFJ fully fair, and I think that should be a fairly easy
code change, and I put in some comments where changes would be needed.

Continuing to test, more soon.

Attachments:

v12-0002-Parallel-Hash-Full-Join.patchtext/x-patch; charset=US-ASCII; name=v12-0002-Parallel-Hash-Full-Join.patchDownload
From 6f4e82f0569e5b388440ca0ef268dd307388e8f8 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 15:23:14 +1300
Subject: [PATCH v12 2/2] Parallel Hash Full Join.

Full and right outer joins were not supported in the initial
implementation of Parallel Hash Join, because of deadlock hazards (see
discussion).  Therefore FULL JOIN inhibited page-based parallelism,
as the other join strategies can't do it either.

Add a new PHJ phase PHJ_BATCH_SCAN that scans for unmatched tuples on
the inner side of one batch's hash table.  For now, sidestep the
deadlock problem by terminating parallelism there.  The last process to
arrive at that phase emits the unmatched tuples, while others detach and
are free to go and work on other batches, if there are any, but
otherwise they finish the join early.

That unfairness is considered acceptable for now, because it's better
than no parallelism at all.  The build and probe phases are run in
parallel, and the new scan-for-unmatched phase, while serial, is usually
applied to the smaller of the two relations and is either limited by
some multiple of work_mem, or it's too big and is partitioned into
batches and then the situation is improved by batch-level parallelism.
In future work on deadlock avoidance strategies, we may find a way to
parallelize the new phase safely.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 163 +++++++++++++++++++++++-
 src/backend/executor/nodeHashjoin.c     |  91 +++++++++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |   7 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  58 ++++++++-
 src/test/regress/sql/join_hash.sql      |  25 +++-
 7 files changed, 314 insertions(+), 47 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 91fd806c97..58789be71a 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2067,6 +2067,66 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	hjstate->hj_CurTuple = NULL;
 }
 
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+
+	/*
+	 * It would not be deadlock-free to wait on the batch barrier, because it
+	 * is in PHJ_BATCH_PROBE phase, and thus processes attached to it have
+	 * already emitted tuples.  Therefore, we'll hold a wait-free election:
+	 * only one process can continue to the next phase, and all others detach
+	 * from this batch.  They can still go any work on other batches, if there
+	 * are any.
+	 */
+	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE);
+	if (!BarrierArriveAndDetachExceptLast(&batch->batch_barrier))
+	{
+		/* This process considers the batch to be done. */
+		hashtable->batches[hashtable->curbatch].done = true;
+
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track largest batch we've seen, which would normally happen in
+		 * ExecHashTableDetachBatch().
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak,
+				batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+		return false;
+	}
+
+	/* Now we are alone with this batch. */
+	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
+	Assert(BarrierParticipants(&batch->batch_barrier) == 1);
+
+	/*
+	 * See also ExecParallelHashJoinNewBatch()'s assertion that
+	 * batch->work_queue == batch->chunks.  That is, we are now ready to start
+	 * processing all chunks by consuming from work_queue.
+	 */
+	hashtable->unmatched_scan_chunk = NULL;
+	hashtable->unmatched_scan_idx = 0;
+
+	return true;
+}
+
 /*
  * ExecScanHashTableForUnmatched
  *		scan the hash table for unmatched inner tuples
@@ -2128,6 +2188,80 @@ ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 	return false;
 }
 
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel join
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+	HashMemoryChunk chunk;
+
+	for (;;)
+	{
+		if (!(chunk = hashtable->unmatched_scan_chunk))
+		{
+
+			/*
+			 * Since only one process can run this currently, we don't need to
+			 * bother with interlocking, when popping chunks off the work
+			 * queue.
+			 */
+			chunk = (HashMemoryChunk)
+				dsa_get_address(hashtable->area, accessor->shared->work_queue);
+			if (!chunk)
+				break;
+			accessor->shared->work_queue = chunk->next.shared;
+			hashtable->unmatched_scan_chunk = chunk;
+			hashtable->unmatched_scan_idx = 0;
+		}
+
+		while (hashtable->unmatched_scan_idx < chunk->used)
+		{
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(chunk) + hashtable->unmatched_scan_idx);
+
+			hashtable->unmatched_scan_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													  HJTUPLE_MINTUPLE(hashTuple)->t_len);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
+		}
+
+		hashtable->unmatched_scan_chunk = NULL;
+
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
 /*
  * ExecHashTableReset
  *
@@ -2908,6 +3042,12 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	chunk->next.shared = hashtable->batches[curbatch].shared->chunks;
 	hashtable->batches[curbatch].shared->chunks = chunk_shared;
 
+	/*
+	 * Also make this the head of the work_queue list.  This is used as a
+	 * cursor for scanning all chunks in the batch.
+	 */
+	hashtable->batches[curbatch].shared->work_queue = chunk_shared;
+
 	if (size <= HASH_CHUNK_THRESHOLD)
 	{
 		/*
@@ -3116,18 +3256,31 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 	{
 		int			curbatch = hashtable->curbatch;
 		ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+		bool		attached = true;
 
 		/* Make sure any temporary files are closed. */
 		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
 		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
 
-		/* Detach from the batch we were last working on. */
-		if (BarrierArriveAndDetach(&batch->batch_barrier))
+		/* After attaching we always get at least to PHJ_BATCH_PROBE. */
+		Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE ||
+			   BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
+
+		/*
+		 * Even if we aren't doing a full/right outer join, we'll step through
+		 * the PHJ_BATCH_SCAN phase just to maintain the invariant that freeing
+		 * happens in PHJ_BATCH_FREE, but that'll be wait-free.
+		 */
+		if (BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE)
+			attached = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+		if (attached && BarrierArriveAndDetach(&batch->batch_barrier))
 		{
 			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
+			 * We are not longer attached to the batch barrier, but we're the
+			 * process that was chosen to free resources and it's safe to
+			 * assert the current phase.  The ParallelHashJoinBatch can't go
+			 * away underneath us while we are attached to the build barrier,
+			 * making this access safe.
 			 */
 			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index f189fb4d28..93bf0ad6e9 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- one does full/right unmatched scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -393,8 +395,23 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (HJ_FILL_INNER(node))
 					{
 						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							/*
+							 * Only one process is currently allow to handle
+							 * each batch's unmatched tuples, in a parallel
+							 * join.
+							 */
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -487,25 +504,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -563,7 +568,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1197,13 +1203,44 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
+
+					/*
+					 * This is a good place to assert that the batch's
+					 * work_queue has been set to point to the head of the
+					 * chunk list.  No new chunks are created once this phase
+					 * is reached, and we don't want to have to do any extra
+					 * IPC just to set up the work_queue that the later
+					 * PHJ_BATCH_SCAN phase wants, so instead require that it
+					 * has been maintained correctly by the earlier phases.
+					 */
+					Assert(hashtable->batches[batchno].shared->work_queue ==
+						   hashtable->batches[batchno].shared->chunks);
+
 					return true;
+				case PHJ_BATCH_SCAN:
+
+					/*
+					 * In principle, we could help scan for unmatched tuples,
+					 * since that phase is already underway (the thing we can't
+					 * do under current deadlock-avoidance rules is wait for
+					 * others to arrive at PHJ_BATCH_SCAN, because
+					 * PHJ_BATCH_PROBE emits tuples, but in this case we just
+					 * got here without waiting).  That is not yet done.  For
+					 * now, we just detach and go around again.  We have to use
+					 * ExecHashTableDetachBatch() because there's a small
+					 * chance we'll be the last to detach, and then we're
+					 * responsible for freeing memory.
+					 */
+					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
+					hashtable->batches[batchno].done = true;
+					ExecHashTableDetachBatch(hashtable);
+					break;
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index e6ef0deb23..bd51e4f972 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2193,15 +2193,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2235,9 +2229,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 0abd888d1e..7615025d73 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -154,6 +154,7 @@ typedef struct ParallelHashJoinBatch
 	Barrier		batch_barrier;	/* synchronization for joining this batch */
 
 	dsa_pointer chunks;			/* chunks of tuples loaded */
+	dsa_pointer work_queue;		/* cursor for processing all chunks */
 	size_t		size;			/* size of buckets + chunks in memory */
 	size_t		estimated_size; /* size of buckets + chunks while writing */
 	size_t		ntuples;		/* number of tuples loaded */
@@ -266,7 +267,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -356,6 +358,9 @@ typedef struct HashJoinTableData
 	HashMemoryChunk unmatched_scan_chunk;
 	size_t		unmatched_scan_idx;
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index d7634af05c..56d5350c61 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3ec07bc1af..027f3888b0 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -784,8 +784,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -806,7 +807,32 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
+rollback to settings;
+-- A full outer join where every record is not matched.
 -- non-parallel
 savepoint settings;
 set local max_parallel_workers_per_gather = 0;
@@ -829,8 +855,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -850,6 +877,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 77dbc182d5..ba1b3e6e1b 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -435,15 +435,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- A full outer join where every record is not matched.
 
 -- non-parallel
 savepoint settings;
@@ -453,14 +462,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.39.2

v12-0001-Scan-for-unmatched-hash-join-tuples-in-memory-or.patchtext/x-patch; charset=US-ASCII; name=v12-0001-Scan-for-unmatched-hash-join-tuples-in-memory-or.patchDownload
From 8b526377eb4a4685628624e75743aedf37dd5bfe Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 14:19:07 +1300
Subject: [PATCH v12 1/2] Scan for unmatched hash join tuples in memory order.

In a full/right outer join, we need to scan every tuple in the hash
table to find the ones that were not matched while probing, so that we
can emit null-extended inner tuples.  Previously we did that in hash
table bucket order, which means that we dereferenced pointers to tuples
that were randomly scattered in memory (ie in an order derived from the
hash of the join key).

Change to a memory-order scan, using the linked list of memory chunks
that hold the tuples.  This isn't really being done for performance
reasons (a subject for later work), but it certainly can't be worse than
the previous random order.  The goal here is to harmonize the scan logic
with later work that will parallelize full joins, and works in chunks.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c | 85 +++++++++++++--------------------
 src/include/executor/hashjoin.h |  4 ++
 2 files changed, 38 insertions(+), 51 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 748c9b0024..91fd806c97 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,8 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->unmatched_scan_chunk = NULL;
+	hashtable->unmatched_scan_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2058,16 +2060,10 @@ ExecParallelScanHashBucket(HashJoinState *hjstate,
 void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
-	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
-	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
-	 *----------
-	 */
-	hjstate->hj_CurBucketNo = 0;
-	hjstate->hj_CurSkewBucketNo = 0;
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
+	hashtable->unmatched_scan_chunk = hashtable->chunks;
+	hashtable->unmatched_scan_idx = 0;
 	hjstate->hj_CurTuple = NULL;
 }
 
@@ -2083,58 +2079,45 @@ bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+	HashMemoryChunk chunk;
 
-	for (;;)
+	while ((chunk = hashtable->unmatched_scan_chunk))
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->unmatched_scan_idx < chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(hashtable->unmatched_scan_chunk) +
+			 hashtable->unmatched_scan_idx);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
-		}
-		else
-			break;				/* finished all buckets */
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
 
-		while (hashTuple != NULL)
-		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			/* next tuple in this chunk */
+			hashtable->unmatched_scan_idx += MAXALIGN(hashTupleSize);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
+		hashtable->unmatched_scan_chunk = chunk->next.unshared;
+		hashtable->unmatched_scan_idx = 0;
+
 		/* allow this loop to be cancellable */
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index acb7592ca0..0abd888d1e 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -352,6 +352,10 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* current position in unmatched scan (full/right join only) */
+	HashMemoryChunk unmatched_scan_chunk;
+	size_t		unmatched_scan_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
-- 
2.39.2

#30Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#29)
Re: Parallel Full Hash Join

On Sat, Mar 25, 2023 at 09:21:34AM +1300, Thomas Munro wrote:

* reuse the same umatched_scan_{chunk,idx} variables as above
* rename the list of chunks to scan to work_queue
* fix race/memory leak if we see PHJ_BATCH_SCAN when we attach (it
wasn't OK to just fall through)

ah, good catch.

I don't love the way that both ExecHashTableDetachBatch() and
ExecParallelPrepHashTableForUnmatched() duplicate logic relating to
the _SCAN/_FREE protocol, but I'm struggling to find a better idea.
Perhaps I just need more coffee.

I'm not sure if I have strong feelings either way.
To confirm I understand, though: in ExecHashTableDetachBatch(), the call
to BarrierArriveAndDetachExceptLast() serves only to advance the barrier
phase through _SCAN, right? It doesn't really matter if this worker is
the last worker since BarrierArriveAndDetach() handles that for us.
There isn't another barrier function to do this (and I mostly think it
is fine), but I did have to think on it for a bit.

Oh, and, unrelated, but it is maybe worth updating the BarrierAttach()
function comment to mention BarrierArriveAndDetachExceptLast().

I think your idea of opportunistically joining the scan if it's
already running makes sense to explore for a later step, ie to make
multi-batch PHFJ fully fair, and I think that should be a fairly easy
code change, and I put in some comments where changes would be needed.

makes sense.

I have some very minor pieces of feedback, mainly about extraneous
commas that made me uncomfortable ;)

From 8b526377eb4a4685628624e75743aedf37dd5bfe Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 14:19:07 +1300
Subject: [PATCH v12 1/2] Scan for unmatched hash join tuples in memory order.

In a full/right outer join, we need to scan every tuple in the hash
table to find the ones that were not matched while probing, so that we

Given how you are using the word "so" here, I think that comma before it
is not needed.

@@ -2083,58 +2079,45 @@ bool
ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
{
HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+	HashMemoryChunk chunk;
-	for (;;)
+	while ((chunk = hashtable->unmatched_scan_chunk))
{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->unmatched_scan_idx < chunk->used)
{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(hashtable->unmatched_scan_chunk) +
+			 hashtable->unmatched_scan_idx);
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
-		}
-		else
-			break;				/* finished all buckets */
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
-		while (hashTuple != NULL)
-		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			/* next tuple in this chunk */
+			hashtable->unmatched_scan_idx += MAXALIGN(hashTupleSize);
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;

- /*
- * Reset temp memory each time; although this function doesn't
- * do any qual eval, the caller will, so let's keep it
- * parallel to ExecScanHashBucket.
- */
- ResetExprContext(econtext);

I don't think I had done this before. Good call.

+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);

From 6f4e82f0569e5b388440ca0ef268dd307388e8f8 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 15:23:14 +1300
Subject: [PATCH v12 2/2] Parallel Hash Full Join.

Full and right outer joins were not supported in the initial
implementation of Parallel Hash Join, because of deadlock hazards (see

no comma needed before the "because" here

discussion). Therefore FULL JOIN inhibited page-based parallelism,
as the other join strategies can't do it either.

I actually don't quite understand what this means? It's been awhile for
me, so perhaps I'm being dense, but what is page-based parallelism?
Also, I would put a comma after "Therefore" :)

Add a new PHJ phase PHJ_BATCH_SCAN that scans for unmatched tuples on
the inner side of one batch's hash table. For now, sidestep the
deadlock problem by terminating parallelism there. The last process to
arrive at that phase emits the unmatched tuples, while others detach and
are free to go and work on other batches, if there are any, but
otherwise they finish the join early.

That unfairness is considered acceptable for now, because it's better
than no parallelism at all. The build and probe phases are run in
parallel, and the new scan-for-unmatched phase, while serial, is usually
applied to the smaller of the two relations and is either limited by
some multiple of work_mem, or it's too big and is partitioned into
batches and then the situation is improved by batch-level parallelism.
In future work on deadlock avoidance strategies, we may find a way to
parallelize the new phase safely.

Is it worth mentioning something about parallel-oblivious parallel hash
join not being able to do this still? Or is that obvious?

*
@@ -2908,6 +3042,12 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
chunk->next.shared = hashtable->batches[curbatch].shared->chunks;
hashtable->batches[curbatch].shared->chunks = chunk_shared;

+	/*
+	 * Also make this the head of the work_queue list.  This is used as a
+	 * cursor for scanning all chunks in the batch.
+	 */
+	hashtable->batches[curbatch].shared->work_queue = chunk_shared;
+
if (size <= HASH_CHUNK_THRESHOLD)
{
/*
@@ -3116,18 +3256,31 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
{
int			curbatch = hashtable->curbatch;
ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+		bool		attached = true;

/* Make sure any temporary files are closed. */
sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);

-		/* Detach from the batch we were last working on. */
-		if (BarrierArriveAndDetach(&batch->batch_barrier))
+		/* After attaching we always get at least to PHJ_BATCH_PROBE. */
+		Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE ||
+			   BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
+
+		/*
+		 * Even if we aren't doing a full/right outer join, we'll step through
+		 * the PHJ_BATCH_SCAN phase just to maintain the invariant that freeing
+		 * happens in PHJ_BATCH_FREE, but that'll be wait-free.
+		 */
+		if (BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE)

full/right joins should never fall into this code path, right?

If so, would we be able to assert about that? Maybe it doesn't make
sense, though...

+			attached = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+		if (attached && BarrierArriveAndDetach(&batch->batch_barrier))
{
/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
+			 * We are not longer attached to the batch barrier, but we're the
+			 * process that was chosen to free resources and it's safe to
+			 * assert the current phase.  The ParallelHashJoinBatch can't go
+			 * away underneath us while we are attached to the build barrier,
+			 * making this access safe.
*/
Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);

Otherwise, LGTM.

- Melanie

#31Thomas Munro
thomas.munro@gmail.com
In reply to: Melanie Plageman (#30)
4 attachment(s)
Re: Parallel Full Hash Join

On Sun, Mar 26, 2023 at 9:52 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I have some very minor pieces of feedback, mainly about extraneous
commas that made me uncomfortable ;)

Offensive punctuation removed.

discussion). Therefore FULL JOIN inhibited page-based parallelism,
as the other join strategies can't do it either.

I actually don't quite understand what this means? It's been awhile for
me, so perhaps I'm being dense, but what is page-based parallelism?

Reworded. I just meant our usual kind of "partial path" parallelism
(the kind when you don't know anything at all about the values of the
tuples that each process sees, and typically it's chopped up by
storage pages at the scan level).

That unfairness is considered acceptable for now, because it's better
than no parallelism at all. The build and probe phases are run in
parallel, and the new scan-for-unmatched phase, while serial, is usually
applied to the smaller of the two relations and is either limited by
some multiple of work_mem, or it's too big and is partitioned into
batches and then the situation is improved by batch-level parallelism.
In future work on deadlock avoidance strategies, we may find a way to
parallelize the new phase safely.

Is it worth mentioning something about parallel-oblivious parallel hash
join not being able to do this still? Or is that obvious?

That's kind of what I meant above.

@@ -3116,18 +3256,31 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)

full/right joins should never fall into this code path, right?

Yeah, this is the normal way we detach from a batch. This is reached
when shutting down the executor early, or when moving to the next
batch, etc.

***

I found another problem. I realised that ... FULL JOIN ... LIMIT n
might be able to give wrong answers with unlucky scheduling.
Unfortunately I have been unable to reproduce the phenomenon I am
imagining yet but I can't think of any mechanism that prevents the
following sequence of events:

P0 probes, pulls n tuples from the outer relation and then the
executor starts to shut down (see commit 3452dc52 which pushed down
LIMIT), but just then P1 attaches, right before P0 does. P1
continues, and finds < n outer tuples while probing and then runs out
so it enters the unmatched scan phase, and starts emitting bogusly
unmatched tuples. Some outer tuples we needed to get the complete set
of match bits and thus the right answer were buffered inside P0's
subplan and abandoned.

I've attached a simple fixup for this problem. Short version: if
you're abandoning your PHJ_BATCH_PROBE phase without reaching the end,
you must be shutting down, so the executor must think it's OK to
abandon tuples this process has buffered, so it must also be OK to
throw all unmatched tuples out the window too, as if this process was
about to emit them. Right?

***

With all the long and abstract discussion of hard to explain problems
in this thread and related threads, I thought I should take a step
back and figure out a way to demonstrate what this thing really does
visually. I wanted to show that this is a very useful feature that
unlocks previously unobtainable parallelism, and to show the
compromise we've had to make so far in an intuitive way. With some
extra instrumentation hacked up locally, I produced the attached
"progress" graphs for a very simple query: SELECT COUNT(*) FROM r FULL
JOIN s USING (i). Imagine a time axis along the bottom, but I didn't
bother to add numbers because I'm just trying to convey the 'shape' of
execution with relative times and synchronisation points.

Figures 1-3 show that phases 'h' (hash) and 'p' (probe) are
parallelised and finish sooner as we add more processes to help out,
but 's' (= the unmatched inner tuple scan) is not. Note that if all
inner tuples are matched, 's' becomes extremely small and the
parallelism is almost as fair as a plain old inner join, but here I've
maximised it: all inner tuples were unmatched, because the two
relations have no matches at all. Even if we achieve perfect linear
scalability for the other phases, the speedup will be governed by
https://en.wikipedia.org/wiki/Amdahl%27s_law and the only thing that
can mitigate that is if there is more useful work those early-quitting
processes could do somewhere else in your query plan.

Figure 4 shows that it gets a lot fairer in a multi-batch join,
because there is usually useful work to do on other batches of the
same join. Notice how processes initially work on loading, probing
and scanning different batches to reduce contention, but they are
capable of ganging up to load and/or probe the same batch if there is
nothing else left to do (for example P2 and P3 both work on p5 near
the end). For now, they can't do that for the s phases. (BTW, the
little gaps before loading is the allocation phase that I didn't
bother to plot because they can't fit a label on them; this
visualisation technique is a WIP.)

With the "opportunistic" change we are discussing for later work,
figure 4 would become completely fair (P0 and P2 would be able to join
in and help out with s6 and s7), but single-batch figures 1-3 would
not (that would require a different executor design AFAICT, or a
eureka insight we haven't had yet; see long-winded discussion).

The last things I'm thinking about now: Are the planner changes
right? Are the tests enough? I suspect we'll finish up changing that
chunk-based approach yet again in future work on memory efficiency,
but I'm OK with that; this change suits the current problem and we
don't know what we'll eventually settle on with more research.

Attachments:

g.pdfapplication/pdf; name=g.pdfDownload
v13-0001-Scan-for-unmatched-hash-join-tuples-in-memory-or.patchtext/x-patch; charset=US-ASCII; name=v13-0001-Scan-for-unmatched-hash-join-tuples-in-memory-or.patchDownload
From 0bd32dd1a7e45e95a62f7f587bfba64bed87da28 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 14:19:07 +1300
Subject: [PATCH v13 1/4] Scan for unmatched hash join tuples in memory order.

In a full/right outer join, we need to scan every tuple in the hash
table to find the ones that were not matched while probing so that we
can emit null-extended inner tuples.  Previously we did that in hash
table bucket order, which means that we dereferenced pointers to tuples
that were randomly scattered in memory (ie in an order derived from the
hash of the join key).

Change to a memory-order scan, using the linked list of memory chunks
that hold the tuples.  This isn't really being done for performance
reasons (a subject for later work), but it certainly can't be worse than
the previous random order.  The goal for now is to harmonize the scan
logic with a subsequent patch that will parallelize full joins.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c | 85 +++++++++++++--------------------
 src/include/executor/hashjoin.h |  4 ++
 2 files changed, 38 insertions(+), 51 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 748c9b0024..91fd806c97 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -517,6 +517,8 @@ ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations,
 		hashtable->spaceAllowed * SKEW_HASH_MEM_PERCENT / 100;
 	hashtable->chunks = NULL;
 	hashtable->current_chunk = NULL;
+	hashtable->unmatched_scan_chunk = NULL;
+	hashtable->unmatched_scan_idx = 0;
 	hashtable->parallel_state = state->parallel_state;
 	hashtable->area = state->ps.state->es_query_dsa;
 	hashtable->batches = NULL;
@@ -2058,16 +2060,10 @@ ExecParallelScanHashBucket(HashJoinState *hjstate,
 void
 ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 {
-	/*----------
-	 * During this scan we use the HashJoinState fields as follows:
-	 *
-	 * hj_CurBucketNo: next regular bucket to scan
-	 * hj_CurSkewBucketNo: next skew bucket (an index into skewBucketNums)
-	 * hj_CurTuple: last tuple returned, or NULL to start next bucket
-	 *----------
-	 */
-	hjstate->hj_CurBucketNo = 0;
-	hjstate->hj_CurSkewBucketNo = 0;
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+
+	hashtable->unmatched_scan_chunk = hashtable->chunks;
+	hashtable->unmatched_scan_idx = 0;
 	hjstate->hj_CurTuple = NULL;
 }
 
@@ -2083,58 +2079,45 @@ bool
 ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 {
 	HashJoinTable hashtable = hjstate->hj_HashTable;
-	HashJoinTuple hashTuple = hjstate->hj_CurTuple;
+	HashMemoryChunk chunk;
 
-	for (;;)
+	while ((chunk = hashtable->unmatched_scan_chunk))
 	{
-		/*
-		 * hj_CurTuple is the address of the tuple last returned from the
-		 * current bucket, or NULL if it's time to start scanning a new
-		 * bucket.
-		 */
-		if (hashTuple != NULL)
-			hashTuple = hashTuple->next.unshared;
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
-		{
-			hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo];
-			hjstate->hj_CurBucketNo++;
-		}
-		else if (hjstate->hj_CurSkewBucketNo < hashtable->nSkewBuckets)
+		while (hashtable->unmatched_scan_idx < chunk->used)
 		{
-			int			j = hashtable->skewBucketNums[hjstate->hj_CurSkewBucketNo];
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(hashtable->unmatched_scan_chunk) +
+			 hashtable->unmatched_scan_idx);
 
-			hashTuple = hashtable->skewBucket[j]->tuples;
-			hjstate->hj_CurSkewBucketNo++;
-		}
-		else
-			break;				/* finished all buckets */
+			MinimalTuple tuple = HJTUPLE_MINTUPLE(hashTuple);
+			int			hashTupleSize = (HJTUPLE_OVERHEAD + tuple->t_len);
 
-		while (hashTuple != NULL)
-		{
-			if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
-			{
-				TupleTableSlot *inntuple;
+			/* next tuple in this chunk */
+			hashtable->unmatched_scan_idx += MAXALIGN(hashTupleSize);
 
-				/* insert hashtable's tuple into exec slot */
-				inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
-												 hjstate->hj_HashTupleSlot,
-												 false);	/* do not pfree */
-				econtext->ecxt_innertuple = inntuple;
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
 
-				/*
-				 * Reset temp memory each time; although this function doesn't
-				 * do any qual eval, the caller will, so let's keep it
-				 * parallel to ExecScanHashBucket.
-				 */
-				ResetExprContext(econtext);
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot,
+									  false);
 
-				hjstate->hj_CurTuple = hashTuple;
-				return true;
-			}
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
 
-			hashTuple = hashTuple->next.unshared;
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
 		}
 
+		hashtable->unmatched_scan_chunk = chunk->next.unshared;
+		hashtable->unmatched_scan_idx = 0;
+
 		/* allow this loop to be cancellable */
 		CHECK_FOR_INTERRUPTS();
 	}
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index acb7592ca0..0abd888d1e 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -352,6 +352,10 @@ typedef struct HashJoinTableData
 	/* used for dense allocation of tuples (into linked chunks) */
 	HashMemoryChunk chunks;		/* one list for the whole batch */
 
+	/* current position in unmatched scan (full/right join only) */
+	HashMemoryChunk unmatched_scan_chunk;
+	size_t		unmatched_scan_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
-- 
2.39.2

v13-0002-Parallel-Hash-Full-Join.patchtext/x-patch; charset=US-ASCII; name=v13-0002-Parallel-Hash-Full-Join.patchDownload
From 9f9a3f56040a3b68ce74a17b57ce3ffe4aca5036 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 24 Mar 2023 15:23:14 +1300
Subject: [PATCH v13 2/4] Parallel Hash Full Join.

Full and right outer joins were not supported in the initial
implementation of Parallel Hash Join because of deadlock hazards.
Therefore FULL JOIN inhibited parallelism (the other join strategies
can't do it either).

Add a new PHJ phase PHJ_BATCH_SCAN that scans for unmatched tuples on
the inner side of one batch's hash table.  For now, sidestep the
deadlock problem by terminating parallelism there.  The last process to
arrive at that phase emits the unmatched tuples, while others detach and
are free to go and work on other batches, if there are any, but
otherwise they finish the join early.

That unfairness is considered acceptable for now, because it's better
than no parallelism at all.  The build and probe phases are run in
parallel, and the new scan-for-unmatched phase, while serial, is usually
applied to the smaller of the two relations and is either limited by
some multiple of work_mem, or it's too big and is partitioned into
batches and then the situation is improved by batch-level parallelism.
In future work on deadlock avoidance strategies, we may find a way to
parallelize the new phase safely.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c         | 163 +++++++++++++++++++++++-
 src/backend/executor/nodeHashjoin.c     |  91 +++++++++----
 src/backend/optimizer/path/joinpath.c   |  14 +-
 src/include/executor/hashjoin.h         |   7 +-
 src/include/executor/nodeHash.h         |   3 +
 src/test/regress/expected/join_hash.out |  58 ++++++++-
 src/test/regress/sql/join_hash.sql      |  25 +++-
 7 files changed, 314 insertions(+), 47 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 91fd806c97..58789be71a 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2067,6 +2067,66 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	hjstate->hj_CurTuple = NULL;
 }
 
+/*
+ * ExecParallelPrepHashTableForUnmatched
+ *		set up for a series of ExecParallelScanHashTableForUnmatched calls
+ *		return true if this worker is elected to do the unmatched inner scan
+ */
+bool
+ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+
+	hjstate->hj_CurTuple = NULL;
+	if (curbatch < 0)
+		return false;
+
+	/*
+	 * It would not be deadlock-free to wait on the batch barrier, because it
+	 * is in PHJ_BATCH_PROBE phase, and thus processes attached to it have
+	 * already emitted tuples.  Therefore, we'll hold a wait-free election:
+	 * only one process can continue to the next phase, and all others detach
+	 * from this batch.  They can still go any work on other batches, if there
+	 * are any.
+	 */
+	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE);
+	if (!BarrierArriveAndDetachExceptLast(&batch->batch_barrier))
+	{
+		/* This process considers the batch to be done. */
+		hashtable->batches[hashtable->curbatch].done = true;
+
+		/* Make sure any temporary files are closed. */
+		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
+		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
+
+		/*
+		 * Track largest batch we've seen, which would normally happen in
+		 * ExecHashTableDetachBatch().
+		 */
+		hashtable->spacePeak =
+			Max(hashtable->spacePeak,
+				batch->size + sizeof(dsa_pointer_atomic) * hashtable->nbuckets);
+		hashtable->curbatch = -1;
+		return false;
+	}
+
+	/* Now we are alone with this batch. */
+	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
+	Assert(BarrierParticipants(&batch->batch_barrier) == 1);
+
+	/*
+	 * See also ExecParallelHashJoinNewBatch()'s assertion that
+	 * batch->work_queue == batch->chunks.  That is, we are now ready to start
+	 * processing all chunks by consuming from work_queue.
+	 */
+	hashtable->unmatched_scan_chunk = NULL;
+	hashtable->unmatched_scan_idx = 0;
+
+	return true;
+}
+
 /*
  * ExecScanHashTableForUnmatched
  *		scan the hash table for unmatched inner tuples
@@ -2128,6 +2188,80 @@ ExecScanHashTableForUnmatched(HashJoinState *hjstate, ExprContext *econtext)
 	return false;
 }
 
+/*
+ * ExecParallelScanHashTableForUnmatched
+ *		scan the hash table for unmatched inner tuples, in parallel join
+ *
+ * On success, the inner tuple is stored into hjstate->hj_CurTuple and
+ * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot
+ * for the latter.
+ */
+bool
+ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+									  ExprContext *econtext)
+{
+	HashJoinTable hashtable = hjstate->hj_HashTable;
+	int			curbatch = hashtable->curbatch;
+	ParallelHashJoinBatchAccessor *accessor = &hashtable->batches[curbatch];
+	HashMemoryChunk chunk;
+
+	for (;;)
+	{
+		if (!(chunk = hashtable->unmatched_scan_chunk))
+		{
+
+			/*
+			 * Since only one process can run this currently, we don't need to
+			 * bother with interlocking, when popping chunks off the work
+			 * queue.
+			 */
+			chunk = (HashMemoryChunk)
+				dsa_get_address(hashtable->area, accessor->shared->work_queue);
+			if (!chunk)
+				break;
+			accessor->shared->work_queue = chunk->next.shared;
+			hashtable->unmatched_scan_chunk = chunk;
+			hashtable->unmatched_scan_idx = 0;
+		}
+
+		while (hashtable->unmatched_scan_idx < chunk->used)
+		{
+			HashJoinTuple hashTuple = (HashJoinTuple)
+			(HASH_CHUNK_DATA(chunk) + hashtable->unmatched_scan_idx);
+
+			hashtable->unmatched_scan_idx += MAXALIGN(HJTUPLE_OVERHEAD +
+													  HJTUPLE_MINTUPLE(hashTuple)->t_len);
+
+			if (HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(hashTuple)))
+				continue;
+
+			/* insert hashtable's tuple into exec slot */
+			econtext->ecxt_innertuple =
+				ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple),
+									  hjstate->hj_HashTupleSlot, false);
+
+			/*
+			 * Reset temp memory each time; although this function doesn't do
+			 * any qual eval, the caller will, so let's keep it parallel to
+			 * ExecScanHashBucket.
+			 */
+			ResetExprContext(econtext);
+
+			hjstate->hj_CurTuple = hashTuple;
+			return true;
+		}
+
+		hashtable->unmatched_scan_chunk = NULL;
+
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/*
+	 * no more unmatched tuples
+	 */
+	return false;
+}
+
 /*
  * ExecHashTableReset
  *
@@ -2908,6 +3042,12 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
 	chunk->next.shared = hashtable->batches[curbatch].shared->chunks;
 	hashtable->batches[curbatch].shared->chunks = chunk_shared;
 
+	/*
+	 * Also make this the head of the work_queue list.  This is used as a
+	 * cursor for scanning all chunks in the batch.
+	 */
+	hashtable->batches[curbatch].shared->work_queue = chunk_shared;
+
 	if (size <= HASH_CHUNK_THRESHOLD)
 	{
 		/*
@@ -3116,18 +3256,31 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 	{
 		int			curbatch = hashtable->curbatch;
 		ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
+		bool		attached = true;
 
 		/* Make sure any temporary files are closed. */
 		sts_end_parallel_scan(hashtable->batches[curbatch].inner_tuples);
 		sts_end_parallel_scan(hashtable->batches[curbatch].outer_tuples);
 
-		/* Detach from the batch we were last working on. */
-		if (BarrierArriveAndDetach(&batch->batch_barrier))
+		/* After attaching we always get at least to PHJ_BATCH_PROBE. */
+		Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE ||
+			   BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
+
+		/*
+		 * Even if we aren't doing a full/right outer join, we'll step through
+		 * the PHJ_BATCH_SCAN phase just to maintain the invariant that freeing
+		 * happens in PHJ_BATCH_FREE, but that'll be wait-free.
+		 */
+		if (BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE)
+			attached = BarrierArriveAndDetachExceptLast(&batch->batch_barrier);
+		if (attached && BarrierArriveAndDetach(&batch->batch_barrier))
 		{
 			/*
-			 * Technically we shouldn't access the barrier because we're no
-			 * longer attached, but since there is no way it's moving after
-			 * this point it seems safe to make the following assertion.
+			 * We are not longer attached to the batch barrier, but we're the
+			 * process that was chosen to free resources and it's safe to
+			 * assert the current phase.  The ParallelHashJoinBatch can't go
+			 * away underneath us while we are attached to the build barrier,
+			 * making this access safe.
 			 */
 			Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_FREE);
 
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index f189fb4d28..93bf0ad6e9 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -86,6 +86,7 @@
  *  PHJ_BATCH_ALLOCATE*      -- one allocates buckets
  *  PHJ_BATCH_LOAD           -- all load the hash table from disk
  *  PHJ_BATCH_PROBE          -- all probe
+ *  PHJ_BATCH_SCAN*          -- one does full/right unmatched scan
  *  PHJ_BATCH_FREE*          -- one frees memory
  *
  * Batch 0 is a special case, because it starts out in phase
@@ -103,9 +104,10 @@
  * to a barrier, unless the barrier has reached a phase that means that no
  * process will wait on it again.  We emit tuples while attached to the build
  * barrier in phase PHJ_BUILD_RUN, and to a per-batch barrier in phase
- * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_FREE
- * respectively without waiting, using BarrierArriveAndDetach().  The last to
- * detach receives a different return value so that it knows that it's safe to
+ * PHJ_BATCH_PROBE.  These are advanced to PHJ_BUILD_FREE and PHJ_BATCH_SCAN
+ * respectively without waiting, using BarrierArriveAndDetach() and
+ * BarrierArriveAndDetachExceptLast() respectively.  The last to detach
+ * receives a different return value so that it knows that it's safe to
  * clean up.  Any straggler process that attaches after that phase is reached
  * will see that it's too late to participate or access the relevant shared
  * memory objects.
@@ -393,8 +395,23 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 					if (HJ_FILL_INNER(node))
 					{
 						/* set up to scan for unmatched inner tuples */
-						ExecPrepHashTableForUnmatched(node);
-						node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						if (parallel)
+						{
+							/*
+							 * Only one process is currently allow to handle
+							 * each batch's unmatched tuples, in a parallel
+							 * join.
+							 */
+							if (ExecParallelPrepHashTableForUnmatched(node))
+								node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+							else
+								node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						}
+						else
+						{
+							ExecPrepHashTableForUnmatched(node);
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						}
 					}
 					else
 						node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -487,25 +504,13 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					node->hj_MatchedOuter = true;
 
-					if (parallel)
-					{
-						/*
-						 * Full/right outer joins are currently not supported
-						 * for parallel joins, so we don't need to set the
-						 * match bit.  Experiments show that it's worth
-						 * avoiding the shared memory traffic on large
-						 * systems.
-						 */
-						Assert(!HJ_FILL_INNER(node));
-					}
-					else
-					{
-						/*
-						 * This is really only needed if HJ_FILL_INNER(node),
-						 * but we'll avoid the branch and just set it always.
-						 */
+
+					/*
+					 * This is really only needed if HJ_FILL_INNER(node), but
+					 * we'll avoid the branch and just set it always.
+					 */
+					if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)))
 						HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple));
-					}
 
 					/* In an antijoin, we never return a matched tuple */
 					if (node->js.jointype == JOIN_ANTI)
@@ -563,7 +568,8 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				 * so any unmatched inner tuples in the hashtable have to be
 				 * emitted before we continue to the next batch.
 				 */
-				if (!ExecScanHashTableForUnmatched(node, econtext))
+				if (!(parallel ? ExecParallelScanHashTableForUnmatched(node, econtext)
+					  : ExecScanHashTableForUnmatched(node, econtext)))
 				{
 					/* no more unmatched tuples */
 					node->hj_JoinState = HJ_NEED_NEW_BATCH;
@@ -1197,13 +1203,44 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 					 * hash table stays alive until everyone's finished
 					 * probing it, but no participant is allowed to wait at
 					 * this barrier again (or else a deadlock could occur).
-					 * All attached participants must eventually call
-					 * BarrierArriveAndDetach() so that the final phase
-					 * PHJ_BATCH_FREE can be reached.
+					 * All attached participants must eventually detach from
+					 * the barrier and one worker must advance the phase so
+					 * that the final phase is reached.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
 					sts_begin_parallel_scan(hashtable->batches[batchno].outer_tuples);
+
+					/*
+					 * This is a good place to assert that the batch's
+					 * work_queue has been set to point to the head of the
+					 * chunk list.  No new chunks are created once this phase
+					 * is reached, and we don't want to have to do any extra
+					 * IPC just to set up the work_queue that the later
+					 * PHJ_BATCH_SCAN phase wants, so instead require that it
+					 * has been maintained correctly by the earlier phases.
+					 */
+					Assert(hashtable->batches[batchno].shared->work_queue ==
+						   hashtable->batches[batchno].shared->chunks);
+
 					return true;
+				case PHJ_BATCH_SCAN:
+
+					/*
+					 * In principle, we could help scan for unmatched tuples,
+					 * since that phase is already underway (the thing we can't
+					 * do under current deadlock-avoidance rules is wait for
+					 * others to arrive at PHJ_BATCH_SCAN, because
+					 * PHJ_BATCH_PROBE emits tuples, but in this case we just
+					 * got here without waiting).  That is not yet done.  For
+					 * now, we just detach and go around again.  We have to use
+					 * ExecHashTableDetachBatch() because there's a small
+					 * chance we'll be the last to detach, and then we're
+					 * responsible for freeing memory.
+					 */
+					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
+					hashtable->batches[batchno].done = true;
+					ExecHashTableDetachBatch(hashtable);
+					break;
 
 				case PHJ_BATCH_FREE:
 
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index e6ef0deb23..bd51e4f972 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2193,15 +2193,9 @@ hash_inner_and_outer(PlannerInfo *root,
 		 * able to properly guarantee uniqueness.  Similarly, we can't handle
 		 * JOIN_FULL and JOIN_RIGHT, because they can produce false null
 		 * extended rows.  Also, the resulting path must not be parameterized.
-		 * We would be able to support JOIN_FULL and JOIN_RIGHT for Parallel
-		 * Hash, since in that case we're back to a single hash table with a
-		 * single set of match bits for each batch, but that will require
-		 * figuring out a deadlock-free way to wait for the probe to finish.
 		 */
 		if (joinrel->consider_parallel &&
 			save_jointype != JOIN_UNIQUE_OUTER &&
-			save_jointype != JOIN_FULL &&
-			save_jointype != JOIN_RIGHT &&
 			outerrel->partial_pathlist != NIL &&
 			bms_is_empty(joinrel->lateral_relids))
 		{
@@ -2235,9 +2229,13 @@ hash_inner_and_outer(PlannerInfo *root,
 			 * total inner path will also be parallel-safe, but if not, we'll
 			 * have to search for the cheapest safe, unparameterized inner
 			 * path.  If doing JOIN_UNIQUE_INNER, we can't use any alternative
-			 * inner path.
+			 * inner path.  If full or right join, we can't use parallelism
+			 * (building the hash table in each backend) because no one
+			 * process has all the match bits.
 			 */
-			if (cheapest_total_inner->parallel_safe)
+			if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT)
+				cheapest_safe_inner = NULL;
+			else if (cheapest_total_inner->parallel_safe)
 				cheapest_safe_inner = cheapest_total_inner;
 			else if (save_jointype != JOIN_UNIQUE_INNER)
 				cheapest_safe_inner =
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 0abd888d1e..7615025d73 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -154,6 +154,7 @@ typedef struct ParallelHashJoinBatch
 	Barrier		batch_barrier;	/* synchronization for joining this batch */
 
 	dsa_pointer chunks;			/* chunks of tuples loaded */
+	dsa_pointer work_queue;		/* cursor for processing all chunks */
 	size_t		size;			/* size of buckets + chunks in memory */
 	size_t		estimated_size; /* size of buckets + chunks while writing */
 	size_t		ntuples;		/* number of tuples loaded */
@@ -266,7 +267,8 @@ typedef struct ParallelHashJoinState
 #define PHJ_BATCH_ALLOCATE				1
 #define PHJ_BATCH_LOAD					2
 #define PHJ_BATCH_PROBE					3
-#define PHJ_BATCH_FREE					4
+#define PHJ_BATCH_SCAN					4
+#define PHJ_BATCH_FREE					5
 
 /* The phases of batch growth while hashing, for grow_batches_barrier. */
 #define PHJ_GROW_BATCHES_ELECT			0
@@ -356,6 +358,9 @@ typedef struct HashJoinTableData
 	HashMemoryChunk unmatched_scan_chunk;
 	size_t		unmatched_scan_idx;
 
+	/* index of tuple within current chunk for serial unmatched inner scan */
+	size_t		current_chunk_idx;
+
 	/* Shared and private state for Parallel Hash. */
 	HashMemoryChunk current_chunk;	/* this backend's current chunk */
 	dsa_area   *area;			/* DSA area to allocate memory from */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index d7634af05c..56d5350c61 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -56,8 +56,11 @@ extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
 extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
+extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
 extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
 										  ExprContext *econtext);
+extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
+												  ExprContext *econtext);
 extern void ExecHashTableReset(HashJoinTable hashtable);
 extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
 extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 3ec07bc1af..027f3888b0 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -784,8 +784,9 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
@@ -806,7 +807,32 @@ select  count(*) from simple r full outer join simple s using (id);
 (1 row)
 
 rollback to settings;
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: (r.id = s.id)
+                     ->  Parallel Seq Scan on simple r
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple s
+(9 rows)
+
+select  count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
+rollback to settings;
+-- A full outer join where every record is not matched.
 -- non-parallel
 savepoint settings;
 set local max_parallel_workers_per_gather = 0;
@@ -829,8 +855,9 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 (1 row)
 
 rollback to settings;
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
@@ -850,6 +877,31 @@ select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
  40000
 (1 row)
 
+rollback to settings;
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+                         QUERY PLAN                          
+-------------------------------------------------------------
+ Finalize Aggregate
+   ->  Gather
+         Workers Planned: 2
+         ->  Partial Aggregate
+               ->  Parallel Hash Full Join
+                     Hash Cond: ((0 - s.id) = r.id)
+                     ->  Parallel Seq Scan on simple s
+                     ->  Parallel Hash
+                           ->  Parallel Seq Scan on simple r
+(9 rows)
+
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+ count 
+-------
+ 40000
+(1 row)
+
 rollback to settings;
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index 77dbc182d5..ba1b3e6e1b 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -435,15 +435,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s using (id);
 select  count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
--- An full outer join where every record is not matched.
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s using (id);
+select  count(*) from simple r full outer join simple s using (id);
+rollback to settings;
+
+-- A full outer join where every record is not matched.
 
 -- non-parallel
 savepoint settings;
@@ -453,14 +462,24 @@ explain (costs off)
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
--- parallelism not possible with parallel-oblivious outer hash join
+-- parallelism not possible with parallel-oblivious full hash join
 savepoint settings;
+set enable_parallel_hash = off;
 set local max_parallel_workers_per_gather = 2;
 explain (costs off)
      select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
 rollback to settings;
 
+-- parallelism is possible with parallel-aware full hash join
+savepoint settings;
+set local max_parallel_workers_per_gather = 2;
+explain (costs off)
+     select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+select  count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
+rollback to settings;
+
+
 -- exercise special code paths for huge tuples (note use of non-strict
 -- expression and left join required to get the detoasted tuple into
 -- the hash table)
-- 
2.39.2

v13-0003-XXX-fixup.patchtext/x-patch; charset=US-ASCII; name=v13-0003-XXX-fixup.patchDownload
From f806c211d2d1128303f7ed29bf8d9b8395d3a859 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 27 Mar 2023 16:32:22 +1300
Subject: [PATCH v13 3/4] XXX fixup

---
 src/backend/executor/nodeHash.c     | 34 +++++++++++++++++++++++++++++
 src/backend/executor/nodeHashjoin.c |  2 ++
 src/include/executor/hashjoin.h     |  3 ++-
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 58789be71a..6539b32d45 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2116,6 +2116,17 @@ ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
 	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
 	Assert(BarrierParticipants(&batch->batch_barrier) == 1);
 
+	/*
+	 * Has another process decided to give up early and command all processes
+	 * to skip the unmatched scan?
+	 */
+	if (batch->skip_unmatched)
+	{
+		hashtable->batches[hashtable->curbatch].done = true;
+		ExecHashTableDetachBatch(hashtable);
+		return false;
+	}
+
 	/*
 	 * See also ExecParallelHashJoinNewBatch()'s assertion that
 	 * batch->work_queue == batch->chunks.  That is, we are now ready to start
@@ -3211,6 +3222,7 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable)
 		accessor->shared = shared;
 		accessor->preallocated = 0;
 		accessor->done = false;
+		accessor->outer_eof = false;
 		accessor->inner_tuples =
 			sts_attach(ParallelHashJoinBatchInner(shared),
 					   ParallelWorkerNumber + 1,
@@ -3266,6 +3278,28 @@ ExecHashTableDetachBatch(HashJoinTable hashtable)
 		Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE ||
 			   BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
 
+		/*
+		 * If we're abandoning the PHJ_BATCH_PROBE phase early without having
+		 * reached the end of it, it means the plan doesn't want any more
+		 * tuples, and it is happy to abandon any tuples buffered in this
+		 * process's subplans.  For correctness, we can't allow any process to
+		 * execute the PHJ_BATCH_SCAN phase, because we will never have the
+		 * complete set of match bits.  Therefore we skip emitting unmatched
+		 * tuples in all backends (if this is a full/right join), as if those
+		 * tuples were all due to be emitted by this process and it has
+		 * abandoned them too.
+		 */
+		if (BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE &&
+			!hashtable->batches[curbatch].outer_eof)
+		{
+			/*
+			 * This flag may be written to by multiple backends during
+			 * PHJ_BATCH_PROBE phase, but will only be read in PHJ_BATCH_SCAN
+			 * phase so requires no extra locking.
+			 */
+			batch->skip_unmatched = true;
+		}
+
 		/*
 		 * Even if we aren't doing a full/right outer join, we'll step through
 		 * the PHJ_BATCH_SCAN phase just to maintain the invariant that freeing
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 93bf0ad6e9..c8af59f106 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -972,6 +972,8 @@ ExecParallelHashJoinOuterGetTuple(PlanState *outerNode,
 	}
 
 	/* End of this batch */
+	hashtable->batches[curbatch].outer_eof = true;
+
 	return NULL;
 }
 
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 7615025d73..f5fcf7d4e6 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -160,6 +160,7 @@ typedef struct ParallelHashJoinBatch
 	size_t		ntuples;		/* number of tuples loaded */
 	size_t		old_ntuples;	/* number of tuples before repartitioning */
 	bool		space_exhausted;
+	bool		skip_unmatched;	/* whether to abandon unmatched scan */
 
 	/*
 	 * Variable-sized SharedTuplestore objects follow this struct in memory.
@@ -204,7 +205,7 @@ typedef struct ParallelHashJoinBatchAccessor
 	size_t		estimated_size; /* size of partition on disk */
 	size_t		old_ntuples;	/* how many tuples before repartitioning? */
 	bool		at_least_one_chunk; /* has this backend allocated a chunk? */
-
+	bool		outer_eof;		/* has this process hit end of batch? */
 	bool		done;			/* flag to remember that a batch is done */
 	SharedTuplestoreAccessor *inner_tuples;
 	SharedTuplestoreAccessor *outer_tuples;
-- 
2.39.2

#32Melanie Plageman
melanieplageman@gmail.com
In reply to: Thomas Munro (#31)
1 attachment(s)
Re: Parallel Full Hash Join

On Mon, Mar 27, 2023 at 7:04 PM Thomas Munro <thomas.munro@gmail.com> wrote:

I found another problem. I realised that ... FULL JOIN ... LIMIT n
might be able to give wrong answers with unlucky scheduling.
Unfortunately I have been unable to reproduce the phenomenon I am
imagining yet but I can't think of any mechanism that prevents the
following sequence of events:

P0 probes, pulls n tuples from the outer relation and then the
executor starts to shut down (see commit 3452dc52 which pushed down
LIMIT), but just then P1 attaches, right before P0 does. P1
continues, and finds < n outer tuples while probing and then runs out
so it enters the unmatched scan phase, and starts emitting bogusly
unmatched tuples. Some outer tuples we needed to get the complete set
of match bits and thus the right answer were buffered inside P0's
subplan and abandoned.

I've attached a simple fixup for this problem. Short version: if
you're abandoning your PHJ_BATCH_PROBE phase without reaching the end,
you must be shutting down, so the executor must think it's OK to
abandon tuples this process has buffered, so it must also be OK to
throw all unmatched tuples out the window too, as if this process was
about to emit them. Right?

I understand the scenario you are thinking of, however, I question how
those incorrectly formed tuples would ever be returned by the query. The
hashjoin would only start to shutdown once enough tuples had been
emitted to satisfy the limit, at which point, those tuples buffered in
p0 may be emitted by this worker but wouldn't be included in the query
result, no?

I suppose even if what I said is true, we do not want the hashjoin node
to ever produce incorrect tuples. In which case, your fix seems correct to me.

With all the long and abstract discussion of hard to explain problems
in this thread and related threads, I thought I should take a step
back and figure out a way to demonstrate what this thing really does
visually. I wanted to show that this is a very useful feature that
unlocks previously unobtainable parallelism, and to show the
compromise we've had to make so far in an intuitive way. With some
extra instrumentation hacked up locally, I produced the attached
"progress" graphs for a very simple query: SELECT COUNT(*) FROM r FULL
JOIN s USING (i). Imagine a time axis along the bottom, but I didn't
bother to add numbers because I'm just trying to convey the 'shape' of
execution with relative times and synchronisation points.

Figures 1-3 show that phases 'h' (hash) and 'p' (probe) are
parallelised and finish sooner as we add more processes to help out,
but 's' (= the unmatched inner tuple scan) is not. Note that if all
inner tuples are matched, 's' becomes extremely small and the
parallelism is almost as fair as a plain old inner join, but here I've
maximised it: all inner tuples were unmatched, because the two
relations have no matches at all. Even if we achieve perfect linear
scalability for the other phases, the speedup will be governed by
https://en.wikipedia.org/wiki/Amdahl%27s_law and the only thing that
can mitigate that is if there is more useful work those early-quitting
processes could do somewhere else in your query plan.

Figure 4 shows that it gets a lot fairer in a multi-batch join,
because there is usually useful work to do on other batches of the
same join. Notice how processes initially work on loading, probing
and scanning different batches to reduce contention, but they are
capable of ganging up to load and/or probe the same batch if there is
nothing else left to do (for example P2 and P3 both work on p5 near
the end). For now, they can't do that for the s phases. (BTW, the
little gaps before loading is the allocation phase that I didn't
bother to plot because they can't fit a label on them; this
visualisation technique is a WIP.)

With the "opportunistic" change we are discussing for later work,
figure 4 would become completely fair (P0 and P2 would be able to join
in and help out with s6 and s7), but single-batch figures 1-3 would
not (that would require a different executor design AFAICT, or a
eureka insight we haven't had yet; see long-winded discussion).

Cool diagrams!

The last things I'm thinking about now: Are the planner changes
right?

I think the current changes are correct. I wonder if we have to change
anything in initial/final_cost_hashjoin to account for the fact that
for a single batch full/right parallel hash join, part of the
execution is serial. And, if so, do we need to consider the estimated
number of unmatched tuples to be emitted?

Are the tests enough?

So, the tests currently in the patch set cover the unmatched tuple scan
phase for single batch parallel full hash join. I've attached the
dumbest possible addition to that which adds in a multi-batch full
parallel hash join case. I did not do any checking to ensure I picked
the case which would add the least execution time to the test, etc.

Of course, this does leave the skip_unmatched code you added uncovered,
but I think if we had the testing infrastructure to test that, we would
be on a beach somewhere reading a book instead of beating our heads
against the wall trying to determine if there are any edge cases we are
missing in adding this feature.

- Melanie

Attachments:

Add-multi-batch-parallel-full-hash-join-test.patchtext/x-patch; charset=US-ASCII; name=Add-multi-batch-parallel-full-hash-join-test.patchDownload
From e357b1299be2ef7a2949825af54572afc3e734eb Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Thu, 30 Mar 2023 15:04:48 -0400
Subject: [PATCH v1] Add multi-batch parallel full hash join test

---
 src/test/regress/expected/join_hash.out | 7 +++++++
 src/test/regress/sql/join_hash.sql      | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out
index 027f3888b0..09376514bb 100644
--- a/src/test/regress/expected/join_hash.out
+++ b/src/test/regress/expected/join_hash.out
@@ -304,6 +304,13 @@ $$);
  t                    | f
 (1 row)
 
+-- parallel full multi-batch hash join
+select count(*) from simple r full outer join simple s using (id);
+ count 
+-------
+ 20000
+(1 row)
+
 rollback to settings;
 -- The "bad" case: during execution we need to increase number of
 -- batches; in this case we plan for 1 batch, and increase at least a
diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql
index ba1b3e6e1b..179e94941c 100644
--- a/src/test/regress/sql/join_hash.sql
+++ b/src/test/regress/sql/join_hash.sql
@@ -187,6 +187,8 @@ select original > 1 as initially_multibatch, final > original as increased_batch
 $$
   select count(*) from simple r join simple s using (id);
 $$);
+-- parallel full multi-batch hash join
+select count(*) from simple r full outer join simple s using (id);
 rollback to settings;
 
 -- The "bad" case: during execution we need to increase number of
-- 
2.37.2

#33Thomas Munro
thomas.munro@gmail.com
In reply to: Melanie Plageman (#32)
2 attachment(s)
Re: Parallel Full Hash Join

On Fri, Mar 31, 2023 at 8:23 AM Melanie Plageman
<melanieplageman@gmail.com> wrote:

I understand the scenario you are thinking of, however, I question how
those incorrectly formed tuples would ever be returned by the query. The
hashjoin would only start to shutdown once enough tuples had been
emitted to satisfy the limit, at which point, those tuples buffered in
p0 may be emitted by this worker but wouldn't be included in the query
result, no?

Yeah, I think I must have been confused by that too early on. The
thing is, Gather asks every worker process for n tuples so that any
one of them could satisfy the LIMIT if required, but it's unknown
which process's output the Gather node will receive first (or might
make it into intermediate nodes and affect the results). I guess to
see bogus unmatched tuples actually escaping anywhere (with the
earlier patches) you'd need parallel leader off + diabolical
scheduling?

I thought about 3 solutions before settling on #3: (1)
Hypothetically, P1 could somehow steal/finish P0's work, but our
executor has no mechanism for anything like that. (2) P0 isn't
allowed to leave the probe early, instead it has to keep going but
throw away the tuples it'd normally emit, so we are sure we have all
the match bits in shared memory. (3) P0 seizes responsibility for
emitting those tuples, but then does nothing because the top level
executor doesn't want more tuples, which in practice looks like a flag
telling everyone else not to bother.

Idea #1 would probably require shared address space (threads) and a
non-recursive executor, as speculated about a few times before, and
that type of magic could address several kinds of deadlock risks, but
in this case we still wouldn't want to do that even if we could; it's
work that is provably (by idea #3's argument) a waste of time. Idea
#2 is a horrible pessimisation of idea #1 within our existing executor
design, but it helped me think about what it really means to be
authorised to throw away tuples from on high.

I suppose even if what I said is true, we do not want the hashjoin node
to ever produce incorrect tuples. In which case, your fix seems correct to me.

Yeah, that's a good way to put it.

The last things I'm thinking about now: Are the planner changes
right?

I think the current changes are correct. I wonder if we have to change
anything in initial/final_cost_hashjoin to account for the fact that
for a single batch full/right parallel hash join, part of the
execution is serial. And, if so, do we need to consider the estimated
number of unmatched tuples to be emitted?

I have no idea how to model that, and I'm assuming the existing model
should continue to work as well as it does today "on average". The
expected number of tuples will be the same across all workers, it's
just an unfortunate implementation detail that the distribution sucks
(but is still much better than a serial plan). I wondered if
get_parallel_divisor() might provide some inspiration but that's
dealing with a different problem: a partial extra process that will
take some of the work (ie tuples) away from the other processes, and
that's not the case here.

Are the tests enough?

So, the tests currently in the patch set cover the unmatched tuple scan
phase for single batch parallel full hash join. I've attached the
dumbest possible addition to that which adds in a multi-batch full
parallel hash join case. I did not do any checking to ensure I picked
the case which would add the least execution time to the test, etc.

Thanks, added.

I should probably try to figure out how to get the join_hash tests to
run with smaller tables. It's one of the slower tests and this adds
to it. I vaguely recall it was hard to get the batch counts to be
stable across the build farm, which makes me hesitant to change the
tests but perhaps I can figure out how to screw it down...

I decided to drop the scan order change for now (0001 in v13). Yes,
it's better than what we have now, but it seems to cut off some other
possible ideas to do even better, so it feels premature to change it
without more work. I changed the parallel unmatched scan back to
being as similar as possible to the serial one for now.

I committed the main patch.

Here are a couple of ideas that came up while working on this, for future study:

* the "opportunistic help" thing you once suggested to make it a
little fairer in multi-batch cases. Quick draft attached, for future
experimentation. Seems to work pretty well, but could definitely be
tidier and there may be holes in it. Pretty picture attached.

* should we pass HJ_FILL_INNER(hjstate) into a new parameter
fill_inner to ExecHashJoinImpl(), so that we can make specialised hash
join routines for the yes and no cases, so that we can remove
branching and memory traffic related to match bits?

* could we use tagged pointers to track matched tuples? Tuples are
MAXALIGNed, so bits 0 and 1 of pointers to them are certainly always
0. Perhaps we could use bit 0 for "matched" and bit 1 for "I am not
the last tuple in my chain, you'll have to check the next one too".
Then you could scan for unmatched without following many pointers, if
you're lucky. You could skip the required masking etc for that if
!fill_inner.

* should we use software prefetching to smooth over the random memory
order problem when you do have to follow them? Though it's hard to
prefetch chains, here we have an array full of pointers at least to
the first tuples in each chain. This probably goes along with the
general hash join memory prefetching work that I started a couple of
years back and need to restart for 17.

* this idea is probably stupid overkill, but it's something that
v13-0001 made me think about: could it be worth the effort to sample a
fraction of the match bits in the hash table buckets (with the scheme
above), and determine whether you'll be emitting a high fraction of
the tuples, and then switch to chunk based so that you can do it in
memory order if so? That requires having the match flag in *two*
places, which seems silly; you'd need some experimental evidence that
any of this is worth bothering with

* currently, the "hash inner" phase only loads tuples into batch 0's
hash table (the so-called "hybrid Grace" technique), but if there are
(say) 4 processes, you could actually load batches 0-3 into memory
during that phase, to avoid having to dump 1-3 out to disk and then
immediately load them back in again; you'd get to skip "l1", "l2",
"l3" on those diagrams and finish a good bit faster

Attachments:

more-parallel.pngimage/png; name=more-parallel.pngDownload
�PNG


IHDR�C>�sBIT|d�tEXtSoftwaregnome-screenshot��> IDATx���{X���>�s��7
�����b��L5M�C%�eY��������t)����`�LQ���,7��4(]�b(��-�N@��0�������y�a=?������3�2�<�\���F!@DDDDDDD�5K/��������,�
"""""""b����������  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""v�^�����?FII���Q�|||0}�tK/��������wY��%Kp��e��N���m��
�\��b��](--5)/,,�o���VkR�����[����>3��u�;�,@��`���x��G�d�3�<��M��q^\\�: 22M�4��<77;w���#���}����W����^��'"""""��BK/��~������x[z)�"!!���Crr���BDDDDDF�G��������1 �������g-��z???K/������� 6��v���7�|!!!�^J�9y�$>��c�?��K!"""""2�
�8!����y�fK/��DDDXz	DDDDDD��Y�k��A��I���lTUU��gffBiNcr%W�^U��[���jyUU���M�u:�]�fr^QQ���iNDDDDD��
�J���8v���I�t�R�9sF�P����p���ucr�&��o���WVVJ_����a���&�Z~��u,^�X��jyff&�-[&m�������
� DDDDDd}�  �OOO���'��K���A����w�������oL��� �{����k4�������_-wttD��]��������s����3�	$����m�����������:i�G��[���{DDD�7)���C||<���-��z����q��!99��K!"""""#�DDDDDDD��A@DDDDDDD`����������Y�k��IG@vv�t��1yff��>cr%J#(>�B������*�Ccr�N'ahL^QQ���iNDDDDD��
�J���>�M���_8q���	������DJJ����1��+W���6m�b������a0�j�x��7���nR����w�yG��jyzz:.\���,�����[�N�	BDDDDD��
�J�>�(Z�h��D�___h4��#F���[��������ydd�bnkk����F�)=^-wuu���?WWW�r///2D�>������w���������:i�G��[�b����^J����@DD�����C||<���-��z����q��!99��K!"""""#�YzDt��z�*��;g�e����;������ """"2	DT�6m������}�;v�W��SO=e����
"�w���6l��]k������scF""""j��I!�A@�)++K:�222�#������kL�Di�!��B(>�Z^UU%ahL����#�������������H���2��������*~����&�DDDDD�d��.]���Di� **
'N��6����z)))����JM��^{M1��t��Z��g��6����<��_��>�Z����E�I�j��s���?Hv����G}$m?~111�&�Z�������Z�P�����f�i@-'""""j��Y�G}-Z�������������FcR>b�x{{K��1����4���T�mmm���b0spp���#�������x������jR����!C�H�������{��HLL����������aaaprr2)o��5������]�v�������I9Qc��U�,,66[�n����-��z����?�������{vW����7������9r����p��������R�����L��DDDDDDD��
"""""""d�����# ##C:���<==]:���\���C��-�P||����J:���\��IG����KG����PVV&ahL^ZZ�������b��j9Qc�Y��K�"11Q�$�����'�M�����BJJ����1�R���^S�u:��E�V������M�<//�����������c��E�&�Z~��9�������s���GI���GLL��	��'$$�����6����x�Y�F�P������+;K/���������`��3��E���1��R�_x����@����{zzJ����/+�vvvpww7�9::��_����I���;��#}|��i���������Iy�-���Di>b�����[�n����������}��puu����IyHH������dRNDDDD�Xi��{��@ll,�n����7[z)�&""?~<����������IBB�����d@LL�9��k�Zxe�g����>}:"##-�"""""��#DDDDDDD��A@DDDDDDD`����������Y���TTTH���tTVV��_�r���f�J.^���+�
Z]]���jyee�t�1yEE�t�1��7������F$7�8�F ����HG �IG �5Vl�UZ�p!<(m���[8z���	��O�>g���6����'NT�u:��EzYY�M�&m��yyy�5k�������4��;W�P�����j�*i$99�����I����?�P�P�����"&&F�P���7|��7�&�ZNDDDD�X�YzD��;AAA��3�Ot��	h��lmmM�_y�4o�66�{d��M�4�����_W�������i0stt���S���eR�����'J_-�����/�����2'O���c�������<((���pss3)���������jR��[7�i�...&�DDDDD��F(�������b�����y���Ro"""����������`�.��$$$`��qHNN������#X�v��WV����#22��K!""""2	?b@DDDDDDDl�  """"j4��YsOd�����j�e�w�  �GJ7"$""�����Kh���~_�{���3QPP`�e���  ����888�������'�r��_�r�)�������_�xm����J{�VWW#==]��jy�x+V����?_����l�h���q�������I��7���']��7PPP???��V�EII	�5kfR^RR�7n������������)j9�%�~�\s��h4���,���~��r�6m0p�@�m��������YYY0)7���Mj"���Y����^��?l�I��[oa��Y

5�P��O���K�"88�`��<&&Fz1�8q"V�Z%�u:���
N1(++��i����_�X��5�Z-����#G���?��lll��HKK��E����������X�j��	����o��,0�$HJJ��M����ol�����q�������j�o�����L�2�`@-'"�����^���x��.o��vvv4h��1�������/���gg�;�W�^�v���w��prr����/�@�^�j��k��[o����Q�;��+���0k�,|����j��u5,6�*�;AAA�wL�0�Z�����I�+������K�!`L������_W�����o�wtt���S��s��V���c�=�g�y_}��7o�zL`` ^|�Exxx�}}}���2'O���c�������<((���pss3)�����������uC�6m���bRND�G���,�?��u3��oZZ222��K�/���.����		1�X-ONN��7GGG����x,\�������e����F�A���
�������x�����q�����M��u����j���=`��}k��.��Tw�[Wxxx`�����E-W��r"jXl�U�������C���x��z�G������H_ �����'�����n��a������aaa7n�b�����>��4���P��6m����+��������O��c�V�Z�U�V&�<��43&'"�d���|��\M����n����������_�~f��;����������
39W��r"jXl��n}���m�e��Z�
!!!pwwG����777���c��y��������������������Z�5
&M��+W���w���w��������$���������A@�5!��;���\t��U�����������BUUU���������q� �@FF������������w�}��_~���?�={������?�|������'����Ng���k���<yiii���h4h��%�DDDDD�Y���4TTTH���/�y�������?++��m����q��e@JJ
"##��wo��7.�����~�z��7Ou}/^T�SSSs�@��<b��W����_����1y�d,_�{����������VTT(6����2\�vM1�z��4/--EVV��yqq1rrrL����krND����������79W������Bi������b����,�����_�zU��������s����J}�dJnn]AD
�
�Js�������M�3f 11Q�$���������#x���������'�����������7/^���(DGG#%%��Gvv���&N��x1~������
��T��b��	���Z�G���'��O?��!C�Yee%�N�*���.]��Y��k����3���/�M�3g�`����&Abb"�{�=i!������������Z�k�.�X�BZ���Dd�����q�F�\�R�P���[�����6	���+���O�&�Z��'�`��m�&�Z�h�"���W�P��wJu��u��k���������  �4k�,��s��E���
�Jj�S���Cbb"
�����
]�t�s���=�L����+�2\�h�����?�X1����Npvv������Y3�r5���X�j���	�e��x��7���cR�1c���>��J��;w�///�<f��W�^h���t�Z��t��U:�Y-'"�d����{pss3)W3j�(h4�����}�Y899�����|����������I���S��ys888������s��&M�`�����E-7�� ���Y�=z(�}��Q�o�7��K���;x��������������m[��Q�������H�4[[[���I�U�������7c��Q:t��c��+�������rOOO+���w��M�6E��MM��7o�������l�-[�49'"�d�����[K3cr5AAA���>hVbV��kW����R�aN]����������u5,~���yvvv=z4F������a������y��s���7��6(�Qbb"6m����$<��s�N�7�x��5C@@�z�-Yx�DDDDDd���/L�<'O�Dpp0z����;"==�~�)z��\�|�����o�[H���u��l�2������S�%K� ::��?������_�~8x��=3��������6�����~���6l����(99���<x0������kU]]
���`���B`����+W��g����3g����+-�\"""""�2l�}%,,���Guu5��?���\xyy!((��o|������2�R��C^^���0b���=�������PTT��������H�{�UJKK��8���/KG������G��}��c�:����TWWK�W1(�# �>��O�>X�l���/�����E��:��{w�={����;������]S�e#�Y��>�������;���G��jrss�# ''G:���<++K:��������#��������Fs�����?,�#&�o�A@Vi��9����I0c�$&&*6	������?+t2#G����'�M��'*6��7_d���:�x��Q8~�8�x�	L�:K�.<���u�m���B��y�g����_~)m��9ss���6	�f�[�,s"�N�~���q#V�\)m��j��[�u��I�_}�~��'��A-���O�m�6i@-_�h���+m�����Bq��8p���D�'Ada�W���KLL999�����1yyy����`���.F�%��i#��o��Y<�������;v���������@1/..�������Q�F���X�m___q��a��VVV��������;�����{��'�����3g��gt��	q��U!�+V�������D$$$�VkR^PP ��Y#:t���/::Z�7N�>|Xz|nn�8z��(++3)���'N�7n�0�k�Zq��i���.N�>-����(4h���q��c��rjJs�j�����.])))w�������p����p����|�r����ki�?��}���,����g��"�_��������>}�(�_~�%���\�x��'�����O?
���{1d����u�W��P-W�G����������y�NNN�?>���_'0`JKK�������x���>����===��w��]���*7w����3��m+���eND���s�Zn���u���������1p�@,\����o�����Z�	���5v���u�����{�9&"��G��t��u�l�aaa�;w.��w�p�m�g��AZZ�|�rK.��L�4	������^
Y6��������*��+W� 55666�2e
���K�,A||<t:����`>��#�������������sW��������+0x�`t���'OV�`������~���BBB�������={������~�F�>}����S
�FKpuu�F���2��#G��?5�����O`���������C�n�p��!�������zq�'=���:t(RSS��uk|��G���z���v���;�7r=z����>���Gc����U�V�m���z�*Z�h����u��a���8t�lmm-�l"""""��w�U�|�2������G�����~�����g�}�/_F��}����@�c

��Y�Z����J��^�+INNV��6S���V||����.\09///��`4&/++Cvv�b.�%%%�����\���u��X�z�����$�X�B�www����:t(��9c���_��k��I��ZND�I��RTT$�hLn��#//yyy&�j�]�����K���,��gdd�����<--Mq��Z�V7�+�ju�ZnL]��+e�r����
"jXl�U�9s&�������'�����/�m����}�p���={�����;vD�.]�������u���cq��Q�y�����Q�F)�������b��1���Z�������K/�j���1u�T��Z-?q�����M�'N`��Y�&ABB���+-�e���+N�>�����
��.}~�m��e��Iy�������e��}X�h��	���{�X�~=>��si@-W��w�a��U�&ALL~��Gi@-����i�&i@-�7ov��)m��ju�1�R]�Vw��Ju�Z]q��Q�h�Zi(���� �f�1�Db���"""��}������������1�O�EEE�\����o_�f��:��'DII���'N�V+��=Z+5j������n���HJJ2xlUU�8~��tV�Z^QQ!N�:%��������3g�������
6�:��������������Y����"55U5����u����x������/_.222>���K����
f��]�/_���j��A����
CD�SS���[������������;jdee���4����(��������QQQ"**���W�^������_�rEdee�G�~� IDAT�_�xQ������*����T���gT.��������\��P�;jrc�
Y'�����m�9����Uc�+n����p�J:tP�;v�h�����qqq0�X�;wV<^-����b��h���d0����C=$=V-���G�N�L����lr������@�\�����������N�BVV����v�Z���#��y��������������������H��19Y'�s���7���M��=w4o���\����b��U+��6m�������
��ju�Znn]ac���_�����D��� ������~3;j���i�;v��X������M�4	������V�X;;�������n�
��=WWW<���_�g�����w��pttl��5l�}A���DDDDD�)D��egg���FNN���BDDDD���A@VIm^���+����������2dgg+�������W�^��)S���o�W�^���l��g�y/��v��Y�����z�eND�I��RTT�xnP��=w���)�0T��\�vM:�����#��322�#������#����crs����;�2@��h�u5,6�*��+6v�,7v�R�t1V�G�x������+>q�����M�'N`��Y�&����_~�%���|����2e
����SO=��~�	���/��^x��qyyy�:�������e��}�����s��������K�j������V��6	bbb���?J�j�|�M�6I�j��y��s�Ni@-W�����+jrs���G��@��J3@��h�u50�NY$b���"""��}j����G,���G\���
Qw��Q�Dll��v�f�DRR��c���[����
6�:��������������Y�j��kL�:��}�����E��7��o������O�_S]]]/��
$6n���f"jx5����%??_�����z�����%����N���<..N����oGEE����:�_�zUddd���J�������er~��E���#���L�SSSE^^�Qyxx�����gT�crs���\���#..N���_��s|{�q��XW��Q��&�d��}�Z�4�4
���f�}^���+s��WmVy
gggTUU���p��������F��{{{,Y��>}:�����h��m[���;�������������&���;�7onV����_1o���Yy�6m���������ssK�66�o�U�;{]AD
�1 �F)$$���������={������~�F�>}����S
�F""""����  �F��g����C������[���><��Su��S�N���m�%5*lQ�����~��&M�������/^}�U7wU���y�+((�<`��5��k���?���2���c�,�"�{D�h�m�������QQQ�|P�u������������s�Yp�DD
#88��2�U�6m��I�Z�
4�B���#���&6�*]�p-[��������m����&����h���t�c�[_���������@��<�s��I_-��t�|�2��kgR^^^��W�J���k�Zdff�j�k���u�����b"  @�WUU���K��M������b���2eJ�K���h���������N��n���uR;����T���R�o�><�����_��Q3���=T�$�q��Y���������F����*++acc#����:����f�vvv�h4����G��K/��>���_uuu��+++���)=P�;{]AD
��c��9:t���u�t$N�>}����.��w��Q:tH:N�����S���������>����Sl���������C�����&�iii�{�����s&��N�������7)����D��}E������:������?���t����w��-�~�i���������k�t:�g�q���:��0a��z����V�\)�O�.����(��C"�TS���[6l��xnP����������,!�X�~�����O>s�����d��c�������E^^����9s�X�|�(((0)������+�������G�������R����C��������&7��8t���,..Nt��]��s|{�q��XWp�!���A@g�A���!JKK��������~���\��X���fi!��K�j��7�5k&�?n����j�Y�jyee�HKK39�������Y�j��7����E����� �q��������jEVV���������-��]TT$�]�v�9D���A�v�P;7(�NNN�W�^b����������'�����A~~������@���&�999���Pz�V����Dqq�Q���Z�`LnN]Q�uG\\�0`���������V���`���r��J���h���Y�����r���kh4��4
�U�mmm�o�5&���W�����������_ggg8;;���quu����4www�����9Y'�s���A-���+.\�i����W_�c�=vG�S{�Z����[1o���Y��G�r��m��ju������G/j(���� ��%�0�e����������������\�|���"""2DDDDf�l<����������Gll,��m'''4o�AAA

��S�,�Z"""96����LT]]����:�i:u����w���X�`z��
���@��Yh�DDD����233!����o��
������"""2
�A@V���(//��������Q����Q]]mV���������i�Uuu�����:����&�����p����V�Eff�b������b�����"##��<??���&�Dd�����~�z8::">>��=rrrLZ��k�p��5�s5��������(,,49OOOGqq��������jM���crs����;�2@��h�u5,6�*���+��g��b��/������Z��SO������1���x����yyy��bZRR��#GJ/�jyvv6��#}|�����?~��b��;v}���	r��1L�:U�$����0k�,i!������������Z�i�&,^�X�P���:��sGnnn��g�����R�������s�R����{|����&�Z������W_}%m,[�����&�Z����?�&�Z>{�ll��U�P���crs����������3(--�f�r�an]QZZ��3gJ�PZZZ�u50�Y$B�^�ZDDD��Om^�%����y�B��G<j�(����Y3q��q��6�y���q����}���������h1n�8}���!=^mVy}�2B���"q���;�
$6n�h�"���R�n�;���M^������@����q'��������DTTT�����E~~����2����������<''GJ��jyVV�(..6*qqq��j�`LnN]Q�uG\\�0`���������V����j�w����9&���=�*Y�<b�\i1ps�����4k��������+=�j���{����;���M���:��s�9���������j�����M��������7o���\�n07�t���hs���������j����oDV�o�����?b@DDDt�x��w��K������?}�������K�.��?��s������b��	������+����_����$������q#��gO������`�=�����O�>����-�R�;WZZ��^{
�����?���&�=z������x?�0�����O`��u^1�M�����o���L�0%%%�Y�f!))	!!!�?>rrr��K/a��h����WLd���L�6
_|�������>�����_~��GRRR��s�!22nnn�Z2�El�;;;��$777TTT`�����+W�o����3f���m�,�V�;ecc����Z�TWWc��Iu��C��1c�������\&�~���Rjj*n��!����U�
+��O�V�)lL��������n^���+�:�Nu��R~��
�����������KKKq��Ei^TT�+W���(�:W��������Dd��=w�zMi��y�q�@YY|||��O�����C��m�:g��� ''��\Mff&����yzz:


L��\����"���/*��S���crs����;�2@��0���t���v�^���/���;;������m�[WQ�b��������k�.��|�������^������#!!Az�5&W����O1///GJJ�����Xq��Z����8�X-?w���<c�<))	�-�6A���0a�i�`����6m���W�w�����gK}�|��
X�`���W���:�{�8{����6��M�V�|���n�����������o�|$�v�V���%K�M�\MLL����M����~�����Z>g�����&�Z>}�tl��Q�P���crs��}�����Sf�			3��@��0����������+����`��z���p���:������o�E����k3�� ���J��$j�����u+6o����������Q����pvv�v�����"�������^���B�������DDD`���???���!!!���������B�����������puu5)�������W^yE�������#G�v�ZTUU���...����Dyy9���M�u:***���bp,�Z^QQ���J8;;�Q>x�`L�>���u�!"��h4B�}�����uMY�t)>������������E||<���j��/����P\gyy9������d������x,\���������5/�
>~YYlll���`R��jakkGGG�?�������pppP���b���n>�����u�Z]QRR'''i����`cc#���1��0�9�����1u���4�����dffb������#v��ooo���666�|�2~��'<���������M�+n����p�Jj����W�=<<�57f^�R�a�<l�F��>����F����������E1Wz~����������K@cri�jLND���s�����3����w�}���P��������U�������8z�(&O���>�gcs5NNN���{cr���1����Y�Z�`n��o���j������8p�>��c,^�eee�l����&M�`���x��������DDDD&��������~�m���a��u�|�2���-�:jZ�������E���`�%�5�;w.f����'O���������:u��>}��6����a������.�����]�v���>��r�L���(--E��]k�����b����z����3f`��e��;������������R���A@DDDt=���x���-��K������<yM�6ps���_~#F�@HH���p��E����/\\\�d���4��������2����  """"�h��)��g��7\�r%v���.]����y��a��!����7�V�_|{���#�<�]�v����m�6888`��h����WJD��c�*��+��<b�y���<b���q���r�N'ahLn�����Rddd(������rsg���yyy�#�r"�N
q����R���999�#�r5���������8�������]��e#��������r����\�nh��%�����mccS�9��Lq���HJJ�u��u�R(�ju|����3g�.]���;��������<y2��o�o������]WQ�b������b�y�j�����r����<b��������1������L�9Rz�V���W����E�I� III�0a��I�6���Y�j��
�`�i!���uj�s����M>w�Z�
K�,�6�r5111����6	��}|����&�1���Z-���Ol��������6l�6	�O���7J�j�Z�`L�T7��� --M���Vz�sqqAyyy����;d��#�r��V77?2��W/L�:{�����k(..��������������q#���[����+���	"[�z�����u_qq�����STT$t:��yaa����������V>j�(����ysq��I�����L����Eaa��yUU�(**29���������������h1n�8}^\\,=^���������
QRR"���M����Eii���
7n4xYNM�c���7n�Z������8��%����_VV&�������j��7�y�s����G�������e������3Dyy��k���%%%��V)qqq��j�`L.��������4h������f��_?e����U�>s�
c��������3f��u�������F���������c�=V�k�����9&���=�P�v�p��yK/�^���)�Vm���\���y�j���a������4f:t0x�������6���Y�j�������j9Y'k?w8::J3cr5j������zs6�Sz������U���s���4t��
����6����Add$�������������h��E����[W�Q�;���m�����

������

�u=wssC�=�����_��(����F�.S���a�A`�4
���b���8�<BBB������c��A`` JKK���?"++�;w���U����=���())����Q\\���;���GPP�b��S'DFF���EEE����Q]]���l����wW�����t�RK��-j��M�����2�������@DDw���a��:u��C�)~MPP��????L�0��Vv�DFF����������uk|����'�|���v������_Q����h4���'z�����0|���X�z5�|�I����D��acss����0,X�����1b����w�A�v���h����������?b��1�9s�b���o�U�V��i��a���x���1c�����|�AC�X��N�����U�-;����
����Klp�~����`���@,X�O<��~�
___��9���j4�wdQ����KII��#GPYY���L\�~]��N�:��G��Qyqqq��������akk�+W���Z��V~��a�<y���8�������k�����Bzz:��������!���oT����������j���!##C1������#<==��������������l����	^^^h�����}{zz��?����YNII	rss��k6�3t}7�aY�a��!55�7oFEE�|�I}�1~�x�����O?���1l�0�����X���2���������={� 44��-���;�����`�����|���8r������o����0����M�6�����q��Y������o ""�������Q��������q��|���8r������S'���c��=x��g�����������F��=����c��Q���Q�W�Z�����I�&0`����i�&<��c�j�F����G��M1|�p���c��(++����������b�9s�V�:22���3��{��E��=jyw��}�0}�t���o�^J������	0e��Z������?����:�����k��)o�H�j�JL�2E<��cb������SB!JKK��9s���#��%KDXX��4i�8w��������SO=%�-[&�w�.f��!._�,���C�Z>~�x1z�h�|�r,���#233�7w�5&���������kh����g�V����N�:����Z~��q��~���$%%��}��;<����B��;����=z��'�/��R����WUU��g����{�)S���?�X�����~������R$&&��}��W_}U���{"00P���/F�:�N������0������c��.]�����N1(..���4���@\�p��<//O�o��<''G����q�)D������sG���L���Nrc���������_�|Y���I��N��z����b����?EEEB!,�y������>�7�#��b�V7��:�������M�<��h�����$��3g
___��eK���o���B��~��qqq�����������[UVV*�-���";;[�q��3w�\���_��FP^^��U
�Sk IDAT�j�����w�s����A`�Z�n-���j5j�4�4iR����yM������c���nnn�^��I��c�	OOO�}�����?����b��M�s�Ni@-�������^����.�j��o��v�cj�=�P����5M�N�:�z�ol^�x��k��76�i�k�N�GyD��� ���={��6	�l�"
$-���5k���#GJy�<::Z<����B^��A@d�j�z���p�B��+�H�������3��o�)m�?^���{F5	�L�<Y<X�^����G��8p������M�[sC
��������k��&JKKENN��{����������������;w%%%��dc"��;�����u��6��^w����@���K�5��3g�j.]�$����M��G��|P�$0��A@d9���
UUU���HOOG�N����#Gp�����!;;YYYh����yBB���/4i�W�\Ann.��8��������CAAA�����8q���O�<�;v���BTWW&M�Tk?��1c���?��f�0�WUU����V^ZZ����Z_[�7D
�N��[��������+8��c��k�Zl��������+<���G�b����r�
�v����D�9��<77�w�FVV��i���J�����`�F���Q�L�_z�%���K&�����43&'"�d�����(�r5��/W�ccc�z�[�6���������8��T�����j^]]
���`���B`��nNmx��g;v����3�r�J���t��u������ABH3OOO���i��5�^�*��v�����)95,�A`�4
�-[�Gy+V���={��S`��m		��9 �k���c�{���=v��www��J����k�s������'Z�j���r����s��prr���:v�����Z�C={{{8::"$$���h��%�����ys��K�.�������t����P�h�-Z�!������P������EEE@��]k�5�[�?��MTTT`��U�={6��]��[����CF�%%%���o�t�R|���������~��=��<??_|����;���������w�^,X���<++111��e��_�I�&��c�������Qk/�c��!//NNN1b���'�|:����DDV�B�\ AAA"!!Ah�Z�x�b���O�E���������9p{n�������'�������W�=z����Zoo,**�G�c���}�Y����P>\�;V|��W���G|�����'��",,L����b������E|�����%����_������^���@���������G�m�f������9pkn����s�����b��]B!���+�����1 �N�z�c�G��w�^�����={�����S�>bp�m��E������.��a��|mLL�HHH��k��P��5�G�,���j6R����_h�Z��7o������90c����fTnh��	&������=z�prr��9p{~���:
www��},**��
���B��#�;;�Z/���

�C=$lllj��76�~��h��M�������[�A\\�HKK����=���{�>}Z5�����9���`T~ks@���Dd)l��no�g��h!�?�������W^yE899	b��uu�n���b�����!�  ����X�'N�������������U+?r��9'''��[�7�8v����p�������V~���<y^^^8{���5p��q�����?..g�������|��=HII���q���;�w������#  ��W�����[�l��K���M�����{��NNN����mCzz:���������������������Z-v�����������������B����F�NNNu�T
��$"��c��uX�l�l�����d�DGG���#F�������_?���Zx�w�?���}�b��������9s��/��R���K�.�U�V�\*�]�����:t���w�QQ��!Ez7�t��[�OML��#�k7�k���h����Fc�X�G%X�E�)�"��. 0����~��<`*pn���be1������=g�6|}}ahh�����o��3n��)���9
KKK�^R���;w���+��Am��~X�z5rrr���X�t)����{�������c���X�v-���P^^����3MY�����?>�o����Ddeea������������={6�9���$$''c��Y�15�9��W�b��U8v����%f�������9 ��>}������y��]�����7��daaaa��E���[7��}���������X������UUU���";;��eB8l�0XYY!%%��������{�����o��Oa`�������;vl�U�m�h�[�9���%s��7n2�+\s(+s��oK�@S�����R2Zf�[s�M��|k2���f����C��������7����9��#UUUW
gi��;�.sv����s",u:��!WJ���~���'q�!Qvv������k�0))���������3g�5x�����DD��?�����7b���.q�!��%�F������P���)!!A��SRR$�8�����h�������ci��y<�������z�+��555WJ���K��6:!�����9 D������9 ��:::3�y��|MMM������cIGG��L�  ��&�����LOOORQQ��9��'������3�"���9��o_������5k��V�pvv��9 �����3�ya���^b��4/l������������hrww��$������2g,,�a������q�FZ�`��&�$/o�`�����#�I0k�,�w��=�}�s�N�M�#F��C�$6	�zq
��}���3g$6����g��\.�A���|��������;w$6�^QQQ����|/�9 �IP^^NZZZ��|VV���Cb@������Kl��l�����P���X����������r�������q>DLL455QTT���B��������p��=���#''%%%077����� 66��w����Q^^������?~�X�����(������O�<������������PWWMMM�_�~���2���#�����3gBEE��x���\>::��H�6s���Gpqq���rf������x��)\\\ooo�}MM
�\��/^�����������WTT��?�DNN\\\����	&��KJJp��U���R$�A������� �q������2gaa��t��6lh�����;��#G�Ht'N��������������;`���"����BUU���/^���GEE��'%%�S/


���t?�[VV&�g�����R=I��������Q����@~~~����3~�����~a3:!


��m���`\�~@�L���/���Ib��$/����������I^�)	---������'�v�*r�M3�]��@ 1����(++��9 ���ySj��<^Z�@tt��o���/�f
=z���3����������%f��M3BCC�g����|aa!����S�Na��yhhh��"gaaaa���
�caaa��@���Y:�<y�������1p�@\�v
�z���5k`cc���l��O�>��A�!����a���077Guu5��]���|<�N���!C���c�b������;�\.�.]
.���>��������L?q�DL�4	�~j��������������������*��3���2d�m���WVV��/����>�
___�]��|�
455e���
�?VVV6l�/_����c���PQQ�����1r�H���`��Ls@�h�����p�B�)((������q#����~��a��U8x� ���ADx��5&N�(���������o<==!���s��1���R��~###:t�w���	������#,]�nnn2�������s�N|��'�y�&���p��]o?e�v������%����:(**BAA���PSSc|cc#�������\_����PUU�JJJ2�������� �OOO���V�\��~7������V���hl������q��f�}������			���_�N��#F`���1b�9�'��9faay�t�x�lmm���������I[[[b���e�HSSS./.s`������.1����)���I���3Z��O�R����������������?��TTT����
<x0)))I�����������t�"1s@�/++#KKK����^SSS$� **�rss���\b��<���Tb����Oe�=zH����������"##�r&���?&MMM���b����/��c������9������q�m���tuu���V�n��_�N���#rvvn�_�|9iii���;���W�WWWo6�����9���:�f�KZ��^�e�������� `a�8��N�������%%%����������!>|UUU���t{!qqqHNN���&^�z%����7�111x��	tuu����j/DEE)))�r��.���BZZ

�����###��wGbb"���Z�#""���K������{"s��|XX���`ii�t��yUUU��}��e����G��(����F�|aa!

�������?���KJJ�������f�����]������d*P�Os0b�����	���������>����y;;;���:::2���Z3oee���b��|hhh��������


PUU����T/)W���������[��p���ww���;,,,,,��1�����G��@ ���?LLL�l�2���!99�/��!Cp�����O���7.\�������?���+�����7o������1o�<:t�^�������~�z888 22~~~�<y2f���m�����D��={6����l����s�������i�&XZZ����������s����~���?s���_���W��/���%K����_~�FFF2�����f����/����W_}AKKK�f<x�}�3���o�AII��?y�$<==�����������������O���


���#����ACC���������QPP����]�v���/���
�x<���������2���������333������";;0n�8��q��
������r���L�=����}�6z���?����Caa!F�	�@����K�������G��}��pp��}TVVb���������ez'''�������w�1d�p8<y����}xx8����\��A�����9�u$5�:�����w}�d!��o�7b����m?��yy�c>����u�������tl��bnn�1c� ??&&&X�z5���Q[[��[�"99...���B����r�JXYY��7l��W�^������>|8�-[SSS���`���R��U�PRR777�<y�'O��E������>>>2}VVP\\�m� <<������Q__www8ps���7�|]]]p�\�0���X�z5���


TUUa���PQQ��~(�4?��#~����1���Lf��� ��]����,�`��A�2<<<����4444PWW�^�z�[�n���?}�jjj���`�����Zddd@MM
���x��5lmma`` ��r�x��%��������������"!�WTT ;;jjj��x��x(--��7��'���```%%%dffb���������W��>

!PXX���G�������R��g����Ct��
���������#ajj*�OJJB�n�PYY���F>������HMM��'O$�`���RS�YXX�?�Aii)�����W/�oT��y���2����},��~�������n��������U^���W�����??##���022j����l@����<~����������5>|hii��}RR�Looouuu�>!!NNNm����G�~��mF��GGG���w�� �9�����A��6	�|>���1`���}Y���)))���_�|uu5�={��}����K�^X�������������<y��UVV��U��������C���p�B����%K�PVVV�|yy9��_�"mmm������_���=�tuu��BBB������8M�4�444h��
"�B���F"����4f��^EE����E2JJJh��Ar��RK��yC��������O�8�Y���m����meff���iii��c�Z��|>=~��z��E|��>}�U�����������,--�����


t��
���'YZZR��=�a�6l����+�n___O/^$KKK�����q�U����N�8A���4d�����[���7211��c����������~��a��$K'DX�DDD���.��#�������E���m����������������~KEEE������[��������D��_�hm����������':~�8UTT����O��{�J�����c�������e:�.\�@���bo/��~�:544��}������|��������'��#**�������=�������"��dffF���m�999���@���m��?�?�P$'K�g3XX:��nP��"������jdff���JJJ������CBB>��p8���������r���<x�&&&x��5^�~
SSS(**�����QQQx�����������"�K�.r��������������x��	������������AAA�����7=z���2hhh0)�HKK�����ooo����F���!##C.��mx{{3�444����x��%(��������D���BMM
�������WWW������Sn_^^�K�.���...��������i��P\\�+W�����O�>HHH��q����z�*�\.����3D�4662���III=z4�v�
"Bvv6n����� 99��
����\����y�&����HMM�������@ ��������%%%����_�~PVVf�H�-�-XXX:�~�)>��S����^^^m�,�����k��i������T���������R��'����/����}������v����vyIg>)++��������m�fffx��i�}����f����~aC
;!


��e��C��������GTT�)p��9������+������L�?��={���;���z\�~]�f
\�x��u���?RRRP__�+W����L�"r
��?�`2������
???<�


�|xx8�f��������O�f2dy��������


8v��9 ������PSS����f��<������+����b�
�����������e:�S�N!==]n��p�o�>8p!!!8p�=z�u��������g���������c����a��Mr���\���[8z�(���>����

�a�������ms�]�v!99���w�}����c��������/d�;v //����?>���q��a���!--M._]]��'Ob��i8w�BCCQWW���dl��M�/**z��XXXXXXXXXX�)u��dlll(..�jkki��m4a����h����x�bz���=�y������A7n�����0�GVWW���M�<�6o�L�����7l������ri������I[�l!ggg�|ll���CWWW�����������*�1cM�:��m�&�+++i��)4m�4
$SSS
fNO��+**��O>!ooo
&:t�s��,_^^NC���������+����wwwo6b`ddD���4l�0�9s&���Cda~~�\~�����O?5[E((##�F�!��������S�^���?�$���I�1�� IDATII4j�(����+�������/""�{��������y<��s�F�M�-��+W�G}D�o�&"���F�z�*�;��-[F�-����������@��}��'����������< ������O?��|||����&L� ������C��tB�����}����#,,�?�7�(���GDo�d�]��ttt$f,^��������2f��A3	�zq��LI�-���OE���3��C���b}ii)
8�TTT$fH�%%%���DJJJ3��7o����9u��Eb&���9ijj�4������WdffF���b3��&&&3���ezccc����9#�o�)Kvvv��6l �f�ohh���H222"������>�����dzq�!!!dhh(1s@������� ���o�\������b�����y���6���c��;b�����x�����������"���0�n3�<y�����/�HOO���rrrd���"�GEE���055��/��$fq���*RSSQRR�xa�@VV,,,D�0S //={�DRR���Z����PXX{{{��������O��0s���NNN�}�6jjj�zMMM�cnll���Q^^�����������ry.�333���6��///����e���:!!!�������ry]]]$%%�����-�g.������������.����������lDEE�����.����2^�)p��())AQQQ.�������t���BUU|>���R=�A������������ ����|444����������	������J��r��\^R�@dd$���ezI���]C��������"���_?���K��q���o�)p��-�x<���|�L����[j��8�4s���;R3	���'r������-[p��aDDDH�����w�:uJb��,��q���_b��<~����2����7�B*++�e3BCC�u�V���O��?� �K�8{�,�-[&��9p��y��5Kb&��������	,,,��
lq�kl�'yY��_�c���{Y����w���YXX�#��$��bffFs����?��������f
L�4Ij��4���CS�L��~�Ib��4�p�B���/�f�����#CCC�x�k��_~������^Z�����L/-s`���ryI�����D2	Z�9444$UUU���f���9 �7��7o���q�i��7�|#5s@�o�)�x�b���&SSS��o�������2�����:s��f
|��wR3���d��������,,�a�SRRB�����Qzz:	�6���|z��E�}vv6eee���{����/)77W������?}����y#���SRR�������<|��*++%�^_]]-��������wOdLQ^EC�a����s�x<����x<�+e���:���o��r�����Vyv�����`����#///z��I3WYYI�V�"���|EE-\�����$fH�����������%f���G�&]]]�2a���m���I�HCCCb&�0�@R���1cdz���
��K�pvv&EE�f�e�@GG�6m������233��������fH�|>�?~L�z���9 ��x<��>���������i����n��A={�$KKK���a��1�ef��7�/^$KKK������i����N�8A���3d��~��LLLh���b3��a����K'D� �����?������^��������4�[����G�����'��o���i����m�[��������D��_�hm���i���O�>����Km�����c��1M}i^\�`���t�����{{y�����Z��O���7�R���8��������^�s���K)))bo_QQAfff����&���C�V���?�?���?.�g,,�R����"�@MMMTWW#33���PRRb2����� ''���PTT��������011�������k���BQQ����������#XYY!33EEE022B�.]����?�����q3�<y{{{������zzzPPPh�{���G����PPP`2���dz777�������?s ##C.��mx{{C]]��g�|��MQPP@bb"jkk����m������WWW������Sn_^^�K�.���...���������*���e
�;���			7n�����W�^�����9����scc#����������G�k��L���7���$''c��aPQQ���x�7o�ASS���8p TTT��Y�������2�������~��AYY����������~�O?�T�������W���������5k��e���/�������'N�h��|�r�������ONNn����j���������$:mmm������������m��{�F|||�=���mtB������:t0f���s��X�p!��?���2d�\^�)0o�<:t;v����+�����7o���L��3gb��m�������������H���)S�����Y����7~�����a��M������?s�L,Y���022��3g���/��B�����W_}����#((ZZZ8~�8s}����,�o��%%�f��}����xj1���kW���a����k�|>�)p��!|��G��������2�!!!prr��_�u�����_����`2~��w���`�����i|}}e���b&S��������O?����

������r�J3���Gcc#�/Fnn�L/�

Eqq1<�={6^�|)�������'����>}0m�4���1��|QQ����~�w�����w��!����v������x��%�\nG�
��:������P\\�����m�h��	��?H������I�����<y2m��Yb&AS/.S���Sj�@K+�����Ub����S�f3�M�&5s@�f
x{{K�����_}��H�@K���.��0>>��
F3g���9 ���;Wj��,���_K������{�������^��af��E�h�����h�%e|���R3	���d��������,,������x����/�x��c��� �����R\\�}��v�Z�����9�x�b��������1cihhH�$h��e
3$e��O�>ihkkK�3f��������4p�@RQQ��9 �������)))I�����yC�����K��������)� HKK�W�^���ijj�������H�HNN��������Bl�@LL�\�e�@ll,���1���w��G��s'��}�v���oHSS����h���"~��Y���I���2��%K��m����i�HCC����Z��n�J�&M"uuu����+VH����&�`aaay��7�y�|x �n�O�+���h��a�u��c��;b�����x�����������"��O�<����\^\�@zz:������#���x��LMM�������������"55Ul�@VV,,,D�0S //={�DRR���i>,,��������9 �3JJJ���$1�������"�����?���������9p��E�������Fl�����e���:��������������d
P����O��������o����\.���'��y��={$����v�g�����gR=��T��'J���CV�������F�u���KG�Qx<�\.n�����X[[#""C���}�p��5TTT 22���pwwGdd�\>00�o�Fee%.]����c���������"����#>>���8w�6o�///��q���ryqo����CCC���"%%UUU8q�6o��E�����"���#���������ht��>>>x���L��r��o�a�����s'n�����z,]����r���w���G�ELL���1�|����xwww�c>q����p��qDFF"77K�.Eii)8��������8s��?�������v�����e���O���Cx��1����p���@����r���@������yyyhhh`���O>��3@Dhlld�-����|>x<�{�#G�D��������������o��^�(/O��.�
�oO]��o���+*++%���s�����a�������YXX�/
$��-K�`nn�#F����������`cc���:!!!vvv�������.]
����?�����W/��u�F������G���b��-R���/rrr������/������C�n�PSS???�>55���L���#G�'N`��U�p8���7��9�y��a������Auu5�]\\���W�������:�\./^���z���G�wuu��={����i��AYYUUU�={6TTT���"�o��������'���_~�%����������C
g��044�����G1a�@aa!���CCC��������{�\�����+,_���u�����=��;wb��q2�@ @jj*��_###����������[1z�h����#!!���066Fyy9�����"����8z�(8222���%%�����������}������������PTTl���������C���Q��d�L�<Y�6,,,,���76�����4������
]��~>��������?|�FFF�����ME�|\\�����[7�~�����q#F��m���u�.�n�UW���G�ms]!�6lhs]�g����S�����ACC����9s&n��
���p8��-!"���CWW�M^ ���:::m�|>\.���r���d���S�N�>�;��6���o�������h��i";m�����o�%CCC�={���YY�������I__�-ZD�����%%%���E:::�r�J���o�9r$���2�����������0aiii�?� ��Y�544�������f����F�%����Q``���_AA���_.�o�>jI~~>9::���J3?q��f:::"�����^�z���������x<z��!������1�8q�U����n��M666dmm�,Q___O���deeEVVV�B
w��E3f� ���&L��r��u���e������y�D^{����Z�b���9������aaaay_H�O��i������Y�jSyyy���_M���+��6m�>}����ezq���R�Yu���V��
�oO](r����dffF}��e.���&333>|8
4����IAA�lmmi��������O������H��������#555RQQ!�V�a��Q��}IMM�TUU���Qn���N����Z`aay����@�n�����������*����G�������x��%,--��kW���[����
;;;�y�������TTTPWW'�_�~��=C���������t��
������������� ���"""/_����+222���]]](**6����GJJ



����.]����aaa�����?��#���������PPP@uu5��;���_�����OOOx;��)�y�#G��M�����p�������g��������w1q�D�<�_&���Q]]
WWW�����O?����L/������/����������������+���|dgg#22��G����}}0�.]���3f���f?e�L�2��~����<�����3���+�o���]~������N�j�������AV]������B�����\W������D��(//���s����������/�������c���000@PPs{��}��!''�������n����<���{��Eaa!\\\`mm�M�61u�,����_����ptt������"77W�wttD����>�,,,��mO������N�<I���4y�d:�<�������i����r�JJKK����2e
EDD��L?���x��|}}����n��Et��y��������)++�V�\I_|����***����r��k����s�!!!������#G����v��Iyyy�`��:u*=z��*++����"�1c}������3�������S��=i���2}ii)M�2����(''����(88�LMM���cry�
���b�������3���H,..�����l12d��;�JJJ����YEF4n�8�}AA������=]�r�^�xA�}�-Y�D�/--���,���!WWW�v�����������G.���A��-������7���Cdnn�o�3���g���t��Pjj���AV]������B��SWL�2El]�z��f[��]K+V��Xwtt]!���+���(&&�^],,,lA'������pqq��$&&�����������d��>�H$s�����������f4�������������������0q�Dx�A�'v6������"�������:����p�OIIIj&�$/�
������{�����g��l�2&��{���r�
���������|�n�`aa!6s`��e044�����`hh(6s`��u���dz---$&&�������{�0s�L<�@��*lKg@R�?�#F�d���AYYYj����
.��Y�f���������SE�
eee�����[�qqqx���������]u���>����\W��+W�\W\�v
g���G}��_`,,���
�N���N�8��������7o���1i�$�]�����u����n�:���b��)2��
`ii����2,]��.]��3���#��������KKK1w�\��q.�w�}'�WTT`��Q�+V���e��b�
f�c��i��>V�\)���y��?����������K���%�/,,��Q����K`�����0���_���PXX���wc����K����@ppp�Att4�t��Q�F���
�v�jv�:����2��# �c�L�>��|>�=���.��?�����mSdo�����i����zzz`����8��1��X�6XXX:����|B�������mc ;;��{�Od����s�H�@WWWf���XW\�tI�A��/�`���b��������5jx<^��
���gO�����:\�r�m��tlA'������HMM���	8����g�����B./.s 33���x���L/)S������ryMMM�c���@zz������"8::�x��_ii)\\\���,v6P���UUU���M�l�$/�
���C���%f���A[[[��kjj	��>}���8w��L����2s@8�/�+**���Rl�@DD�\���<�������>�/u��b��qptt������o��Auu5�v�
mmm���3�����(..�����@OO��555(..FMM�\^OO�I�'"����AEEE����+TTT����,--�
6��������]]]��e�
������iW]Q]]-����������u��kW]!���+�mbaayO���9�����7o��k�h��q�p�Bz��q�2Z��f��m�h�/\�@��wg�7$$���������
}[g�zi�-�����W�y6��o�l���e6����>}������G���t��9���`��i�@ ���F����z>�O<��{6����s���Fk��!�C�?�����>��s�w�������i��]��p���4s�L�|||<�>}�<<<h���TVVF����/����N�*�?|�0M�4��?NeeeM4k�,z���LLC����{w��������Vg�;�
�oO],��8v���IuG{�����v�B�������� `a� ��N���9F����XZZ�������
�)���;;;��������������^�z���[b3�y___������Qb��,������Dx;b�'N���X�l�<�������x���bg��������,�����)�������8z�������!���%�������/G�n�`ff&v6P����_�FFF���;(���|$!�E: IDAT$$������(//������������AFF�����$zSQQrss��o�6���|���Y�'�|VV�\.Z�������[[[��|�z�
[�l���;q��U>|fff���������\���/^����aaa���B��_��������r�
������K���������r�U�V���HOO�����PPP��u�.�n�UW���G�ms]!�6lhs]�g����S�����ACC�������@ ���/��:�� "<y���u���#<����t��`���������i�(%%��+++�o���

i�������*��ph������O�-����V������"Z�r��.yy���#IWW��,$$�<<<�H�}���#����G,�����Z���O��������O�8��:::")���222�W�^���C!!!��<�>|HvvvdllL'N�h�oll���o���
Y[[��s�Z����)22��������z�����g�����	(++K��#"�~�:yyyQnnn�����i��y"�=y}HH�X��
[��3XX:'ZZZ�w�^��� www�z�j3_SSCG�!333:t(��u�U�����={������Kw��m����������;M�8�Z�/_�Lmzl�) MMM�u���BKK�]u�����9���|233��}�2��]��V�^�xqu�v]�����A���At���(���uCCC222PWWL���G�`ii���J�|����r�[�n!55vvvx��
233���L��4��u<{��{�FNNrrr���L��,����������������H�W,��
1����K�w��AII	s���o�����#E|S�t����Dp8����2�={���<x0���+������x�"���������X��������/_FCC���r�<��Gvv6"##=z�`���0�.]����X?f��<y���m�S�L�����e����=;w�l�s�5����sAD������2������.��m(ZZZ������===���������;w�@WWjjjx��	�����


x��!bcc���K�.HOOGMM��>--��;��L�>}��
��
WW�v�B���">>^l]Q^^.��9YuGG�D��������`G:!@II	���������G���;�������K�.!!!s��a����[�l��Q�0k�,=ziiiX�h����7n 00P�������'����{�n����������#"""�}�v�~���8r�
�1�x�"&O�����c��y���/��O?���`���������xooo�������6m���1N�:��[�b��������===���_CEE������p��l���������d����C__AAAPUU���������������gc��)������������o�>8p���0`����=z���w�^�={;v�@�^��|�rXYYa���R��?����*��������ccc�_�X�v�L_ZZ�={� 11�7oFff&6m����l���CCCnnn��������Q�Fa�����Dpp08��[���>|#G���g�����4���j�*�z�
�O���q�0u�T�>99�v����.�-[���$\�r�'O����e���x������iii�nm����:�Q�|��W����v� 55�w��X7��+����_���u��766���������kW��b��9���m��������b������+�>00��u��A�����tl��bkk���P������������
�f������qqq2�G}$�9���S���QQQb3	������d
dgg���Ib�@K�?��?�8qb�5�AAA��x�u_�<���y�l`�}�-guuu���3,[��Y����+����k�4��[7��K�FFF2���ZZZHLL���?��{��a���x��9�A����q���#44�&M������333p�\�����---�O�[f�:u
2}NN������/����^������������,$''�{�n���v�#��x��!��=�O>����9TVV�Z7������b��Ym�+���0u�T��BYYYd�a\\?~,��000hW]���kk�6�B���6���]���g�KG�>�X��������������V�ZE:::4k�,��, ---�������������L��^\����I]]]b�@K���S�-���g���|QQ�����v�*q6P�/(( RQQ�8(�������))))I�$055%---�-iii���3211!mmm����xccc222;���(�w���,--��FGG�����K����%;;;����T������&egg3�����������"6s@���Oc���9(��0a������tuue�/���:�l>����,X���?�Pdd$�=*++#"�u�b]&��@AAAb��������]u��������e3XX:6��������X������Gl���g�`aa!��9���	kkk�~�Z���)`oo���L����t


fq�������^�>�������}��f%y��_�}��f������-r��}�M���
�������l`�}��|�}�-g[�+��������TTTx�I@��I,,,�"b2�|>^�x��w�BWW���b3��PTT�9'���xb3���`dd$�WWW#//��>��Yu���+���ZWTWWK�+�bll,��ho]����UW}{�
q[�XXX�l�������r�]�v���g��������7o�����pss��s���{�����wQYY���&s���pvv�����TVV",,���x�"�����������o_���O�<AUU��9��^�tI��8q����|�2TUU����/^��\.!!!��_DD�f�������fDFF���`���())����"�|��8p���gB�V�^���Rp8f6P�?x� BBB���	???��������
��CBB���4������ 77��
������HJJB`` 8^�~�4�ZBD��x_����@b@���,,,��@�c�����iii�������d�DEE����(++CJJ
�9 ����b��Y���Dhh(�������d���L��.����zXa���S�d��c�����R'
���R���y<��������
���h��ZW�����+*++E�w����������oW]!���+���$>�,,,�6��bnn������
���X�d	���QWW�������{055EJJ
�������L.�s�N<z�����������s��{��r������Btt4�N���3g�����������������bo3���
___����������?>�O�mmm���0���/^��U����_BMM��>cY���'O�����1e�())5�g��W/����#�f����0g�(**���	�b���<<<�CCC�������7n���7X�x1��������@�<!;;�W�F��]all�l�O�HOO������]]]$$$0��<��GRR�n�
MMMTTT !!999�g#%%C�������???/_���������PPPwww(++��?�pqqi�g3XX:'ZZZ>|8���AD(**������o_�x<�
���>�������u����q��e�>}���(--���|||���$�744������������{w�X����2���w�QM�k��ATBB@� � `U�u�,m��V����O=U[�UZ����Z�`Q���Q�8!
���`�I�g$��������#�*�����k��
BR�d������c��U�����[�lAqq1���'�:deeAKK�Wg��� `cc�-���XXX@CC��OHH���LLLX��	�n�:9�w�}�������+lmmq���n�
����v��������zEEE:::���
���@*������w=�+!����v�prrBhh(� ���'��F��D,,,�P($�|�	����cUUUd��%d��A����7���})���3��_��W_�G����� �f�"�����������4�8q"�}aaa����BHYY�2e
���d��U���R��e����
6(��������z��8�*����_]%�k�.�b
���CI���������|>�����}�T*%��������Br����������������������������+��������c���okk#111����X[[kkk�uu����9s����b���B����|�����t�RR^^�-AV�ZE�={�R�sp��;�����]����9y��7Hll�ojj"���d��!����\�t��xCC��c111!�'O&��_)^WWG6m�DD"�6m� R��9s�8::R�����$88������Nk��!���'����������������[��/�$�N�"---���A�����7��
>��V��quzE``���.,,$&&&d��Q�}���d������w�
GGG�A��K�1���J�033���������]�r���6l������C�6�����QPPggg������hmm�|v��������c��Aii)���)�Acc�J�������l,���...(((@AA�4�����p��}<z��:�]__���(TUU��I�&���[(,,��,���!22


*���$�
9������#hmm��)Sx�hhh������(���Z�������;�����d��T*EII	N�8�>}���7���7PVV��H$x��1��9mmm�5
7o��VQ����N�����?����.,,,������������-wss��`bb�-����;v@$u���34hP�8.\zW!HJJ���>,--q��mj�Z,���;HLL���D"233U����HOO�N���|deeQs�l������HOO�������{��Q>6����{��)=�/����-[�xt{���X�`�3G�O?����������������n�q��)�
l����E�^!�����'����b�}��Ux��zGO�
�T�V����K��{��FCC+W���I�p���={O�>E\\8��c����pqq�����g�����{�=����������^����JDGG��g������������7PYY���(����3��wtt ""����?><�!C� 88�o�FUU�?t��B!5;X]]���p<x>>>�<,,�����GMM
����C�a���*q�D�+V���555��gu�/<<\��8���
�D???<y�O�>����q��I���{��Ass�J���Dnvo��=Duu56n���eG�����[�na���X�~=JJJ�m�6����w�^���a������R��r����_�T���*���K�,��{����r���c��}��		��y��������@JJ
BBB�����`����v��=��v�BBB ���~L�6
���8q��J���K8{�,�����e���J{[�8x��Z�B���:::��b��
o����1�u{��'O��2�N�P������&������9r$�9�.���999�����$2���g�nnn
����XXX --��I��{zz*8<xkkk$&&�:^�����6m���<wAKK�v6���vvv8�����UUU����q6���f�ZZZ0l�0��@&.�
�#F(��u�yyy����"������u+455akk�8�����0d��������r���]�V%�������
6`��	HII���s)!eW��5�������������@gg'RRR�k�.��������9p��!Vnhh���Z��o�������u�9s���(--U�?~� ??YYY���?^�AP[[mmm��������X�hQ�{ESS��������� $&&x� ��`r!��+455ann��^!�������/_FTT� ���'����������1���!��������s��:���O���T�t����g�G.\����S�N%$��-S�����HD=&,,������+W������������������3�*����d���DGG�q6P��jkk3:	LLL��������������������>�O;�
�DD$������rcccbeeE;x��E����9u��RSS���=u������A��K����.)**�n�����{����B�P��B���N���m�J�����9���O+�5k	

%���gr��B� ���%������^M&N�H=����hhh0�u{������2�N�����
w&������_���	{{{444�:?~'''�8�s�����Gee%+gr
�=O�<Q��f�����#??�v6���c��U������6�����w��l ���I�R���2�2q��_��}���o3:	���K;�YWW��~�
:::x��7igU���Q�hgO�<���|>ig��;������[����3�s#\�p�
!�P������� %%���
���U���9@�HOOW�khh�:���V.�QXX�*_�^���W����z�zE]]��^�5��C�^����V��quz�!.\���po��tvv����.]����1t�P>|o���s���#*q&����G��o�r&�@DDU�999
�y���077g�
�����/��;v���/�g��?�t6��w�����R�$>|��s������'�g�>|�q6�����{��e�
d�!!!d�
T��[���cJKKQXXH�F��D��b��u�D"a����s���w��_�eee�{�.�8x� -Z��`�aaa�;w.�s@>s�LF�@xx8+�2e
���U������~��+�X,V���_�������^QUU�V��quz����i{Eee%�&�,��Og����={���+d\�^!�[s����
� ��177��	�����C���o����5�������K�P�������sss��y��9�� //VVV�z�*�s�����TVVx� ���ADD����U�G��U�G�����3�������������������8t��J���8Qs_1�>b6.�H����m��AWW���r6�����J��{���
�JTQ?~|�xaa!�����o�^�`����������#_�s.\zgx<�z�-<��J�q�F9�@XX�B!���i�L\�8v�

Q]]M�`�2�@LL���QRRB�`����X�jbcc�������,hii������
�SZZlll�����abbZi"OHH���LLLX��	�}�{[������3g��+d������"22��oW����@jj*���T
???���l� � 77������	���������+i��B,,,�P($�|�	����cUUUd��%d��A����7�s@�����/�������h��xEE�5k���'�����6>q�D"��������'!D�}���#f���#V��f���O�>]�A����������7�+&����6C,--���5����XWAzz:�3g)..Vx�!$!!���?����v������K�����n����j�*������������Gv��E����o�Abcc�xSS	

%C�!�����e��������������'�:����:�i�&"���i�h����3g���#u��AH���IMM
���f���~R__�-���M�=J�����Kr��)������zzzJ{[����j�
W�W*<o��`��Q�}���d������w�
GGG�A��K�1���J�033�T*Evv6��S 77��
Css3�s@���GAA���QSSC�P�cccQT�?�� IDATT�1c������9��+++i����bU�3qU�+�L�t��_���n����>b6���b�}�l���������?���������:"""`ffF����p�����t�{xx`���D��s��A@@
�-����B������KKK��}[�)���###�D"Z��9d'��|>�s����������B�~�h�L������S������e���:q`���X�`������������BWW�[<44}���:?U��q����^����V��quzE��w���
�X��}�*<ge���{�T*U�Wp������A������+Wb��I8s���=��O��98F��2��{�!44�����e|��Y8x� ��������3��wtt���bU�3qU�+���]�+��jkkC"����XWu1We1��������<���^^^���.�"R�UUU��o�,Y�{���:BBB0o�<F����E�@HHf������]������i��t���K8{�,�����e���J{[�8x��Z�B���:::��b��
o����1�u{��'O��2�N�P������&������9r$�9�.���999�����$2���g�nnn
����XXX --��I��{zz*8<xkkk$&&�:^�����6m���<wAKK���+Ve�2.�
���8;yyy����"������u����U�G��U�G��y<����a�L�0)))�;w.����;���\���0�����:;;����]�vA__������C��rCCC����:~��7�xEE�s���3066Fii�R���c0�������� �;e���
���Zhkk+�
u�hnn��E���+�����_���!11�s����I�^���	ss�n�
ONN�v��|�2���8.=�W?���-vvv��aMM
���&|>���;��90�|�����s��=��x<�p�BVN��:u*8p Y�l�J<''��D"�1aaaDOO�o��������9���Inn�����qU�3qU��q'''r��)����{{{�vW��5�����]]]RTTD�nii!{��%�����9�

������9�m�6�����s����V>k�,J���)�� �;��AP[[Ka�
���"::�L�8�z���/���`��������+d\�^!8.=�LZ/NKK�_��?�����hhh�u<~�NNN*q:�@ii)����JV��=z4�<y��[���_��bU�+���?�}�]9��g]]�����qU�3qU��q+++��u��=�87b����B����@NNRRR`jj
�PH�P����c�������t�����s���{���a�b���������a�
u����W�W���)�]caa��;��:::j�
W�W�m�����	�A/Lgg'jjjp��%���C�������[o1:�9�gr=zo��+grDDD���Q%��������R��U�G��U�G��w�������I0|�p����>be\�}�L\�}�l|��u(((��;PZZ���B�7���%B,3~���%	��~�.�+�����(++���w)�����h�"F����s����3g2:���Y��)S������vGG���_��b��7��j^]]��7�����*�z����+���O�+*++�7d�>}:c�P�W���G�^!���
�@����.m8A/���9&L����F:�|�
���)����|��]Z��2���,���������e<  yyy������Wi�l\v�����sALL"""T�W��>b&�����>be<<<�q���}����������������C�T�G���������q�D���Ll��
��������1wuTVV����puuU�U��������Q^^�7�x��
���G}}=F��R�sp��;�����[oa����U��7�9��� 
���L�`�2���c�`hh���jZ��9bbb`ll���Z�ooo��U��`vdeeAKK���Tx���� `cc�-���XXX�J�xBB���`bb��'L��� ����������z���-��9��^!�����������}�B����@GGRSS<wH�R���1��g{!�����NNN

�\��D^�HbaaA�B!�5k����cO�>%_�54h���"���/�������144$, /�KJJ�?��O"
���K��'O^�����@@�F<==	!�g��{�=���O~���]�2������k�1V���G�l�B������G�����J<88�����|bkkKtuu������|>�����}�D"!YYY������{����� �����������C��ooo'������������G��oii!�N�"�������X[[S��� ++��g!KRR���&��������'�V�"O�>�?q���i��\*�\����x<L�����1cHLL�ohh ���#��������������#�������L�<�\�z��xuu5Y�n�Dd��i���/�O�>M��L���w���RWWG�:m���>|Xa�^U���G���HSSS���e�Hll,iiia�t>���7��
}}}�z����+�l��������H$"�F������%+V��8]� ���W8::r.\z(��A/�T*���=455������Z�g�������C�;�����&����f���������e�P__��w����	����s�����'�0a-�����g�������
��---�����i�TWW#**
uuupww�������M9
��)S� ''999�q���JDFFR����i�����������,>{���D"Q�'''SWl����B��}1c��5�������,�������_E������"%%Ee.��;~�8������o���x���J���yyy�����������Tj�����b��� .."�����GAG��������rA$u����{���Q���3�z�jv�s���w����$���a����u��E�������~�:���ann���t�yKKn�����4�������o��|,l���	��_GVV^{�5���"33UUU*���Fdff��|Y�x1.\>�O���xyy���u�o��3g���������1e��u~�r777����W�����+d\�^q��m�^�����}�*<ge���{�D"Q�Wp������n��u=�Ep���?��u�����.\@GG�B!.\���G����~��H$\�p���J���9x<gggL�8����������]]]�={����2e
�/_���\�p����xDDf��
oooTTT >>��������'p��1V>m�4ddd�����c�w��Ecc#~��w,X�K�.����H---DDDP����������aii	


����������v]3��K����������=!		��S��a�,^���_�r���1b:;;���?#::�������p��e����a��apvv���������6lZZZ�s�N\�r?��>��s\�t	W�^e��������{�n���#003f�����q��
888(����x��)������<l�����>.]���������'O� $$���)._�ooo���7Q^^��>�����W����;v,{�K���K����[�n����q��E���������8x� �����������.]R�2�����kaff��/���"��������_~���%V�^
\�pMMM4hn����'&&������X�x1 ))	����:uj��]<777�����_������2��^�t�Rdggw�W���s���+n���s��)���?�����
���/���	�����c���j��a����+d|��]�����+<==ann���j\���A�cgg���8;;���c�����Gaa!���`��y055E{{;������<|���?~��s���c���(**BNN�L�///�����!''3f�����/�B���"88���011AFFf�������
Lxx8�o������?�������033��7�xKK��Y������
			������'���������|�rTTT��������
0u�T�����755a��%���������l&�+/((���O9D"����s�N466���
W�\A`` �}�]��L,_������`���HOO�f�!x��	�����������C("//6l��	 �J��������bV���PQQ�;)))�;w.u%������A��K�����)S�@"�������g��������}������Ggg'��������&�B,[����@||<"##�����kkkaii������b�g����S�������*����|>�������� �;e���
���Z���Oio��{EKK|||��+�����7�(����v!11�sABB���i{GCC�Z����C��v������n����D�8q�sp�����.,�����WVV�o�����|�����:���G���������{q�3!������:	>��c�������i�|����%�~��J<''��D"�1aaa����+V�����������B2j�(2`���@e���G��������q6P�����0:	D"����s���\���I������>�l�*����<�v6�����|��A����v6��?�P�;99���(����{{{�vW��5�����]]]RTTD�njj";w�$B������:T���������9�y�f����Si��V�"�����9�����8;;S��A�w
���������{Ett4�8q"�___�����;�����j�
W�W�A��K�s��466���+x��!F����VZ�@II	������D�N��P3x�j�*�Z�
uuuhmm��N���*�������et
������L%N��N__�=��
��x����l��O�>�4i���ig��l�OGG���>�l ���	L�:��I h��+++q��Q��w���
T��D"�����FEE�rSSS�=�v60&&F%������4jkAGG�J3�\�p��WG*�R�����q�����b����U���p'''Z�@ff�J\GG��9����#F�r(((xu/f/[o��{Eee�Z����gJ{E����2�u{����Z�B���t[��p��j�9za����������#1b�����OF���U�@�����9r$����?�����������P��ttt0z�hxzzb�����Fll,�s`��x��)���+��x�x���������g�
�����G�(���-7���w�)�
|�kjj"$$�����e-Z��O����~��
\�l������;���~���s�E'Aaa!���(����������d���O����t6P��cf���t6P

����l��m�X���;.^����XYY���;�|�2�-[@�A �H���N�Bx^2�b1��I���I�����[���s.\zg6o�---���#??���6n��a��1:�����aii��X�~=+766ft�Y�FFFJ9�������,Z���@,C*�2�l���L'V�����O�>��������P��9���p��I����+�����2���zEHHN�<��+�B!���/� ����T*��;w�T�W���O�3gN�{���?���">>�sp��C��0���3f���1b�,\��S 11B������_-w��������n�:,Z��/����Y�.�D��w���H$����i�l�����u�uE$<<111����������SSS������������q6������HHH���+��GQ����%%%x��1>������IKK��s�M;;(�	={�,��_SSlmm���������������Chh���_kk+���g�8����5k����FFF���L\6��y�ftvv�����2q�D�{��!((���+YYY(** � �����[����Nk�.**Bnn.��������<??O�<��������<;;5557n�&�9�p����x�4i��������rN�_~�ZZZhoo�u0q�S���c���ACC�s������������g�h�����k���\����Thkkc����o�^�v
B��o���K�.�������oB����88::��������(8���kddd0��^ajj���D�^�����{���+��m�B�����D"Ajj*���T
���l� � //������	�����������i��"
��Y�HFF�{��)������A�����s@'����_B��{�^��xzz�c�����B�_���O�?��O"
���Ki�l��������0���IQ}_�*��������(Kaa!9t���}�L�t���O�.� ������W�c���BHKK9u�177'666����b]YYYd������D��#����$���M�������?OV�ZE�>}�-~��	�i�&RYY�R�sp��;���Hpp0133#c��!111r�����������WWWZ��2^WWG���	�<y2�s@���&���#"��L�6��9���>}�8::R���w�&!!!�����u��u+9|�0ihh����#QQQ����[|��e$66�����r:��W��z���>k�P�+�
LN�������F������%+V��8]� ���W8::r.\z(���F*����������Bmm-��u
<|�c���X,�u������r�.�F����i�& <<VVV������1lll������l��yyyx�����PQQA�`�����G_f_�*��'N���Z��y�;%%�z�����|�	����3����#~1������Py1Ww_1�>b6.�������8�D"���3:F��������rA$u����{���Q���3�z�jZo�*�.�+�$%%���C���[����_���5���i�L\�HKK���=

i�L\�����k��]]]Z�ollDff�J����c���������~���x<^����1s�L8�[<88S�L�=Y�
wssS��z���;k�P��9d���I����
MMM�S�zGO�
�D�V����K��s������X�n,,,p��ttt@(�9~��H$F'AWnddkkk���R�k����Q�0m�4�s4�}�����PB���!�1s�L�����h�1������`t(���MCFF�������hllTy_�������e������z~g�����7���`cc��q�w�y7nDXX~��G���a���������6���PUUE�����+������G����86�r���7n�Pi�2��k��������u1��	BBBPQQ������������� � ���sp��;333l���G����i��������s�E>d�9����kaff��������S`���000`t����D=zb��/�� �;��A���R����+�.]���l�^�d���C���;G�X�x�R'���;wN�W|���(--�s455!33��w�9R�^1l�0�z����������_�\��P8A/���"""����c��!..|>����������������S�L���b��!�����N����c��IrN���L��� ##��9�"7n<<<�+0�����};x<����bY***����k��a����?>���0a�������ZZZ�����3g���c��m������8;(�
|q_����uuu(((���O9D"����s�N��+�---*�#f��������8��CEE���1v�X���`���������k8.�3P)� IDATDTT�L��D��7ob��=������/:���Xy�~����D�������+����u�:u
����l:///��Gvv6���0;�N?~���������S����pTTT�����9����7
����AAAHLL��A������z������V�hll��!C��+d<;;���"11'N��\��D^�L������7oB���$�~�-������?�u��7����1��R�I�~����99r��6]���i�|����%�~��J<''��D"�1aaa����%��	!$66�\�rE��������sG��b�����{�������O?}�}�t\OOO�A`llLrssU�G������������;99���(����{{{�vW��5�����]]]RTTD�njj";w�$B������:T���������9�y�f����Si��V�"�����9�����8;;S��A�w
����������l���G�����7�q�^M&N�H=����hjj2�u{����Z�B�����sp��C��8����r�
>|���G�����9PRR��c�*���TWW�����;}||����K�.�������KJJ���w��:Y���q��Q3:\]]QVV���
�U__��|_�,"����-���.�C�k����p�B��}������v_�l��i_qWN7�^YY��>be\�}�L\�}�l���	iii(..�|�*3��22�3��{��.\���H�RTTTx�����;HMM���C���/:T�NNN�����L�����s ''#F�`�PPP��^�^���n�P�>|:::��A�P��������e���
CCC�z����+��q�����s�����<��#G0b�����O�>���U�V�"����i��544```��C���������.\@QQtuu���c��)hjjBll,�s`��x��)���+��x�x���������Wy_�����}�����DH�
���f��EI~.^��I�&���)))4h���:::�;w������;��]��9	
���D9�o����v$''���X��c�J���xPP�>b6�����/"''VVV�s�._��e���wH$���������XL+dR�3����f�|��w�1c��::: �Hw�3q�A��K��������{{{������������1l�0F���y3,--����g�������5k����H)��x���?����E�`v��bH�R��m�_��$�����6��������*q:���N�<���z�����^��s��GEEa��
X�l�R�?y��B�
���������
R���w���S�^��O?a��9��2~���n����x�A��K�s�����c��1hoo��#�p�BXXXPN���D�B�:1n�8��3YN�:��������
�;v,f��KKK��������1e�xyy���mmm

���w!�p��mZ��~�:n��E]	GLL"##U�Wlff���x����s


ETTv��
{{{\�|>������O�q������Oq��E��,�e��}�g�������G���	OOO�A`hh===��������5���#f�����CPP���[���PTT@�APQQ�[�n�����F]TT���\���AGG��O�4�*�����WYdY�~=��]����^���Avv6jjj0n�8�+L�sp��;���0i�$���x~���_�)��/�@KK�����&.s
;v:::hhh�u0q�S ::���x���s@_�v-��������A���
mmm>��
�k��A(�����
X6~��%��������M6GGG����r��_�������+LMM�����W��������+8d���I��o��M�W���A"�P'�V�\	�T
���l� ��%������	��������H�5pa���
����?&�o��ceeed�������|��������<00��O"���S�
������+�������?������_TTD�O�N

�7�|C���_��?�����0���Iy>���������0(�������Oa������?�������9�����>}���c���s��w�}�:���3�|��g���������>}�0��?�$��'�@�5�%''�XYY>�/��O�.� ���d���r+�H��[����%166&�v�z).����W������ x)���Fbcc���9���'�~)���L�?N������-����XW�������)//Wx�!����������!�����}�O�&ZZZ���t�|>��M!g��%AAA�����8� ���w������@2d�2v�X-������]����)�8q��l�*����l���<�L�<Y�y��+++����D����$''�?y�$qtt�n39:D~��ZW!�����?~�466v�o����������nq???r��E���L��A�����7��
�^�
�)��7l��������bddDF�E����KV�XAq��A�w�ptt�\��P8A/�T*��#��_?�����������g����nnn�J��u�jjj�lk���}����K��������c����������l�GGG<z���������������
���;��������hjj�|vN���A{u���������6m���������V>c�<x��o���eee���_`bb��g���7������g\�v
�������q��e�������DTTtuuq��exzzRSRR�DB�������={6RRR���A=���!!!����g�}���FSS����UlB>|���pa��HIIQ�K$�������>@JJ
���U���>N�:�������Uy6������,��������
�^�3l�0R�3_���c�a�)�]Oxzz����8q"N�<���,�?������SSS���N�
ooo��nq.\���B���>��������f��� ))	�����
n���2ollDbb"n�����G���7o�DII�J����/_����1n�8���#--�r����:�����|�7o���K��x1K�,��Y�����-���0�[|���pww�=9�
������^1m�4�^�����wt���!##C%.��W������P�;z�WH$�z.\z.��������5k`kk�+W����	zzz���Ctt4������



\�t	8p������������/����"������?����_����1b�������#�����|�
�;v@SS:::8}�4��=�9s�`����������hkk�������c���M��[��YYY���F||<,X����
eee8�<����#G�P|���(((���H�>}�����������&d177��y��r�J|��g�k///�Y���l������R��w�Fbb"��]����?�u�bccagg������OHJJB`` ���#--�����x���(App0F��������MMM��c������|�	RSSq��%Vnkk���j����=����������T\�v
VVVJ���5����o�><}��6m���;RRRp��M�������"8p---X�n���q��Z�_��5��������I� ��?�����'''3:��A��K�L@@����i�&�5
��_��G�`dd��w��������X�z5p��5<~������[���+W����9�^����2����d;vX�b
���TWWC ����/�����������0;�N�s�:u
555����W|��Wx���B��r�
���;,X���w��cbb{������GGG+����g���X�AP__���4��1t�P�z���
jjj��+d|��������� �����9za���ggg�>}111�����g����///�D"��bDFF">>���GEE��e�������u���������BDEEQ�GDD &&<����5kf��	�@���6���)))���GAA�����G���S�RW@������?���,���'tuu������`���c��A����������e�������
W'���(������r;�/���'��������k�b�������5������~��w@�?|�+V��"�qqq8t�JJJ0d���s[�l���+����5k�����2���G��a�|�MBPZZ���TTT���<K�.�������'O���K���_?<}�k����1c �J���#���
���J�l���+1j�(��q^^^�����U���GRR����1�������c���~N�A��K����q��iL�<���w/���!�J����l�28::���)))g�hoo���)/^;;;tvv���+�������xss3�`�XYY���qqq8q�������F����������DVVf��)���Wp���BGGGiox�^�������~�!tttT�k��e�
l����?���B�hllDPP<w\�x���Q\\�V�())�H$b�l������"99'O��\��Dzh���������7oB��� �-"��|�����///���i9!�������W���������2�vKK�w�9{�,9t��S`�����������srr�H$�F�|>����ig'L�@x<-/(( #F� ���$66V�]�z�>\n�\ �0��K$����'���&$7nT���0��I`ddD�|�������������4bddDhgU��
"�������
���k���Faf�k�����9shgcbb���!���Q��
F�;F���TbooO��� xU),,$s��%iii�Bf����~>�A��K����.)**�n766��� "
����s@���O�}�]Z���
T�~�!�s`��D ��3f������Lq&��)t���ZB{ox�^�z�jZ��2����+�������������}�*���
###bjjJ��r�
�;��:�B p.\z(����������:�?���puuEgg'�s���o����e��1���@XX���9s���W�����k�a����7o�b1�S������g��]y[[���544DQQ�l���&>��C.����������Ndgg���|>���?~<���:8p�����k��� ��^�
444��3���)7;(��2d>��F'��!C��I�"��-,,���A;�
��������+�hhh�������U���|DDD��l��3g0t�Pj�1��3�������XXX���C�x�"~��'F'.\���J�(..�|U^ZZn�����G�����9�
;v,���i�w��U�����:���0a�V����P���������L�e\Yo`�%%%J{E�8::2�u{���u��E���c�`cc�W��zE�~��/�%�p���p�^���`�7�����'0f�,_������JD���kkk��)))X�b.^�������b��A
���������/F("!!}���s,]�uuu�N��\KK�Z<wTVVb��q���K�,Ayy9�����f�/^����C ~��G����g���_~�~���O������p��hkkSG����,���(�~��W
��AAA�������9^t�������r��>x�?��#>��3����x`` f��I��>�/�}������P�<y555ppp���#G���;`hh(7����qv0  nnnHJJ��;w`jj���,\�z��A �H���J�B:;;���F+d�qr�)����WWWBp��U|����#�����8���9.�3�7o���&,--��������������
ct��u�������9�z�jV>x�`F����/����r�@���x����?��;*�{}���^��"H4B�DEcP�hl�h,�1[�F�b�	��h4��A���R�6" �CU�M���|g�f��AO"�y��V�:��"��g��s=X�~=zAGGx<�$�&�uy{{;X,�?(okk����T��A�d�\�v��7H�rrr8w��P�(..�u��t�AR�����BMM
Bsss���R��7�G�����X�����%���$�� �WDFF2&L�R� ���9������������)�������^�|I�$�������amm
�|�2V�^
����1m�4L�:�y�&�����W}=aaa�>}:�t������DQQ�s ==��gK�ccc������z}���p���c������6�<yB9;���
]]]��?� �7��������*���
6����X�p!���|�r��������l6�r����C�rxyy����t������g�����������l �'''���X�|���������{����7���022a���PSS��
������H��<y��'O���---���#��	:^�x�����;���"/����������)m�]]]�.�eee��=z���zL�<���A�&�3jjjpww���X,dee�c�!������T�q<!!�����O*��;�_�����fJ���������|����D(((`���������BGG����h%�[�na��a������*�����������!���E>>>����i{��^������\J�@~~>���i��|�����AR�HOO��C�DzEff&x<<x��A�����w�����z�N����������q���Xlo�+F��s��1&L�B��A�6�
eee����������Y�fAEE�n����.>��CRH(��o� 55mmm(++��K�����!C� ((��9������@�������d��.0�W-}+�BCC1j�(��5��k���ooop�\����������/^�������f�"W*	���@�����9s&�&M�����%����~����������w����abb���R�^���O'����
V�Z���"���_X�d���~UUU�_�����x��Loo/>��C�7�ZZZ�����������cmm�u��	�����"<<���EQQbbb`aaA��`��hiiArr2.\�w�}@����C����iii���055EEE�w�������C���R���dgg��*�#Xlkjj���Z���KEE���(Yee%�������Z�	&�+,c��ERR�={�����'}���0f�8::�����I���w�}������CKK<==aee%������aff������b��������+((���A�U���(**�����B�������'OPVVF�(�����������Z<,,Llo��+���Ez���2V�\�/^P�*.�7xxxH�T�������-�w�I�`�X000�G}������`��E�
ii��� �3a�����@0���`ooEEE����o����/^`��i��x�N�/^���`aa���8�X,���c������?P\\���r\�x>>>���AHH��_��#G���^^^�{���1���6|������t���������w���jqSS����]��'O
=F����c�����w�����X�j��+�����G�?���x������%q�.JJJ011��'�����������VVVpssCPP���PVVF~������wvv";;��������Q�hg�G���G�
m������o�>���Sr~*++�f�l��U�P���a��EX�l"##)���tuu)���;6m�mm���L�0\!������������D�)))�������)�t��x��!���`llL���|�@^^������E���MMMHOO��������+WB]]��o���-"�<����s���<�%
��?�J:� IDATf��A�qI�����I������9 ##C�;�8�s���������{��!C(Om����^QXX�+W����|��s@�$�
&L���0�A�����������%���+���96m�Z'�����7�&L@||<~��'<{������


�3�����q#|||���MMMTVV��������;������X�r%i���9-���@FF��� ;;


R�+����E���l�����<������������'O�@KK�r�MNN�������W���A��Glee����=�t;v���HNN�j�8nii����7�W�^EUUy����*


������
�����������r�={�<.i``���J�+G����{���
===L�<!!!������O����k��!;;�_9��8�0�������8GGG$''���D�)�s�N����:�s!��7�|333Z�t
l��
zzz��*���Ptww�����K�r\�~��7H�k��EII	�s���>�T<<<��9�����u�yXX�H�X�x1***����HOO�����o�+��#��;w�X�?u�mo��+&o)��`���
ppp��7yyy���R:bbb������j!�?A������x�4i�T_��'O�S�Q�W�^��{�O���������oJ�@���www���p���������U�V���@�Q�)S�������[���W\\�������+BG�y<��(��������W�v��������m� 044Ddd$�������/_����-<(�3$##���B���{�}�v����g����S�L��d_��������7���������+�����V�<VVV������~��������{7�i����sS�q0a28����7n���
�������������N�x<J���$���ntvvR:���+����Q:BBB�b����*�766BWW�=Bvv6z��R\\\D���PRR��+�����={PXX333Z��8�}�v�^���
$&&�s��sAP�����7�/^����!�s�����������_�|I�$����T���2&L�F����L�������� ����X�~=���I,]��������/_+V� 444(yOO������ �vD���e����2JV^^N���jjj���NTTTH�O�>%

��9�<������������w��A����8|�0��'������O__�?~<addD��l�?��������g��z_1��� .\�@>n``@���K��X���#���C>^YYI \]]���2����HII!6m�D~LMM
QSSC����/&Z[[E����+5jq��U����#F� ���?+V�y�7�����~����	������	��#<<<�����������+��>&L�!C������������61q�D"**J�������ZZZ�������!��p�}��I�?��C"55U������m#455%rooo���3����<H�]�v����b~��w���?���������� ��a �b���Dss��xaa!��;������A��aaa��)S����c!'''�w�I����'LLL��g�
���."!!��������
�z���&���"��c���?�A0C������&DGG����'OFOO�s����������������@:t�6m�_|���,R��������g���g�Fmm-�s@�S	�tuu�x_������	�v�����q������.]���TUU�9�	&���_����x�����i��)"����t������������������c��	��������[1v�X�:u
�N�BXX���H1�����3f`��������R��@�;99!--�<1���%�L��d��Q�y�&����o��� ����b������d��������PQQ���+==<����
F����?�����\����:�s���&L�����QPP@������h�����k�+�7�W�9�����������
|��8.�W�����w�i�077'���w\�z��K��z��^!��b�����A0s��18;;����		������[�BAA��9�e��������P����������x<�������

���s�i�&455���ttt����G�������YYY!�������D�$�����{����������R�+����G\WWG������y�f���������"�___8::�����TDFF���~��/�c������rss�f������������=���#I��`AA�T���xqq1�\�B~^��+1s�L���	�7s�L�WKK�����a���8$$����W<m�4��� ''&&&�����{�(�U_t�
{zz���A)d[CCC^�x����������/DFh����w�y�|�]��Uft[�8� `�dp���������a�PPP����CMM
�w���Q�h�����{aaaA���s�DnddD���c�rMMM���������@� ����������O��III��s�p��]��������DDD &&F����6������,��K�,��k�h{��^!''�s��	����bZ��8�g��]�V�s@��+���PPP � 077���*e�����^�����b���������h{��^�8�0yKa�0�������w��������s ..JJJx��%��@?�<���0d����a���X�d	tuu����.�|����x~���


Q:�������Xddd���@�	���v_������_WW������v����������+�~����q��=��}7n�@ee��������l6���>b///xyy����3R�#����]�������']]]���/_k_1����'Op��I������yyy�]7A��/Hi"_|)���b���`�����kA?Dii)V�Z����{������������|���������Uvv6���)��=B}}=&O�Li������	��555���CFF,�����c��S������?*��8���@^\�r���:�w
\�~,�����:���� 88�\OL� HLL�����Ky�666:::���{�6''������/)�
�\E���B�z{{)/B������������E>>>����i{��^������\J�@~~>���i��|���"�~o�s�C������L�x<<x�@��������������
>'��)p��A���A[[��9 ���
�z���#q��9�A�������l`".������6�p�B����B��������	}}}b����Nq������L����W�&�={6 ^^^Nxzz����_|A���]\\MMM�����^^^A��N�>����!�l�B9;8}�tBKK���k���_KK��t��3gQZZ*�xaa!aggGhjj���YXXB���S�A���Al��U�������a���@A~��u��

%V�^M��1�X�h���?R�9����ADDDfff��#(g����6���k���C	KKK��w�!��� //���e��3B0< v��M���P��O��<VRRB=fiiI���������~*4���_uuu�����[���?���0 �8�0�QSS#�=J������'����xSSq��I�����2e
�s@�p8��C�###�����9 �����v�"

��s�R:����P�����5����?� ���O��M~N�8A\�v��I�?������N���Prooo�������$&M�$��\.����kq���8��@KKKlo��+ttt({?�����A�$pqq!{	�s��8 ���)���H>�c�b��m$��1�^��wuu���#���	sssJ��8�&�����q0a���8ax<\\\������d��_[[���`�|�~�! 99���R�+W����^^^hooGJJ
�,�����/^�����Q__Oe���K��wp����������b��d�TTT 99mmm"|������GJJ
:;;��������/�Pz�9r�<��'O�s������BGGG����R�8q���X�j������B�������011���kE�`���������4}�������_1l�0�X�IIIb��+���a��������s���� l��������o��#?�����VWW>|���@���b��9HNN&���8����p��M�����������Q�F������6`�����o���F�P���������c���x��1������'�3.]��G�wwwl���\:P��	��� �����c�b��qHNN&})����{�.��������#G�777#&&�<y2���������R�8��ADD�������C__)))�3A���J�|������+���N�7l��E���u�����S�N���
�7o��X,hhh���X��8��,��?f����|��b{��^�d��^!;;;������E�w�>}���B������7dffJ����
�S�z���
A���������������7������)5�^��	���A0s��	������HLL�����
n�����X���a���PTT���w���+(**J��������5k�� �Y //�����wO,OLL��e��j�*p�\���BFF����r�
RRR$rOOO���	9���PUU���t|��g���Acc#���������������UUU������&x<N�>���,|��011Ajj*ddd���I~o/^�sss,Z�			8�<tuu!''���rr����V�
eEE~��G���a��]X�t)


p��M:]]]8r�


p��!,^����$�������
����{����w��������������������yyy�����ZZZ����9s���8u�6o�///�=������@BB._�OOO���������PPP@ee%N�>���.�����M��G����
�������;����k�.���#..��A�oe����<y2�/_�3f����8�0������1c�g�888 ##���Dvv6�\�cccl��
���HKKCaa�D������4���
_�5�
6����R���K�������6n�CCC$''���
���HJJ�������Htuu���?@� �'2f�XZZb��m��� /�c��E77���p��A.�K�$�
�����	+++��VWWG{{;***����"++�7o��+PUU�7n@__���8v��Po(--��[�����P�^�`����	98RRR({����k�
A����'N���`��}�={6rss���CCC����'_�Wc��y���	���A0cee���8::"""��_Gww7Z[[������C__]]]�~�:n��� ���"�{xx`�����&�������������X�d�xxx@CC�t���CYY555X�l�D>r�H����w�/\��C�����}����UUUttt���~Cbb"���QYY)��?6�
mmm���c�����O�r��������������"�?&���v����+dee�������#;;�����4_�'�KJJ��7��CCCDEE!00O�<���^�x�}���������C��r�Y�u�����S�'3:;;???tvv�����E���J�[�����7�|���2?~%%%�������e��������X�by�M�A���A�������*���1}�t���"77g��A}}=deeallL:z{{����?��S"�p8��x�����5k`aa����������Bss�D�����������������k�������.����HOO'���9��tww�������I������\\\D���PRR����---���#�����O����
�X{{;<��q���W��
�{��o�H�hhh���?�9"##���N�;rss_�Wr===p8|��w7n�@uu5~��GBWWW"�r���+����8�0yaFa���������DGGC]]�����kL�4	,�|�����F+((�������}�6

%��S�BCC���777455����>|�T�J<W[[���Gc�����NII	s��!��SqOOO��� 44���BG�%qeee,X�O�<App0lmm�UE�TWW������puu�����7�***X�d	233q��U|���B�|A^SS#�gVVV��y�����[�na��9��4�'v�M�


�����yRTT������C���c���$311����������g�'X,���0u�T��l�<''�f����������0a������y7XVV����������/_b���B���F*���&��9���F�
SSS�xWW�O�N�%������#ttt+�������Ih-�����<������G���>CCC�[�:��
������iii�4in��A>����`��9B�c��u�����DzC��A���
����������<>>|�����u_WW�g�FZZ�T�Mz��&L��0
~����������������b����*��~�:������.5t
\�v
����������: ##����A*�V���������
��G"������;����t�R!55Uh6P/--����ann�+V ;;���B��������7N�<	�������"��|nll,�g.//��s�0j�(,^��|��3(������k��e8p����+YYY=z<O���:u
ppp �Z���������������w,8;(�'N�6�����;�@� `��	�3<�<�������T���c��)�����r$&&J�]]]aff���T!�@\\?~,�����rDGG���3g���UTT�����r�����������.�H�
��
���xxx ++�v�r>�����O�$jkk�8����\\����=m�x�^!�=<<p��}�@@@��#�$�
:�&L��0�A�c�����999�����	��W_AEE��9�a�(++K��������"����###)�k��AGG��@����d!AMM
\]]igW�^���&���������7�������N*��>�g�V�\)v6�����������9�;	���akkK^)?z�(PWW???,\�P�l �v�y�����\���(�����������effACC���x��	9�w�^��1�vvp����<y2������A��LJJ"w_:zzz���F;����
.�K)d��wuu�����ygg'���h�|�q�A�������!#####�������022����1r�HZ��$��7�`�������[�J���������7���X,��$hll�� hoo��#����M2���@���B����W�h%�@��YYY��g���A0�|��I���b���3�����_~��C������;v---��c,--%�vvv��#G���*U�8v��<y"�+QTT___}SSSQ��~���z� ���q
���A__�}�f���G�Q:	���wwwddd��I��������dL���0�AsssR�7a�,_�����S **
<�����q���+���������)�������]������I�������@}}=�>Axx8��o���fCEE/^���d��PUUEYY�s ##���b����l`NN���$���"����O�B___�I���///�A����a����_~��+**���6�l �/^�nnn�����'�s�N�7.��i�(��n��_����M�6����"��'N�@EETTT�fy<
q��TVV������(++ � (//G||<.\555��.,,Dff&<==)m��xNN��e� IDAT����������tTWWc����0t�q0a28����������BFF��e��S���K�p8 ��9@��N���@477�����9@��N���������R:�������+���@� ������<&L�@y�6<<���7n����x��q����9s������0|�p���S^��t����`ccCyC�O�4I�A��������7H�***��h��YB_���2�-[�s���;��y�fdee���#F����&�555|���������o��&U�(..��DzE||<X,<x��A����g����W466��������w*���			X�j�kb^^>L����z�$>r�H�;w�q0a����ddd@AA��O'����rrr�s�455)�����+���cccJ��8������VDEE�����9 �744P?�������������������[����B������o��I;XXX(���������������b������=Btt4�l ��9�d�/_���[�����w�b���9r$��G��_ETT��]���G�\Ckk+�k�C98m�4���#33S����������HKKCII	�]���<�\.���������vU�$���+TUU��/J��������QH��0a2��b�`kk6����2��5K�)0b���������9@��N��C�"))	�����:�w
�����������t����Z��Z����������>���L\�~�=��%K�����i���ajj�m��������kjj��� ��W0UUU�p8��i�xtt��� �W��}��
�/`��������_����`�X��������b�
��7QQQ��:99I�+\]]){Eii)�����1�^���s\�z��8�����/���8�G���C�PWW'�$�$q&L���P�3c�VC\\\0d�����������S���s��AOOy4K___*~��5���������HMM������I��8���n,X����������������(�<�g����x�bTVV"%%�f�����_�l��>}:���!C�H�>>>����i� ++K����a��99���b���333���E�`���������4��������;x��w�f����B��n���Z���$��w���CPP�����g�4��/_���=yG���`��ptt���9�Q�F�e���\.���I����
���)�����g���GGG�c������q��%�{�;gL�0y{!���7nLLL�f�agg+++�)p��}���@__l6#F������=����������T���;������N�������PVV��������$���z��l��7�t���Oi��K�p��Q������'�N*����PWW���7���1q�D���Q����a�����}�qooo��AR�X�x1�����S����������>s�?~���!t����R�
>��+���(Ou��������u�A���g�����1c����C�"$$�6mBff&�������AR�`����� �9q�v��	kkk$&&���@EEE�)�~�z(**�:�x\\����f�A������X�lV�Z.�K��===���&� ���BUU����}}}QUUE���#������+.((�u�#:t(���aggG������������w��GL�������x��	Z[[accMMM�3�����q#|}}���---�����f#""���N�>���T$&&b��
PWW��bO7;H��������;����k�.���#.._}�a��j&�3~~~3f���ddd���@�)�m�6X[[�:�smmm!���_�a���:�xrr2���q#

i�T���;���DWW�D��$""���PUU��a�@,X.��K�.a�������`nn�������
�� 88\.��7H�>>>���ADD\]]���7o"88&&&����)��:L{{{�����\.8�m��I�+JKK*�+,X���2������p8HII��������Z�x��M�t����IIIx�����~�?G�AGG�L�YYY���c��a���'�'O���
�zEpp0����8�0ya�0VVV���#"""p��utww�����9p��-�������C�9M��Q9	��%KD����PVVFMM
�s�?9r$���I���p��!������b6�
mmmrv��s��K��X����W�v0;;%%%���oH���!���(�>b*���I^��_IJJ��1c��G�/��S^^N�.�w��	���%�t_�������e��������X�bi�t���q0a28������pL�>��������3gP__O�������?%r��G�������9������hhh�����Bss3zzz(���]C{{;������� ==����9�$�~�-v��
eee}����D�^���O>��'���D\\\D���PRR��$���H��;�3x��!���������N�]����PSSJg����
�x�b�{����}�DzECC��������A�__M�;rss_�W}�v�����$l���W�FQQ&L��3f������hll���7�p�B�����?p�������.�K�$����t���2&L�F&�.VVV��� ��/_k��!455�%K����B���sb�������T���H����^^^������#�������bb�����:�n�:����O	CCC�c��?Ohhh_}�QSS#�����B]]������G�&����;vMMM�yyy��a�555b���DGG��xNN���K2�8t��?|���A\�p�|�������'�l6���K����������yOO��c<�HMM%���E��������������r�����	����8�<-5j@���4b������gb��RM�_���+���&L����!C�^������G�ZZZ������o}<�����^�J�;��r�xgg���������g���E��3G�����j����&455%�����O�&H~��Ab����+KXX��������w/��5k���?~��0�T������(�����F� $�I| �p8Dkk��c�����}�SS��Z�#�L�B~��;yyy���uzADDD��� ���u���������"f��ETWW��edd:::������ �Whjj)))"���	�>��p���C���GUUf��
����T����hjj���������������'�\�T���H����,X����x{{������������a����� _>'�K��X�����+�|��`�����GL��������s�X,L�0A�{������4rkD��5
...B������+�8q"�l6?~��t�H�	&L���x<�4S[[RSS����)S����l6��|��8���www��Y�}�A��P�GCC���puu���.�l6***�tc������
����r�I<==����9s�`��u8|�0`���"kaa!$��7#�7H��=����r�
���p��i<|�P�{����!C�����r|�����������{Eii��^!{{{���:��CCC����!C����^�k�����5k���C��/^`��1����$�
��_1a���
� �9v�������HL�0_}�TTTh�6l����DM���.�9	�<22��9�f�ttt�:	9AHNNr������U�}�222BN___TWW�:�s��Y�>bq��~ ��	�+�r�������t=z�4JK����?}����PSS��o����=z����������#�PzxxI������?K��x������BFFtuu������$l��	������mmm�2���np�\��-�wuu�����ygg'���(�p�����	����BFFFFF������add����c�����:^WW����S>��"���G�p��9������������?���.���i��7o��utt���F����v��	~�o��6�xxx�����]���<���l��	,yyy������bcc��������+�X,�����
YYY��P���T����#  ��7H�zzzBr��G�b��y

BBB"""p��Y\�zVVV�s}�|������?#;;��{��c�����^������"����s��������w����#F����!@OO�v���E����;w��
z�l6����������N�2��W��}������	���A0cnn[[[(**b��	X�|9���I�@TTx<)����+W���S:�����#11


����tH�7o�DFFyG���G``����UUUQVVF��������X���!�>bq����r��j������H����
�_~��v��}��� TWW#&&����c������$����PRRuuuXYYa���"?�����i�����W���PXX�3g�������(,,$�����r���c������"33����$j <''EEE���@yzz:���1c���Nt�q0a28����������BFF��e��S���K�p8 ��9 �}}}��������b���B���~���W����q�###�1�S $$����r���q�����r�
����;bcc!//�	&P^�
���.��'�D�hkk���
8r�D>&((�����=��K�.���	666�1��I�D�1jkki{��^�c�rCNdd$���,]�������&7555������/��������O�����v�(..��DzE||<X,<x��A����g����W������s��!88�N���#���b�^�Z�"��g��t�R��s�\i]XXkkk��A9r$��;�8�0yaFi222����������0i�$������;������+�����������FLL������J�9��������QQQ������S�EEE�xCC�����+�u����_t���������
�\�}��x�}������S�N��G,i_q�b����SSSl���7oFSSYv�|������DRR���~zzz���_"))i@��edd`ffggg��������.QGG�?.�K����QYY�������^�BUU9J2P������j�]��8&LWX,�B����f��������6661bRRRPSS��3g������������u�PPP@>���p 77EEE������y��yyy8::BOOw��Eoo/�O�N�5��K{j�j������:������[����j�*}#��c�SSSC���JUU8�x�$-�7H��-"""�������c���8t����P__���d�_����X�t)yHEE�w�~�^���J�+JKK)�^$�������o���^����������3._���� ���b���X�|9�L�;;;|���d���?H�
�8&L�^��0A���C�Ajj*^�|	�?N�����3222��q���khmm���':::(��x@@����`�p8J��$.''G���n_q��A999,[���90d������v6POOO*N7�gff���W�����#�F�G�l�2��A*�������������5�������#33S*������<�������={6�l _q��r������888������Y[[c��=����qtt��m��J�@������_R^����9�}�9�2P��	��� ����q��a������������#G������������8q�|,<<���X�x1���`ee777ANN�<Y������(((����}}}J��������A�d�,Z����|�������<Y%)?��8rss1n�8����a����6f����2e
���$���-�7H��������.M�4	��������p�g���GR^�W�9?�^���Gy�C\���Wdff���"#)��GRR���x���+��!C///����qC�w��
�z&L�^� ��'��w�������������<n�����$���c���PWWG||<���!''����K�)))X�h>��3(**"66---���A`` ���/������������_�?��YYY�������*� x��!JJJ����_��|�	:::p��-}/dg��!������p��
(**���?��3�={�-[�`���b��+PSS���������G�Ayy9���;|�������q��U���������CUU>�E������������=ye�����OGTTttt���������~~~���DII	n��!���������������}�0{�l<{�����uttPQQ(((������MMMTTT��_~�����8w�455�k�.������;����;�W�8�0���������w�^899���G������*233KKKl��
�F�Bff&���iyZZy��^����*�.zJJ
���K��(((�����9�����g����7n���)RRRPRREEE$$$�����<**
�������� ����� t����� 44h{��^aooO�6���!++c����444�x�b����-"/\��JJJ������'���/u�����_�%�+���QRR ���;w({����T�"''�W���333�����o���e��d�|���8z�(V�X!����DPP�P�8~��k�����c��y���	���A0cee���8::"..AAAhjj����9s���
]]]tww#""���hooGOO�D>�|xzzBSS]]]�q����������N,X�@,_�|9>��������W�^%_l�\.V�X!�[ZZ��?DUU�>�������f�r�����.]Bdd$���+~��Y���BUU---����0m�4(((H�8u���������o��'N����D��r����{��A__�����?)��eee��s'� 044Dtt4n�����T������
{��������	�������MMM�o��c��A�����S����!�gffB]]�����u+F�� ���s�>}�����������W_���������+QTT@�A���A�������*"##1u�T�x<<}����������+++�Y����Evv6���OZ���S��������
222(,,�����o��S~��Y���`��)���������-���	zzz������@�����b����� /����9�����"� hll������ �f��M���O�^$�n~XZZ�����R�^�����~�I�WTUU�������|9!U�HLL��+lllp��!�#���HLLDii)���1~�x899Iu���w())�v��o4`L���aFa��������rrr�w�TTT��{��G����===HHH����F+((`��qhkkC||<ttt$r�1��]\\����;w����D*NU�`ii	ggg�EZQQ�&MBee%bbb(���+JJJ���G����<�'�+))a���x��)"##�������������1{�ldee�����<y���Z����`��������">>�'O&_��>��4<##l6�'O&�������{�=�<==YYY�4iF�Er===899I����1q�D�������v'�	&L�EFF�4����`���011Ajj*���1q�D����b��ab�;��C~��/_�������	���Q^^��3g
	`kkkQ[[���^��{W�����B���{011�7~fkk����y�Eq��������,M�AD��A�h,X��'&���r���b�7�{�`�X���"]�H7�HQ�������v.+3;+|1w���<1/Xg�u��g>�s��������>�\AA�������K� ��[o��� IDAT���s�b���D$����E���+��PQQ��+�����w��+,--�6��������W_}�
6`���ppp��k�H������o2�1_���0b���,�@I6u466"**
MMMX�t)���Dd<z��������\<11���Z[[�S�NA,c��e���r��O����		���V�Z���6��d�o�������#$$$��������!��];������_����u�P^^�7n�ut�����������_���"���Jt�������8q">��#dee�����s������������4i�w�����cQQ�\|��)D�qZZ��L���\�����W_},@zz:1�������,�?^.������tb�����2��#F��J�D"���OJJ����1g���� 55��mmm����������
����/��������������!�U����9s&�.]
b;www7���������
�A�.\@UU-Z333�\GG���re�/��7�q�RSS����G���o����#��������� ��������������q��~���T*�Qr=��w�����F�;��s��%~���+

�����{�b���������JKK����%K������������W�������`����/�2\F/T������}��X�d	rrr�?h-!!�;w.,X�[�n����h���.]�����t�R���"99�/_��%�����s�����+W��k���+W���������'�����
f��M<���BCCQZZ�����M����	������ <|��|�	<==���O��#����#00uuu��e�����G����i���;�����$��,,,�c�����R�W,����`������akk�}������
������]����E��o�SSS:tAAA���PUU��}� ������8|�0�9���^��TUU��W_�r=zG�EWW���)���|>����R�������������������===�D�A]t�#F#O������@ss3N�:���G��w�A{{;���???������s�\UU������5
?���������CMM
�.]*�Q����E�!22�O���Y�PXX��W���������KJJp��A������b�(?xutt@II�2�����CEE��"�����AMM��Q�� ::��7���7�x�x�s�������Cjj*������H��444�7�|��w�J�n�m���;w	��������w����'JUf�������G�;v��I�+$m�[�
f
������3g���~QQQ��h��
��};����o��}���KI��1���d�@q�\���BKK3f�@@@����L���8tvv����f������|�2z{{���C�9 �GDD����
����"��������f�.\@DD���p��
(((����tv���`�Xhkk#�HNN����L���L�9p��M�������f�����LhkkKe�������� ���������?h60''������d\2�w��!@MM�4s@���!�TTTHg��H$BEE�=���Rttt����H��APYY���/c��������������?�"���Eqq1-ZD�@�o�����:��7�t��3��Lijj"  ��577��,�9���j(((�f������}����1��|(**����hjj�H$"���|>�w�Fhh(�
�*�����PTT���7�"Add$

���E�@�CCC1f�����.��#G�����������i�e,Z�}}}����W�����r���?�}��g�jjj������d$''���366����
///:tIII���|��W�����wl��}�������Bvv6���H�o����w��B�?����Tuu5Qo������������?����f21zbFF�
��p0y�d�o��H$BZZ444H3d��'������044$���===���S���`��Q��t\br��d6���III=z4��`}}=���L�9���CZ~��
xxx�f��wO.N5�WPP���x���B�nnn������HKK��$�g�������C�9@�%�999���?(g�8�����)q��m����VY��'�|>�/�X�G��M�E"�|>��������8#F�F���rq��-���Rfdee���'����+W�$���	���?1f�())��������3gh��WWW�%��������@  ������R��$
���I��9��Q���d>�,.���(_?:���&�7��
�Vw��u+v�����7###�x��F����+q��qTVV���W����*��;�O?����R� ���r�2_����k����y{{#<<��u����W�^4���o���NNN�;w����`����Ss8�g�L�2zzz�����Q�����G�����(++����B!z{{aii	MMM�xhh(���������.p�\������aaa2ypp0���������&�X,XYYAUUUUU8v�-ohh@ss36m�������8|�0:::������())���
������$��y�PZZ
uuu�������������@ ����e�E����:::���!��f��x�bZ���
��������������7�|YYY������=Qs��/�@,��������
��?ttt0�|������H..��;r�

1s�L���\.�����!33aaa033��)SPRRXXX����n���!22������DUUi����&O�L
FFF�����K����1a�����s�\�7��9Ss�������;�f�aooGGG<x����022B[[�]������������������WSS�������pww��7 ������.��QQQ�����	`jjJC{{;�^����dee���hjjBll,���1~�xhkk�����������Gee%6n�������c��������[[[�-�t|������"���{xx����rqy '�9|���P__O��|���5�;VUU����acc�K�.���U��������'�|�5k�������X�~=q�$33S�L��w����<���D�fBB�b1���)}�<�Bn������������������l6�|>�����///x{{���������>�|>222��+:�05���1#P�����-[������t���CQQqqqD�����


����������<++K�.����������Dtvv��b����D�������+�b�
��b\�~��Fd��~~~�y�&>��s�������"f�-[���^����PPP�H$Bpp0��~�m�������PQQ�P(�����<  �?Fll,�G��/���K�.��uuu���"��f�����������7n�@��3g���D�d6��o���9s���C\�x����������m|||PQQ����CWWW&���'�����b��-�:u*JKK���Z^QQ����COO_~�%���O�@�w�@������;0i�$l�����CQQ
������\"s@R�����;w�H���WCWW��O?a��i������[�y�f��?
�HOOGpp0&M�D|�UVV���!����������CUU���D���
`ff���,TUUAYY��_�v
			��x���P/��D�@p����
t�b��9HOO�������i��I-H�'�Jttt������L�>�x�a��yr���g��.Dee%��Y�����'HLL$�FFF��B]]��===,X�]]]022���!�k/i���n}V***���Bcc#<8d_�E�1��1#P�G���S�0~�x��q���hmm�H$"����Bww7-_�x������X��|����f�+V��)p��E��rd��r;;;���������A�c��;����%�� ���v��*.O�,.�
|��������d<|�[�n%2LLLp��U���!==���X������i���>b*���C�GL�555���G���L�Z�
��� �A�w�A�������:�\�ooo�D"������#x��!���H3BBB��?�@����a~��W�����;v���S�����W^y�`B�YYY8y�$=z�E�9p�����,�����y�3�N����A���S�����:
ggg���@EGG���������5�/_###���{�.F�M�gD"X,�\�c����|E}}=����?� ..�F�"�)))��b��}��vjj*^{�5��###L�>��O���7�������Ay������%���M�P]]
�!����<DGG3��1#P�-_���pvv��Arr2���H3���ftuu!!!�����,S������077���m
onn~��bI�@ee%��M�9@���#��%�T}����
���
�GL�W,�K���2��<}�t�����2e
����g0���1	b�XD�����Q�`nn���t444Pf������u�d211���u��I16����GC__iii���#�PWWGJJ
-WPP���#s�����7�qggg���c��i�y�����1c�������hhh 
ltpp�z��X�v[�!�WTEE����W�= im���BHH��]


DFFb��
prr������8::��m���%�{��!##cX�����>������^�!0b$%f�`J�����QQQhjj���K������$��<z��������\<11���Z[[�S�NA,c��e���r��O������U�V���M.���5�9���=w_qyy9~��Wp�\�[�����q�z{{��������a�����l�\yy9�GL�W,�K��322d�Sqy�����������������b����R"����������p��m��3...HMM%x[[��������6l������6�p�����Dii���w�mmm������
���/\����*,Z�fff2���
i��Et��y|���'+�� �����B�I@�+�����w��+.`(++����&M��U�p��1TTT������X�f
��������7���&&&x��7�w�^���K�����+�����;j���/�1��A0�g�8::"77III�1c��_mmm�����ZZZ�������������)3	$���+�����T�yoo/222�20w�\���+V������2�2	��b�Xj��.����������t�R���g3	������@d����������0�|��:�}�v��=�2s���������x{{S�n����{yy���������D~~>��������� ���������x��������}}}���2���������L#F#S;w���V\\�S�N����}����H3F�-�;;;���������s�NL�6��\���SPP������TRR������C�9�q�FXXXPfl��FFF�q�ZZZh3��� 
)C%��B�x{{;(C�x[[�l�\�,�`��y

��
t�B$����C�B���=rrr`mm
uuu�<y��W���/hhh�+X,*++�v�Z�fff3f����c�����"^kwww|���HOO�������b����
,\��1��]WWW�������v�ZZZ�y�f�����b���(..��������_����"���!77(,,��:�<���_��Ce���A0��rakk---��1066&2������	�G�9 �GGG�������EOOi��,��W�B(����4s���9s���hnn��Ap��DDD��W�b����F�9���%%%�\YYY�>bY����t�������~~~�B���>���A��T}���$S���C((( �#����+�D������GQZZ���TTT[fTVV����X�r%�����������hii=7���Eqq1-ZD��<�y�&���0o�<�����F�F�455�'O���������T�@xx8������@�I���ggg�t��Y���8hiia��Y����B��+V����DX����q��q��,s 22����|��������o���/BQQ����wg###ahh///�T:�1c�����t���9r���pvv&]���M�6(�`��E�����
t�BAA�2�H_!��7o��hii���������X,dgg�� �D���o)}@�+�Uee%"""`ii�����~�@UUU���K��m�����;��+��f�B������K������'O��G���|bFF�
��p0y�d")V�) ����


��Y|������Fjj*

I3dqOOO<}�)))5ji����g�<}����pvv&�x��!-���X�����#(�P777��@��bY|`�@^^rrr(3��p��Y,LMM������o�����.�X,��'v��q�G�US.�dvu�����3b�hdIAA\.�n�Bmm-e�@VV�<yB�%�A��������Y�fA[[���vtt���1�|�M|��������M�-����?&�lkkMMMddd@ �fPqEEE��}Y
�����������(��x2_��x��t<--M�o��III���P}�����x���5��w���g666��e���@OOjkkI_s.��?�>>>����b��/�N�8���,Z���m�/��2�k��]����)�M0b�����@���S�L���:::0j�(hkk���G8}�4�������P���^XZZBSSS.���jx{{����\.������EXX�L���&������	,VVVPUUEUU�;F�����M�6�1(--�����}����Cii)���acc����r���������-Z$W�,���M�
��+&�#������=�E��_~�X,��%�����eqI���#G`hh��3g���FFF�r�������www#--
���������%���Hk���0y�d��=+###xxxP��qsssL�0�r�/�r�7n�ssf������;w��f������x��,--add���6\�v
��_���=���Q[[sss)>~�x����'������O>�;������CWWuuuHOOGzz:������<y����000��?��Y�f�			HHH����������XXX@OOMMM���Evv6)ollDxx8*++�q�F�#���;v,�����3lmm)G�����aeeE9�@�=<<`aaA��<������{�����
t����eeeC����5d_QPP}}�A����AYY���.����X,���9����Wb���066��-�����G����G(**���������3��$��������8t�,X���9r����
0c�xyy�~��=�N�����_�!3bD�Y ���?�l�'''������������#2�}�]hhhPfP���,,]��W����e�������+�b�
��b��Y���7o��� ���EUU��}�t�����29]����X������Gl``���d�7�X ���3q���A��d}������T���m����C�9�,�����#��8~�8������_B__����W1��L����&M���[1n�8���pP�����,������	 
��'BUU�tN�����/��_��}�P\\�M�6��N�<	l��fff��d���kHHH���� �;�l����3@��|��e����>d_!�QQQC��?���g������k����@���$&&��###�}��G�0u�Thjj���mmmPTT���O?����b	?�� IDATl��
S�LAbb"N�:]]](**c~���R���������+����h���v�������+��^�Xww�?��1�_L�����q��)L�0���8}�4=zeee���a��������GBB��9�'O�@II������������r�
��=���v(**����W�����x���Cdd$z{{��p������;w.��������};\]]����<���8�<D"�l������S����O>��'O&f�����555(((`����8q"�l6-�����#GK�	���o�E�����
_�5�A`bb�k��!>>W�\���6TTT�e��9��~�������������QA$�������`��qC&OHH���&LLL��'�`�����x���;���T����>��C���!33�V�����Hg�]�d0b42����k��a����D��>�����@MM
���X�f
,--!
Q\\���P)���SjT���AAAhll��u�0w�\�����
��������466����)S������n����'���C���`�����������HLLDAA����<==e<}�jjj2}�H�}}}8|�� _QUU���@����� ��������������pY��������������������o���5,_QTT�����6���o��{��333����� �Db��E�� ���s8b�Xff&������===����G�FOO222���`8EEE888���
��������K�s�������������000���m�nmm���9\\\��������EZZ� ���������������������l www���w�����������
&M����$''�����H?�%��%9���|dff�����H��V������<�������xijj�����KB�\\\0v�X�������N.^^^�n��bz�1b4"���@��d�X066���.������c�����f���t6G�������gi��q�\�Z�
'N�@MM
&O�L���&&&���\.YYY������%�����e���_t�a��
eee��b����)}�p}E~~>��HKKCxx��1�x<���H����
����E~�!���k���O���#F�!f�`j���X�d	����(//���7D"����L���j������G����@ ������r������p��1<}��g�FGG���e���>b�����F__������F��|Z�����������~���***(--���f��������{�����&-Z��w��������������;����add��K�"//***3f�l6-/((��;`eeE��jhh����x^����A0i�$���.��[�����1c�@("''����|����={6������
[[[�x<dee����������MCQQtuuamm������!,,L..1<������DYY������3b����;v`��)���'2������kkk<|�FFF055EKK._����$R����f��l�T�IOO������hkk�Ja�X�����I����r�
TUUa``����;wEEE�:u*������333R������Z�����>��;b�y�fTUU��
��())��?�8d_q������|���233�F�����w�W��������}Eff�/((������o����H�*�l��


�]�?��={��g����d��\�I1�^��|>���������,���b��D_jDD�������������������\2������/���{������-�GFF�:{�,>|���Wc��iHHH@ll,-onn����r�p�B\�p@���'����>�����x�"�]\\p��!�����O>��	p��9�����erGGG��������y3���J����������@��?{{{������#+++|��w�������X,��C�`hh�-[�������~�o���Pccc������?Y�������1�=��G����ASS{�����>��s���/����&�?�c�����l6����	>��cZ�������8q����s���?��Cgg'���Y������G*5�yxOOx<i��<���B��r�g������s������O�"""���X�r%:::p��I������uuu���������|�r���D�����������	[[[�������V����J��:;;q��)����������>}:�,Y���*DDDP����c��=r�m�������mkk���e,omm���*i�<����!�t<77�����
t����AAAC�>_�k�.�}���� ����KKKJ�1_�e�����WHxPP��}ENN���e��������@������^Y5���1#Pb����044���//^CCC�������y�&�l�T����-���Ctt4�f��2$3��8��Cll,�^�
�%�9�p�B����T���p���o.\��.��bI��/^��������o�M�H$����??h�o������p��l�������@r�d�B��� �������{�A��T\�'�����������_���<hv�����C,c���8~�8<ee�A����H$���������r�kUU����n�:�E�{��!99�V�"]�����(,,D@@�"���BMM
/^L�@�1b4��f�����}��AII	���R���/���'�w�^(**�$ ����L�������PTT���'�/_sss�Btww����X�~��n�������w���HeHFd��������W�^���f��E�Hccc����<""���$]������������Ir2����������WH�P}����"44tP������������>_A�f�����������-^y�����:�����G���l1#Tw�������

Hg
��}�����T\�)p��m"y�,s��K2���addD�9 �744��d
�
����������[�`kkK9(�5(��9���%svP$���~����	PPP@���������}d��T\WW�G�F~~>���Hg�8��"�������HyqWRR��= y�v��%��C����2?��qF��<!//


�����x���sq����#77]]]pqq���9���F�Bkk+.\����A��L�����*.OhiiQ�@:�<\WW�rw�<\OO�rw�<<77W�o�������>T_���@�+<x0�}3�S����W��200����/������;�_��jjj��F����={�`���D=���X�)PSS��3g������uP��,���f������
]]]�2d��� twwc��y������9@�;;;����M�6���+--����q�����*** �����K����f�
TUU�����&�
�����������YXX����FJJ
�#""`oo/�A ��������/^���t��@2.�


����������A��T\2�
{{{x{{#??�l ���Dbb""##��+����������PGGnnn�F�������a��p���+C�ppp�4�T�� `�hdj��PPP���;���p��=���Ie$$$`������AEE��L*������Xdff���&&&������	�������-������LpI�@AA�9P__?(s�����!$$UUU��q#�;;;���BQQ��u�����2��W`aa1�N�����������9Y�'�|���jJ�@�+���PRR2d_!����C����PSS�+�����p������ ��044��/�W�x<����W<x,xi3����7N���X,\�tI�JDF��
1##Pl6��-���
"##q��ix{{#))��3����9�,J���������R����{���{v������2geqwww�����
���r����


����z���M�9@..��4(����g��|>!!!�������Q\\������c`���aJ���_���|>����+s��������W�^���'�z�-466�������/-�s��se<�o��������Kz�������\������!�
	��PSS#�����z��?�������
�Pmm�!�
	��x���KB������7=�����Cb�Hn1W�(�L�0@���?�eee���3g� %%JJJ��,s�����q�i9Y�@dd$�\��#'[
�������l����7��X2�w���>b:.��;z�(i1������O������}�����j�s���G||<���K�G,�
��{������l`pp0-$�#^�v-�;&7�����~;;;477S�eb����R


X�lQ�r�Jc��]PSS#�

��?��3TUU�2$����rs����'O���~���
-���`d�?BA��l_���o���o��b�����x�|��HOO�����������
	��x����M�F}}=:::0{�l,_��E#F���(I���!Mff&1+G�9���!7'�HOO����\�,s����000���m�nmm}��������O�>��%�7����}�T}���<}�t���...�vO���r3b�hDHAAA*3�������������)3���[����F�9���&������������>�|�/:�0�}����L_1P�����c��"??X�b ������e�W_}�C�;�Z[[_�!1bD�� ���?�,Y��@yy9���!����>(s���G����@ ������2�>}���g������2y__��L���>��;�������\__����������@EE�/�+���X��>�W���������S*�`��Iv_1U1]_����GL�%�GTXVV���8b�������F�F�v���)S����mmm�v�������kkk<|�pP�@RR-�d�����u��\\GG����2�����Y\YY�������|�:���$����7���J�o��}EII	~���!��;w���~�+����5k��� ���FR�1\_akk__�!�
	/((������o���fHTVV������#%%iiiR_'O�Dll,>��S�!����bF�agg���ldee������������z��bDGG��V����>-���Gss3D"��9Cd,_����HJJ����wtvvB(���D�@@@TTTp��uZ����[�n��/��A�����%Kp���x<>|��
|��7���@p�H��{���/�@ @\\������?��1��p�Btww#**
JJJ�������o���o��yhkk���g������^�����<�t�]�v���
�����mf���'O� &&���hoo'f��3f�@}}=._�UUU<~���
����-�o��S�LAMM
���������b6p��M�|��I���Djj*����D�O?�����C[[eHa__:;;)C�xOO�����������KRH��F�F�v��	�H


���������+6n�GGG#//�h
�d���>�vvv(,,$������������r+++������,			D���u���rer333$&&���~�!�����B�����6���!���V(((P�!������l�����l�`��Y8~�8�o�������������!���~�	�`�����"F`ll777R���w�
�W���kC�����!����h,\���^ 8z�(������8��q����������?���^{����!&�`J,#<<����������ahh��s7o���&���������D��l��Y���!66W�^��"�����T���p�������r�S�����i}������������l����XwrrV_�������E"V�^���8p����[^����u������w���X�ji�!/,,Daa!H��xVVjjj�x�b�:C:����%6�
mmm���JJJ����)p��I��������T\2:p��iBQQ�4s��K*
#""�{�np8��Y�����������W����Y�f���������1q�}^xzz�.�����Pxyya����u�9�v��
eeeJ�@�+$|��B��_:ha���P����
gg�a�
	���Z(zYTQQ��?������i�`ff��'Ob�����������K,�1b4R�d�P��{,...044 �)p��m���RfPqI��������M�9@�%����022���� �=���+~�>b*.O�,.+s���x�D"�����#��/����b�yyyhll���+))�.|�>���UUUI?������e~����1y222B^^(3rss�������F����:rss���E�9@�f
���@ PfPq�"����dna������%�����y%���#]�������
t�";;{��B���+�4��+<x0���@N�;^f_��k��]���_��>�������?����n�:a�����u��>\F���� ����3g444CCC������'O�Dww7V�^���&\�~zzz������8q


x��wQ]]��W�B[[���x��-���>�������;�x�
���\..�n~V������_all��_����|�2�.]
mmm).���t�/^555���`��������e�d��+W"99.\��E��L���w���S�N��7n�@ll,�����J���O������7�]�&��������_'f�8��S�b��IHKK��Kf��?�������ptt����i�d������9s&����7ob����1c-���DRR.]�___b+�D����v��O�N��S�N��wp���a���������xaa!jkke�#F��z�D"ddd`��y044DJJ
���	&���W�\Avv6���������dXZZ��������b,]����077���3-ohh@TT>|���$$$������������������?���\��o����X|��U���������)}��x������;d_!��������b������d���+x<��|�<���,�@0�=����H$������������_}����Y �b��X�lTTT���O���IIID����/���q��yDDD���			�\�)������t�����/^���L�i��!!!�����������rqK=���v���W��b///��������\}��8��!�+~�������i����G,���b�����@ ��#��|>!!!�������Q\\,U�%�������
���AAA


������!�b1���SSS�D"466B �����?��066�P($.������xx��	-������x<?~������---2yOO�0��3b����H$���-��������---���#2V�\����<yR.������2"S����Bcc#N�>���p�����;w��K�,AUU"""p��)������P&�u�JJJ(������{�!55��7��
OOODEE
�WH�p|�����@LL���}��1����u�W�Bhkk�WH�p|E__���F��D�[f��q8w����2��w�Y `4b� ~�����3fN�<	777dee!,,�������o��9s�@[[�7o�Dhh(�����+V����455!������P466BWWo���L��;���W_����|>�]����P���BWWk����������E}}=��;��~�-<==���������x�"BCC���
===)�������B������?������(?{�,BBB�f�a``�/��...`�XC�9^ IDAT����'O�DHH���```��[������j|��wX�z5�����_Gzz:��9555���c��M�����N�����544`ee��>��mjiiAxx8���d���hhhh`�����q#lll �������p\�t��kjjb��qx�����r�����+W�����}��!44111�r������Axx8�������]��Dx��������MMM�����S�N��+`ff�H���R���!++ZZZ������W�&������)�3f�@@@%///�����x����\��#zihh !!�&M"�G�}�s��� ����He
	�B���!,,��������utt0z�h\�v
����?���FPP�~��<yzz��o����/����O�>����L�0�}��Cxx� _QVV���@������7�|Ghh��noo?d_q��]���`��)�{��J���>8������b��q(,,��PXX(5*��g���������<bF��+&�`K2�������|�X,�;��������?��Os8�5
����������\\2����.����z���'{:N6C���===888��������Fuu5���q%%%���������066�����,�����{���Eb�WVV��1cPTT���X[[�gyGG������kkk���666R�w���r��w������H����������������
��������akkK��PPP�RCCC�kkkCWW������,,,�g���@CC���������G�&fq%��F�'O���������344��BAA���h���ZF��XI��I��{n����d����=��b��066�@ @~~>-
�5je(����|�H�JJJ2}�@544��/�W�C��0��U�����y3\]]���Bd<�������������8qNNN/��1"���@���K�,�P(Dhh(jjj0w�\466�������]���,X�<��755���
ZZZ(++CPP���������V477��O�>���-���q��=8pK�,��G����N������?�@�����������n�3***(..F`` ������o���L����~����-[���B�x<���CII�����a��=z4�/_���L��b899��f����l|��wpuu��U����6�M��"�Dx�/���	& ((nnnx��7���%%%8::B("==�v���x������UUU�;<)))

����L>y�d��1���PWW���������������===���---���������������������666������Wq��yL�:D_2��Ekk+.^�������*���q��������������'O���4��1666�{�.-755���)���\��5&&&(//'���xQQf����2b4��c�xxx����8w$%%=�����{n��utt���C������uuu8}�4��������������PYY���F�_�u���Id5��7oFEE�L��g����B|���C�yyyD��@_������L����wXSw���!	;$@����TE�V��ZWnk�S�Ok�����e���U+�([QQ���I���
�^a���H~p��#;@+��y_W�h_`�a��9�����@��C&����r�}���G��
www��=��}������W,Z���]s�������7n@GG6l���!������O���c�y�&V�^���A���5�6�����B(���f�����,�:u
?~<�_����|�����2e
222T���0DFFb��1�x�"����t�RL�4	���8u��Rpww��S� 
���///��{���*�P(��b����x�b������/^`���������=�G���F�a��
puu���%�������b������#W�����Y%��};y����ZZZ

�=[������[�n��_�X�����	�6m�����]]]����?�@�S��l�ccchjj"44/_�$g���>�L)��q#���E�d2�8z�(�����'���L&��MMM����1.���vuu��~:����P�����������������r�Jtvv��"���p������W�\��q��t�R477#**J-^UU���|���������<yR)����K~��P����F�!&&���d��0aB�k�4_�|�Z�A'^�GDD���iiiHJJ��3��{����T)/,,�����z����zzzryCC455n:P��B!tuu�u{���F��U���8}����AU_��������}���W���Sn_1b�tuuI����+\\\��_}�U���M�6�����}�i4Z����~�M���u���������������;������������O��]��J�P�u�`f��}(**����1w�\��;\.<l6���;._�����9`dd������;wp��U�����6�
[[[�\[[��_G||<��v���`�X������Q�cccQVV���7�>A����m��ASS�/_FBB9�����C��<>>�|"���mmm8::��` 66V���<~��u��lr�OSS...��h8s�n�����t0����D�������%�������L� ��s'�����c���hkk���'q��=��@e���:::ppp@SS��������J���C���;;;�������HII!g�!����9Nr��Ydee�������t� hll$=���8�bmm
�@��������p8����8�<�������
���j�����������������	��������GGGc����	*TYv���I�&���Kd�����Um��---��
����9�\.������j�9`ff��[YY������X�n�'bbbPXX>�/�Evxx8�={kkk��|o��#G���+++��DU|��}`0�����&�'		�9APQQMMM�}���"!!�_}�7m������fc��m2}Ett4�b1��Y����B^�����������_}���W>|s��}mO�����y777������'�`���
�BS�2P��4'''rg<�hhh@zz:�L�\��2nmm���Z������������-***�����u��	���|��� ##���rg	nnn.w60??_%���T8����W4����*���H$���;�������<����xO����O�:�91�gjj�'O����T�l�2N8�<y�P(��������J�Y��p����'O����N�s@'�������_ys��8�FCzz:�?.wnX�,�T�����J����E\����N�'O����C�s@'zU�������Lm&���ann����*���.����W����add������ ����������W�x<�}EQQ���IU�1�}�~���������v�/�
��N�����g����!JKKaee.�K:jkk1w�\������J�9�����/x������P���Z��2N�[�h������(�P�E"����i�&�'rss1b����������Ann.Z[[ef����t�R�����
433S�W�X�{����
�������U�7n���1b������@���h�?���FHz����
>>>�u����@y���;|�0���1g���{Wf6P�9����	ooo����8�8{�,���0d�������>�}�����(**"��="�����x�"�\����z#F�@ZZ��s@���Abb"�~�m����u��III�2e
������'37���#������<y2u��
�A�;v&O�L�SS�^�E\����#YYY�>}:X,���d���@ ����QVV�����-lll������
��W�;::*|�_>l�0������9���+<}�Ta�������Q�P�� xggg���{���F���\.4
�O��b��l�}�@�����~�z���C���'����������c��e����������*��Poy
�R?�E:&M���7o��9 �{���}qHsr������[b6���F�����'y��?�����AOOO�l�*�d2:���A��H���$q�t:3g�T:H|�*N4	�������C�l��������K�)���\�vM��������C:z::::z���}u�����j;�����
*�#"������aY;�
_�P(����'OOO��s@�?|�����	&��-����R�������}�+N����W�����+���p��Y�����T�w[���Wtuu�����}���W�����?-���p��dgg#//�����!�����K����@R2J��`M,��"�H������pwwGRR���QPP�C:�l6:;;q��=���A ���/_�w�y,����u����P]]
CCC�9��`������EGG��������e���3f�@ee% $$_�5���Z�+&�
K�+��G
�@�o���V��=�������������W|��y���Uq�E:lmm����+V //p������������X,Fii)"""p��u�����������x�����p$&&��b��E|��	}�eN�U�V�i�9��FAA���[,X����
*T�����>n���1c���#88�W�AW�6(��t
�������?Fxx8233�f��r������w��	�@�������};v,���k��1@�q���z���)�{_��������"??{��Ebb"`��������q���aaa�W�����}Evv6.\������z�j���O�{�.���0y�d�����C�)�R���C9q�'�/^�@JJ
444�:���z���uuux��1������N���J����d�W�������_�}�=�
��W��777�����������}���#V���S@zNT___�����T��}}}������R%��.s��u�ycc#�sI�
����v��6(���e���
�)))*yWW������_���a�����J������R�wd_�����Pg3�`NGG�l6f��������+==�]*�C9a<�����aaa(--��Y�������j��P(���s���������8^�|�y�����uuuJy}}��S�����@SS�Jnff���h|���yyy���~�����G��������g��� ����I:����Q�F!00P�}������Z��qu���c��EJJ
����Gll,6l���A��o�����t\�v�\7������T����W1q�D�1���J���auv���}�ennn�'O�`������
�A�;v�����
#kq�_�� ��[�q����b�@NN�O��\SSO�>Euu5yDY����y�-[����Pi��w�iii������W<~���o��+455�������v0�L�����;<<<��W���c���}�+��9�N_!�h����Ap��i,Z�H���v�����7A�P�PCk�0x��!�B!���0w�\��5YYY�vH����^9�91[���4
�26^�������x��Qj�#V�]]]��G��o��]��b@�I�u�V����8x� �����G��o��E�}�����U�#V��L��S ++����l`` ���,���

��s@�����%s�}�e^SS��������
*mh4bbb���I��	&��WB���W��/��uH���B���[�w[�`0cnhh���&y
��\(BWW����[^[[����<�����
��
777R��������+v��)�� ��=���
�}�W_}���b��M011�s_ApU�e}�o��&����������W9"����S�N��/�|EWF���P'a������"<�s�����s��r����f���������hii!�FFFjq}}}��sW�^E{{;�`�����U����q��u���C,���>��<66eee��y3�������m��������������j�#V�{:z�+��G<l�0�>}Zb����;����o��V�}�����c��:T�>bU����'9{�,�����������O466���g��EFF�, N�X[[C  &&��U���p8�����{����>�2'�U����NP�2��k�.L�4	�.]"k���_�j�<nii�VmP������r������8TWW��333����
uuuHNNV�� &&������r_d������g������@?r����n:P������p�AO"s�������
�U}EBBB��
�o����}����m�d����h��b�Y�@�	�A�������_}���S��
����8|��k����``��puuU�����+W����)�-[����
���4'''r�1�hhh@zz:�L�\��2nmm���Z������������-***�����u��}��r_�����qE�����H$����>��s_��}��p�)����B�]�L&��UUU2��===�]���e�?��	��]��E�
��]]]��������STq�)���ttt(t(�D��*666������D�|>����T���r������3����TqbDY��w�=y_�
�'��(**��7��;������u������{�a����8q"���[�8q��?�-[<z�G����BE"TG;#�1�|hii����022������p��	tvv�_�������p�����G����6��_���\\�x,<���*�/��.��Y�f!55.\��e�`jj����������g233q��2�/�������,[�G�/_�7o���3g�t�R���!--
{������1a������F\\����t�R0�L<~��v����&N����?'O���%Kt��}����:u*&O��3g�H��a2�HOOGLL-ZD�����3f����cq��e�91����gc����s�H��2N��EGG����������;;;��9S%onnF||<.]���B,�����\]]Mr����D2������q��%��s>>>022��[�`mm���z


*�����#,]�����q�,--1v�X�����srr�r�J��b$$$����F�Buu5��=������=�
*��H$BRR�D�����UmP���
�xyy9N�:���2�����]���	F���\�~=R������8u�y����"��4��s���%�ommEnn.����_����}���b���HLL�s_A���qqqr�
777�c$�����+�����W������O`2�����q��]>b�������|��
���R?�E:&M���7o��9 �{���}qHsr������[�}����j�#V������G��3�L���������I�~�t:f����>be\,���X���P��X����p
<y���]�����b������������^;�y_�=���w�v�����|��P�28"�����
6��������>�Jz����^9����QXX(q�i��!077��Y�P\\���r>...����������{{{�������	����zF>����\������G����=RRR`bb[[[ddd������J��1c���QXX���XYY�����'�?.�KJJ�SD�-['''��e}���,,,��W�p5��������Wxyy�����[YY��� �`���������a��
����hkk��j�@EKK�����U�p��I�����������������q*T:4�?��?,���������x��jjj���777���@GG"�O�>Err2�B�Z|���ppp���6D"���������f������])3f���������.��� 99/^����.<==Ur6�J�f IDAT�������BBB���_c������bb����b�}�������o�j�*���9p��}��������?�r�*�b�H����-����b�
���8���0\�p�����(--EDD�_�}}}xzz���<��U���D�X,�9��O�0����	�j��>�2g��(((���~���ZA�
�������71f��v��6(���e����Ntuu����Gff&�l�R��p������x�����;q��)�����f�.####tuu!))	���((( m�3g���Fgg'������0p8�e������`�X�����[����j�.#e|��i���EGG�������.��|���&O�h4���COOOi�0�����vDDD�������w/[�nEtt4��'���������}�+���q����?*T����N�������c���H$"�������_����p�@ ��#��4
�����EEE*�H$�9*���6�
ggg��@kkk��HpMMM��� ??


���%��W�2�4�/_�\f6P�����Gjj*��� 3;HpyO�555������
xyyI��ikk���\.&M�$1����333�����O�.1���###����-���+��������`�XHII���-|||$�l6���HMM���C����r;;;��aCCC��t�����7�P���666�H$Bjj*���`oo��?�T�P|�����kGok�<�nmP����=�\./_�DJJ�J>a��x<�z�������?���N����---���������HII������=]Ex��RRR0}�t8::��=]EVVV(//Gnn.���#�Ko�!��o�}������"??_�^���amm��������b��}�+�.�	y��9���ann.���Be��z@0cnn���Hxzz���-������7��MMM`�X���?��===������`2�����������022���;�������3ZZZ*yqq1�]��������(--��1c�`0T��O����K>|8���p��9c��� �+**���(�u���?q��1,]����ADD�/_���.��s?���J�r�J6W�^���������/_���

R���������o�������Gkk+�^����h����n��
+++����hii�i��={���/��w�Ecc#���p��e|���033��7`aa�)S�@(�����]���'$$���'N��g�p�����b��u���jqkkk�;������O�a��|�W�\��U���R�BepD,���{X�d	Y;z[�quk�2N�W���0j�(������7nD}}�R^]]�{���x:;;�i�&���#66o�����p��q��������000����"����W_}���|�8�����-���q��!c��mx��	��=�U�V)�k����������~��|,^�III��3=��c������g\]]�v�Z��uQQQ���'_x*��=���;1a��?�.]Bxx8��������0s�L���[8s�BBBMMM$%%����o���/&N����P��z����������to���}{����K������}�o���������}1x���mJJJt� �=
��m��a���hoo�F���7������T��P�x***�����O�����2$������b	.�@��������<��b��y��UUU����X,FYYz��B!���I1���Wexkk���
�H��{������9��������'O����������1|�p�|����p8`2����B[[����w�^�5
���S���_����BKKAAA����G}��30DFF���yyy2�D���H������HL�0~~~���@DD"""PWW���F���������e�������h�<<<���Fee%0m�4|��hii!}�xxx8***�������f�����QWWG�+��{3C��?54
����N'k��3zU�q___�j�2^UU���H���C  --
����7of�����J�\ ��~���|>~�!����#�'N����IW���SQ\\���`���b��q�~�:***�d�L�4	999W��3.\@cc#V�\�q��!--
aaa*yHH<<<���N�^�6lBCCe������911'O����&>��c�9|>'N�����

R�8###�_�...077���������o�J����q�F:l6���������Urgggl��666���DPP\\\���D���1z�h���u�V8;;��/��W_���������}��bq��
i���\�x?��#������h���|>���puuEll,���DDD�%S�B�z@@e�3|�p��=.\�K��2o�<�1��������a������@������U|��!�E�����F����~J�W�mll �����N�8:�OOO�]����jq@pp0Z[[e����������`2��0a���aee�X___DGG���#�����o��+V���\-�x�b�:u
���������B$��CCCq��A��l��5.�������K���&*T��hhh���Q�v��6(���e�����-Cdd$���CCC��7s��������T�i��!;;[��y<�����p����`ll,��p8X�b������?���K�,!��IFU<88�n����V�\��'BOO�������2~��1������a���;v,ttt0i�$����[�l��>������=>��cxxx@SSS�L�������
[[[����������+�88~�8��;���q#960g���N�<	�|���������v��MMM�����$

B{{;�p�8������}�+���B�:��%��n��8�����@�������������@��R�2�y���PyM#����D���`hh���4�������W\[[,������"-��p�hkk###555033�����\WWL&hjj������$
�033�����zzz���,466����\�����GGG����������~��okkCNN^�x+++p�\��X,���</I��?!=kGok�2��6(�t:,������EGG���$�������J8��$�N����B!��� �`mmM:�t:8jjjPPP�kkk��.���@AAlmm�z�`0`hh��������ZZZ����������d���/PRR===��|��������S��,|>��
�d2��r����6���'_�2�L��� 33%%%044T�{��kjj���EEEr��<55�����?�}�~��{������)&N�(��^^^���y��H����������"�H������O�����",,_|�������\������}������3���t��������F�I������&M��e�p��5��b�81�w��!x{{c����q�4440|�p�������S1e�$&&��d���E%'�111�1c�|>�����g�>|���db��7n���8::���111�����Y�0r�H<|�,vvv
�8w��R~��)��w�g����=RRR��p`kk�g������*��G���{����O�<���1x<***���4������������@��Q�BE*;v��X,���s��all������S�q�@���0`��`�X������),,,T���"9r���X�n��9���,Z�EEE8v���������F�!??VVV055EQQ~����������?Gqq1lll`ll���|�����X�d	������� ;;�\GG��/GQQ���1t�P�����{�b�$xff&������|�
���{���B(���:::HMM��?�sss�\��|@��?z�MMM>|8455���#����������777c������HJJ�7�|777�^��n���/����6�5��^n��
|>"���7oB,CGG��m�[o��5k� ..5j���/_�������W:ts������T����?�$O���s�p��EL�<K�,�����d���J��j��
��N�|�t6�F���E"���?Jg	N<���
��hJg{r�X,�HMM���QRR�9@�I�[��4��s@���3Gm��4oiiy�?D�
6���}T���H��c�b��u��?���������W�������9 ����P^^.#����C\\�\������������������#�:��>�ppp�� �ohh��>/\����J�<O)733S�066V�>@�s@WWW��@WW���I����;N�:%q�eee$'�4
AAA�����+:;;abb�������+������?��5~���zK�c��7jE2�A�*��S����"00ZZZrg�b�J~��hkk��
��8z��RN����
�Djq�%�(++#�`�r���D":t,�����s **
����$��g��!37A����+���s�aaa������r�������z�b1)��B�u���.\KKK�v�8q�W�AW�6(����r�!!!��{�Jnnn�I�&���K�����]�v���\�9t��|���r�;w�����B�@O.�

��������:���s���#�r�
lmm�:	n��-�}���#��Fll,�|�\��"N8:�������u(�8x� ���:��������|����)s�����9s�\g������WBGG��}������W��������#  w�����a``�c����g�6��LA��� �Be��d2ahh���L(�
T�322P\\�p6P���Dii���@�xee��S@zFT[[[�����9h4������3����pWW233Q__���~��%������$w��'�H��
�8x� ��[��������3q�DTUU
��R�����D��mm����
������:Z[[���������Lhoo�q���Q�K;���������.���S������������������rdgg��d�����!�%%%�������\��"N8
���
}}}��e�������������P�322���#���P(�	'A�����~��O_!���u����b�0y�d�h4�8q\.EEE����a��a��-���__�"T�Y��0����i��={0b�rvo���HHH��
������O�6
�����[���N�:U)�1c�N���w���
�6m�J>a�<x��t
���������a�n��;w`ggG:���p��9��9���CRR��s !!���.F����d���?�����>�����C�"55U%755��~��	���ddd�����?���S_[A}}=�|�M�>}���HIIAjj��?������y�@_2*je��pss��#�������� �/X�@����s8����8�>}�����@)g2����FMM
>��c�s��?��u�@��QPP �8v��={�>�t:O�>�q
<����hkkCII�J>t�P	�����,Y���:TTT�8������s��fc��ex�����@ ����A�e���������%V�\���l��E�p
899���O��@��};����z�j$&&�u(�_}��~�m�Y�W�\AGG����������v�������t��m��a��)��+����`��>��s�N�����B,Z�������hx���1}�t��9�w�&O�<{���?�[o��y�����|>���|�T�t�1�Be"��w�^xyy���X��q�Z��������G��30�)���'�����H�9��Y�������^9�yxxx����������������&G����%6n������=�(�Q]]M6�T����h8w��t:Y;f���/_	1v�_IO^UU�+��4���d�-����~(�9 �$��s@��HKKS�$ �"���a��:	

e�����8y���S���+uH�H8����:���N6���9 ��t
hjj"((...2��;;;c���

"��p|�����+>��s��� �X,�s_q�����h������.��������4@WD���P�P�ttt�����G��2@�������G�����=����*�����������ps���������xv�<44�O���}��srssq��
�(���x�WpET��5�������D��mmP���
����1�-[���H�y �9��O�6
�������`llL:g������`����?�333��U<88�n�����\�@XX�R~��1�������u���J�-[��|��������^�s������_akk������u?~���S��s;v'O�T�$���9v��!3�F��I���v���������k_A�����*T^}��>*T b��W����}�����	�@FF���dt:��B�P�Y@�0���\�9���w����~�w�khh�<y�����������
��>=kGok�2��6(��S�����������P�uuu!�%��x1I8�B!��� �d�555(((�F��P�+**PPP�!�9��������ZZZr��\���{S����\����OQTT���X,�����\��<�@ff&JJJ`hh���s
�|�{rb�K�I0�}�~�T�P�P'�P�tvv������ ����@68L&Dtt�Z\$���eee��k���#�S���� 
QYY	===�������CPP�\�J������:TWWC__���x����=WTT ..�V����n��
+++����hll������������l��q�2e
�B�J~��<~�k����@BB���0q�D<{�L-������_hoo��+W��r1v�XTTT **J)�������&��
Crr2F���c���T���D"$%%I�[[�^�E\����������
���G}}=.]�###�5J%/**��+Wd^<k���p��q������>CYYbcc��p��o���G��������������000��������l6[�lAjj*��=�U�V������8t��Jnmm�%K����{������,,,��������py����7���{������?�������={����k��EBB�R~��%���#  ���x��v���1c�����Fll�J���hjj"))	�}��L�oooDEE�����X�z5�n��������%WbG���w���c���'�{������///r\f���*9�8z�(|}}1r�H����8}�4|||��W�^��S��l�2��������������I��".��*T^M�T�@h4���I!
�F�����\������+�066�8�naa�6���011���	��zJ2Uq�333�����QVV&q�%%%���'�$��uH���2�������]�������x�������������~���x���+�2*T��H��c�b��u��?���������W�������9 ����P^^&�)q�yyy������v��9�����a��q9r�R��"��G���r��������Y�p!�:x<�Rnff��9`ll��>|�|�����R'���.~���Nwww�:uJ�~���HN8h4���@���:h4�R'AOnbb"���9 ���4M���'okk��/?*T��*===������y�/�o����b�
����r%�>>>�D8t�X,�y��@TT8�#�I����1�O��{���2�r������Vl����m����o�	KKK����k��� IDAT��2�P�������aiiI��'N��6����e���T�s $$�w�V����1i�$\�tI��;;;�k�.����8���y�/_�\�S`������T�����AAA�~�:x<�\��4�v9rW�\����\'����e��zzz�S�����������P�	���C�{{{��e���DWW�B��2���������`�/�333e�7113g���,��?����:�b1Ur���X��G�B[[[%����q�D"��!�I@����;*�s(*T^I���%��� 33���r�4
YYYx���Z�/��{���2ojj�H�n������BCC�g�,]��'O��o�-�����k��������D��mm����
������:Z[[���������Lhoo�q���Q�K;���������.���S������������������rdgg��d���Fnll������@GGG�s@'�����������\��2nbb���\�������u������q
��P(���� 33
�����b�������<����233QZZ��S�P�2p����_�EP���?���<������aaa���/����������_�����h8;;���
�g��Z��l�i)//�������>Q@8\\\�������={>>>�8q"n��
mmm8::����N�B||<|}}1j�(���oJ���w�b�`gg���*������X�d	����������eee8q�222�l�2XXX 99���
���i�����e���}���7Q\\�%K�`��������g������Eaa�\�8*�1;v�����|�M�v��{�W�A_�b�Z�Ag��HII���	x<����@�+V��b)�t:���
�����t�����`�����hHOO'������_~ACCV�Z����LX[[��������?���������V�����C����!����g����b������Faa!����r %%;w����9>��#���������s��!_��7��e����������k��Ejj*�����o@WW���J������������Op��=<{�#G�����Z|����<y2��[�k��A(���t:w�����[���7�����������&p8<x��\1{��M"??MMM3f���[���/�p�B���#66/^����:;;����������W�}}}q��ettt���
mmm�|�28����>P�	?��#������X�8q���>f������<77.�����*T��1�B��+���)N�:���z��b�<y�f�����A��������(������qqq�3g|||���:���wvv"""��������;w0o�<,X�������2���R 99�-����������(����3�%�W�\.6m����7��������+�B��	�FCll,h4Y;-Z��� �/\�P��������3�EEEHKKCNN|}}1m�4TWW+�������o���.q����X�bJKK�'N��������Q^^N�*--��#Gp��q�7����3`���(,,����U�c��a���8�<�����nnn

R��=���G#""���X�f
F�	GGG���>"			������>��c66668t�������@�|��}������~��C������,��g�J>r�H�������-X,���9r$���k�|��	��q#,,,�d2�{�n888���noo������@w]���/1a�|��g066��D`` :;;�����7�`��IX�~�J�f��`0���6�I�����?�,K%����������a����������B~�����P�BE�P'a���P'���	������@VVf���+V���������Acc#"##QTT�9s�`���011��R����Q]]���(TUUa��yX�h����f������8y�$����h�"���{022�����5�B�q����'�?;;;����RZZJ��R�2��k�.��?���#k���o�j�"�NmP�������������O���
����1c8�J��r������O>�}����|��\.x<�<y�3g��F�a���x��w```.�KKK$''�������!�,������R�CCC������zzz077���%�����������������5k���XZZ�����_��7o�����%N����1\]]���+++XXX���K�������R>l�0|���pqq���&���aaa���\�xQ-����c���`02d������8��������R���_���t:|>���		�Y�@�	���ann�������K��kkk0�L2'N����7��<O%�����!C������P���|�oii�'�������b������ttt����c����	*T ���
*�$x��rrr���===��`&����V�������`�X�uycc#


�����lrnW].
���S�|������KCCC)����u���s1y�d����+���AVVv���
��
����������AW�6��L&555(**B{{;

Ig�:��`���#��_YY���ttt����t
������������	����j���b���C,����t���>}���J�z����ry����4�|��v0�L������Z%�������N'9��@vv6jjj�������~FF����`0T��/��L&������#xjj*����d2e>�3ihh���x<^��H$BFF��6�����Bss3tuuI��:��J�
F��2�B= �B��+IYY�����'�����n�����t��>}�4�a�,Z�			�|�2��S'�xdd$RSS����c���r�
n�����R��G4��W��{�����0������~=_u�!qqq��i�@_*jG$!))I�v��6(���e������������[1r�H\�p>T��������2/�B!�����m�����g��Ejj*���ghkkc���033Ctt4������jq333|��w���Edd$�>}
HOO��}�Tr������BXX���)))���\��p���hll����Q[[HNN�?����K%///���G���x�����;L�<{��Q����/�����w���������}������<x���[�n�������7���e���+W�������#��	���]�����~�III8z��Z�p
��?�W_}�{��!44Tm~��EDFFb���X�~=�u�---J��"�����B ��{*�W(*T^IJJJ�������&�$�v
P���}qHs������u ��{�M���i7n***$�)�Be�F$���w�QQ]�
����h�� ����[�%�5&F)b7F����bQG(�D����I��_��P)�K(CG����5�13w��s�Z��<s!��=��7������U{%��Gyy�K�J:����j����o����yE\@ff&��9��mtl
����R����������� �9 �b��!���dm�_]]-�}�2e
lll�6LMM�zccc���~��]�����R�����Z�������o~~>������Pfy�hs���Hmt�&&&bMR��^�9@j�������<y+W�|��'����|>���BwoP(
�P������?�P�0��?&&&&��G�!3g�T���<3f� qqq�����$--Mqz���}����0�����:����Bioo'eee$""�����1c�.�Kx<����HXXqss#�����:D*++���G�m�F\]]��I�������B���HVV��aquu%S�N%G���IRRR���7D{{;9r��;w.�����q���HtttHCC���K�����6y��!����6H��\���3g�S�N��������5k���������[����xCBB��!C��9RWW�|~jj*Y�t)�/_�L�>}J!��������E�WWW������>�O���C���G\]]���s��?�,�7551���[���������>����uK���������y�Huu5imm%7n� S�N%���d�����������B��?��37nqqq!~~~$55���|���+W��#���	$������]n��w�777���B�/_N����������#��D���/�����|www��W_���B�744��g���===��
Hqq1������'����m#%%%����$����������{R���!����HW����7@������=qppz���"��7ccc���N455���	�y�����@� �P(�����Xs���077gm
�
�����l��������555�������dggCGG�u]qG/��;��������L�2�f�S(��W�6�yy�
����ks���R.obb�=z�=���&��������9��������@ii)rss����hS���yyy���dm�z��@AA���`gg��w��"X�������22��9 ����0w�����6�yUUUddd���HlH�***x��1ttt�����k}}=ks@�D���gm
())���7��!���022����|>055�����TCCC���������@GV�^
����~~EE������XXX���R(rC
�S(//j$%%������U�������y�&��Y��m�pJJ
��[��S���E�
���a���5j��������S������FRR����{��������(--Eii)233q��)3�p
�;@a���k��^����i�����9P]]��7������q�������-[`mm-����D[[��������mLLL���M��}�b�����am�z��������@am&D4<<<�w�^����6$yAS`��	�r�����������JlH������E�p��!���('N��&���?���$6���6m�����5N�<�e��a���R�`R�+cdd777���.`���'����<y������0)���O�Q(��###�����~���'3M>�/�9���,����W^W��{���������>��D||<�^�
ggg�c***066��nmm�i��a��e8|����J�������a�^^^��+�9s&>������t�<�������[�ne�`
�������Y��M���(�����l�M���prr��$xI��&��������������������{��j
Im���M]]]��6��)����D������.Dhh(�f��U�`hhUUU��i^OO***R��|[[�������D����z/o[[[�6��d�,���amm���t�����!R(/� �P(�B�~�0z�h=z����<y2���###B���
�������M��O>��z���������S�������W���

����CDD

���{��	}}}��;'O���� wW����&�����=cn/�x�`i���QRR�������E�
��<�Y~�����������1|||��@OOzzz2�|��
=��}�BOO���X�`����~��a���;v,tuu�����������{7�y�|��g9r$������(����okkk|��6l455���???DGGK�\.W�\��A����WWW���c������H!�j�*�����;���������������DDD���Kptt������l�2���AYY#G����IIIpqq��W�\	+++p8�;���:T����/�e�8��u��v1PRRb|hh(�;�L.�
L�4�_SS��_^?m�4��C�����'��e���3qqq����p�BfY�4����ornhh��J������t���e�
�SPRRBcc#���annmmm�&��g��6dy�^��
����$/��\��ai�m_����G���{�b��
B���
��� �3y�k�$/��A�4rss�������[�vD��D��%%%������1k�������033cm��yyy(..���ks@����AII	���hs@��]�<x�H����?������%��w����w�������l�����X�������7ks@�ooo�����O���,�����������9 �wgLMMq��=����<���FXXX'��B���==G�P�
EEE�t��,Y����kBM���D��qCh�r���4�*{����e^TT���0VWWGii)��;.����6L�4	;w���;w��MLLd&w(��N{{;n��-t�x�k�$/��A�4***���_c��!��I���'�p���AUU�###����
6���R�Ip��hhh`��M066fm��������ks@����FHH���X������}��������������9��g����
5	:6,X�����6��)�������KlH�.\��'�����6$y������	��'����H�q			HNN���a'��B�
���B�t
���X�l��p8BM����Q��{�w���K�e.(Zwg�������?hkk���#F��)S�`�����Oagg��~�	)))���W��)�hoo��q�����\;^�Wr��q����T���OMM}�����}�6***�ne�����3gX��M��M�w�}Wjs@�������;�6$���@2�����A�@�����������g&������P(++�68��&AGobb"� �9 �E��6	:���F�������3�N�
'''���`���033���&jjj���C�:u
�/_�/�����R(���6��7���5���?=�7�������	���#G���38�7��3H\\����1IKKS���0�o�&666�����#C�%eee���{����������F��C�\.��x�/**"aaa�����?^�����e�2�:u*qtt$III�s�������I���	HUU!����RbggG0oQQQ
)�"?���������];^�� ��sm��g��IN�:Ejjj���F��Y#����"[�n%NNN��
		!C�a��s�H]]�����d�����|�2y��)!�>�O���O-ZD\]]��,�ohh`��;w��y����+�;w.����e���&���u�xyyWWW��g��[�n�ySSS����3�s��F��?OF���D�������I~~>������w�777���N���+RXX����r��Y����'��a)..f|]]9q���~��m��������$66�������{O�744$�����;�
����x{{�������A�R�$t��B�TTT��������@ee%kS@�n���Z����yMM�\^�^����R�2����{6�b��a�|�2~���nll�?�������������R(/��^����i���g�����J�|cc#z��!�x���������F����c<[S������hii���6���������V����m //mmm�^p'�?���z�����
�������6���������MB�����l�>�����x<�^t������&N�>����3������������B�R�$t��B�t
���B����$|��wX�j|}}Y�7o���5k���#���^����e>j�(���t���Ltuu�j�*<x��OW�p(��������/zm`��^�y��@uu56n�(�[[[���bO�!��e��������hkkc<[S@[[��m����\^�)��o_���:::��Q/����CXX!�M���?��'
5��5	���&�9 ���i���@``�\��9p��I,[��W�������\����f IDATv
555���E~~>amm���Q(�t���(J��O�>������
��S�N���>>>�p8PQQ���GQPP�g�������3g>��C���B[[[�?y�$>���������~��y�0m�4444 11Q����Aff&����������c���������'��3g�(��������%��Yjj*����m�(�������g����\;,X�B�6?}�t��
�|UU�=���h���!99yyy����1f�TVVJ�eee��q#ZZZ����
,X������"**
����[�PUU��b��())ADD<�4�|>���������DEE��������������@899��������www;v&&&��A�������p1����}XZZb����a����U�Va���X�jsW��]�PWWkkkl���g�F``�L����=z 22UUU����������E�AKKK�WSScz�������G}����CUU����������V������������?��.�"�7P��
��� �G|||H\\:t(1b���Z�[VVF"##���;3f���a�������Ixx8y��w��	H||<�nW^B\]]��)SHbb"�n�������K�����
���v���O8���c���O����7�O>��477+h������K�o�.t�x�k�4/�� ��������q�F���Bf��I��?O������������y�!!!d��E����$k��%�������|������g���1Y�|9qrr"s��!��]c��z___���(�hkk#)))2���~JL-ZD����\c�|>y����www�G7&O�L���������!jjjDUU�hjj�=z===�M����^�kii�����~)���DN�8�������������hkk����q���d��	����
!�����B�t<O�<������9��!�����������p�u�����v��� //���PVVf�������PTT��'-x������M����>}}�������DG����i�&<x�AAAW�H)�G��^p�x�k�4/�� �+))�������abbuuu������|��AE��yyy(++c*�ZZZ�oiiAvv6x<�������4��YYY���Bss3tuu�%JJJhnn��322P[[���f���AMM
���@cc������;������c��i��c���066V�0^>��������;>|8������C�[XX��~@hh(���[��3G���P��
�S(,,DQQ�����wo�?�3g���p��q����X�~=444p�����c���(//����������7����.]����L����b�|~~>6o����j�;w=z����c����������)��/^���G�x�b�' �8;;���c(//g��JW��������������
��<�i>++��������m�PPP�3g�@GG#F������Yo��������������<~�			���������===����o�F||<4551x�`�����������\�zG�A`` ���������[�wttDPP��;���h,]������;w"�����=z���
+W�T�P�����DTw���B[[���L�q��Ub�}��W�3g� �t)��B�


�n�:�9<����
G�)��p������2����]7��_��+f�.Z7,��IZW��w�=�u���{�<���iiit���-hoo��3����3���6����R��
����Y�qqq�����$���o35��ddd����Ls��/���#������X���"--
�n�����E����gggDEE���CB�Y~��%prr���8�o��F�9���'�����GDDk�@����;���By���q��9�����
Cvv6,--;ad�(v��
� x��
�}d���B��~����d�����GGG�M���m���������%�+�����l�B,q]qG�����}�����Y��<z��
��By}@��o�����xCBB���qpp`mdff�+V0��)���G���%6D=[S���^js��mxyy�A�Il�����AAAd���
���������o��K�|�r���\�����������M�B�z�B�Ks���999���`m�x<���BMMM�g[7\VV���|�����E�
������@��������577GLL|}}������������FF��ZZZX�f
���=�7BVV�������x<��@kk+���P\\333��@aa!JJJ`ee%�m
��������=cm�z��@nn.��������$��/1�t}�|>�>}*q��B.\� �w/����	
��)���1!���*�:u
�.]����������9p��Ml�����2=�����TK\W,������
 $$D����>66V�����?>F����|�]�=z�;&11�Y/�����QR(/���2.\����+z(o�������[b��gks���BII��lM}}}���w�������5����k���6D��U������

��X�
8������c��8|�0��S����������uo���A'(J�`jj*�8u�|||�&Akk�������T���"u�����L�"�6��4hv��???���������TUUQYY��w����C���m�=\
�"x{{���D�9��IPRR�����777�M���ppp��$xI�+++�&Aaa��O1�"???|�������_|WWW�����?�@MM
�_��3g����)))�.�"� �P(�B��}1q�DDEEAUU>>>���O```Bf��
������6���///���S.���bcc����y��a����������\���	���011����1i�$����G��;w.N�<)��Otg|}}add��������B�������w�fn��P(]�������-Bll,���+++|��9r$���`ii���DEE!44�
��E����MMM8P.�w�^��???���B]]���X�l8 ����b���:t(0x�`���a���X�z5����<}BE��������S�����u�V������������s0`�"�H�H�NP(�N������'���fm���
�U.���_u/����������:2c��?7n�@rr2x<�����*zx
ETT��y'h��������I������l�x<477�6d���,TUU�����9 �gdd��������Q�6]s)o/�����[�p��$%%!99O�>���3��u��I\~@�(:A@�P:���B!((�{�����a``�4	�?�_�Uh�r���4�*{����e������S�������I�0i�$E�B���4!		am���COO�w�����Y��|�����W��6dyGGG���s��QO#���������p�BE�B�:A@�P:����[��ij�68��������;����^����hllT��}���|���/�u�LLL���CCCE�B�H!##��kxzz�5	:6����6$�%K����	vvvR����9`nn�������>��kc�������A�0�5�B�����O>�����������1m�4������SLS@__�{�����1j�(DEE1����)��gO����1\\\�L���&M������0w�\XYYa������4���4{yy���VVV���!���7n����{�����puu��{�=\
�"eee�����9r�P�@CC�������6�hmmEHH39 ����BKK�i
TVV"88��������z�j���b��M����oiiQ�)�P^�������"���B�t
l����J��������9������555���)PVV���|�����E����(((��$������O?����8x� s�w���7n`��	�t��������%K�����W��)�$���X����(**Bqq1���X����())����\^�)������R<{���9 �E����(//GCCk��.1�t���p��	dff������b�dee���T��P$C'(J�PVV�o���i�:u
�.]����������9p��Ml�����2=[S 55��������X�9PPP����M��>66V�����q�����������������h}��Q�x)�t������r�PRRb<[S@__�����;w�����BMsss���k��Q�j�*�����3���p���&�����O/�"���j8;;���@��o�.H��:A@�P:��������(..���2N�>
???xyy�%%%���#??


�������3f���ZZZR=��A\\���QVV�;w�����&MBcc#455e������#;;������cQ__��'OJ��~���O�+��p��x��1x<���`mm-t���-233���E������x<���p��A>����x�bxxx���a����r������+W����%K����#F��������1l�0�9s���X�x1����",,L�

������`cc���@���`���		�EEE�>��T:��}���/����scG!(++��0B
E2t��B�t
&&&�>}:������???x{{3����1p��������3g�����\������{����'O���6��������8t��������q��AKKZZZ�;w.H���}}}������������7�y����By	������	333 **
{��������	uuu���a����r���{7����x�b���AMM
����\~��]		��#�x�b8::BUUX�f
�������`l�����C`` lmm���kkk�_�!!!B�����>��T222p��Uhkk�<�_�~�0"
E~h��B�t
������ANN8�����hnnFvv6


@Acc#��_������,���3�u�_��gff�������]���3��mmaw���^h]�w�}?~��q�]
;u|
E~����y��pP[[����������ip8TWW#--
O�>ECC����%E����������PUU���*3���J����GhiiAmm-�������x�'�)��N�=������7<
���
�S�������+V��D\\���G��������|��������@ii�L��!���b��]�������q��9@aa�\���aaa�8q"��9���rrrp��A�����S���f��)��{��y�f\�~�3gsL~~>f����S�2�S(����<z�{�����
���;v�o�f��]���woDDD�������_�������666���o������H������Ol��M�wwwGtt4TTT��r���������7�y)�tu�������u���M2��B�P(�N���[�ne�p��qTTT@YYY�)���(--em�z���<y�����6�l�2�)��CNNks@�755u��|��9>�������:2���PSS��7�a�����E{{;����q�����L���P(,���#66�i�����������C����C���oPSS�������GGGp�\<xP�9 �wpp��������6$yAs`��		��={X�_YY��SL�He����������ajj*����W�e3�.� �P(�����Ps`��Ihkk������G,]�T�9����4��e���5Z[[��7������9 �E�---�r����bmt�FFF
;�����@���V�I����'N0�s8(�P�0�����k\\\����?�W�X!���{7BBB������lM��[�b���ry����
�q�FL�8��I���?+�S(���BII�D����`��!pvvF��}��D.++��MJ��NP(�N���5Z[[������XYY�6���P\\���)��������E����(++���	k�����
JJJb�BMMM0@A#�P(/J]]���PWW'����ENN���������Fmm�\^�)������ZTWW�6D�hs ++������bm���t���P��t�>��s�����OR}w�S�>��B������������t�v��	�>}:::���O�����7
\�tI�?�<���1k�,�)���#������Q.ohh�I�&1����bp�\������3�����<��SL�P(eeeDEE����8v�444����4	���uuu8991Mccc������ry===���2M[[[�[��}�"##�b�
�~��ux��w����a�0}�t|����r����/��`��BQ$����p8�5k���#vw�,�^�z�
��By9��B���g�2����O����i477Km())I����R�JJJ2����,��QE�b
�B���b���:t�Xs�c�`�����w��������&��Kj���Im������9k��6(]:III��u^��(�����B�t
&&&���O����Lx{{�G������30c�?~�y�?s�L������@���������#G�0O�'O�������8{�,&L����������={6ttt��W/x{{��w���C��'�������6���1w�\���"H�P�
������d�}�����{��OOO�/_�:::��{7�����
Ls@�'� $$�y����uuu�9 ����a��-�����-��������[R�����_��L�6�5��By}�	
���l9D��)���������p8���5	���������BX��|cc#���P\\>�/�����-@UU�����$���DYYZ[[Y����� �P(�%���	����Acc�X����iiix��)X������������z���,���#��������9 �)�����)���+�����1;u$55��*y��od|��B'(�}�6F���	O��	���q��Ec����������#G����"$$_|����� !!����������������������7o��c+**��C�PTT���0L�8g��a~y��|yy��<]
����x<`�***��?p��1��}���v�B�������#66��0�Y����|�
������ h�����������
�\.����i�z�V�JW����cff&6I`aa�;w�`��94�I�r�0}�t��������[�W(��Eaa!�n��4����L�@�)@js@GGc���Ni�^�����M�6a��-��r�
����e��1MR��������,
�By���+�pwwktl
8::JmH�8p����$/h0��9 �i����9}�4���


p8�����66m�� ((����B�
�g���`���
�f������!)�'O� ::!!!����m������I�0g����1M����)S���:u�������������t����5�.�+�I�����D�P(����:v����������***		����M���l��Ubs@��6JKK�q�F�M>���SL�H��������������|�%�qvvF{{;�����wP��9s&<==�z�j��C����
z��	���b��)���������o�>���K�.����_������#F�������OE
�����5Z[[������XYY�6���P\\1�����'O"**J��������{


���r���hnnk������&&&�M���N&Q(��B]]���PWW'����ENN���������Fmm�\^�)������ZTWW�6D�hs ++������bm�[����� IDAT)]���{��y���=����
�.���"6odd�'N���#�p8��};1�|��5�Yw�]IOO���.����l-s�����������~�/���s��������S������������t�v����k��6n�����P��?������'O��������W/�7UUU<}����bO��������5�����r1u�T�&AG_]]���aW������B����2������$���g�����066FLL,,,���M[[[9r�z�bm�z����a�555�&�`��B��477�}lff�\	JgA� �����>�������<<<���T�����	&(`���'O�`��a�������?7o�D��=���9s&���X[[w�P�*��g�2���A����Yjs@III�ggg�������#))	111�����-[���!��{{{���3�_;2f����Hm())I�G������;w.���+tG�B�:���b���:t�Xs�c�`�����w��������&��Kj���Im������9k��6(]sss������W�qyyyHHH��]�:id�l��?���/���Ojjjpuu���kg
��2h� �>}�G�f>���/69 `��ix��!� xE���///l��	***X�f
f��	MMM�������c�����W���)S�'�l���Uh����/�X�n���Y�2p�@��{���9s�������������+1z�h���A[[,����D��W�7t�^UUU())y��'� ;;�������J����i�X����;�����+W���
���033���k�g�c���X�|9����w�yG.��7b���X�l������KKKl��!!!R��
���_c��YX�t),,,����kw����W�)�P�2�|�1���X�v-z��!vLbb"���+��3���)]
:A�������HKK���0n�8E��bii���|�	�y�@{{���M)))3fL'������#%%���4hJJJ�����GJJ
�������'t�g�~���"&&[�ne�\������� 99���������e����EH��!�u��%|�����kUVV�����|-
��z<��p8())Arr2���34662�N����"$''������hnnf����K�������4b8�����***(//!D�����y
��3h� ���~~~��o�����_?������w��Eqq1��m��)z��t����tg���}�v�����������
���������&�:u
IIIX�j��G�������'O�o�>������������������7o���BII	'N����>��s����b�����������"�d]]]��o��+W�������c���GDDJJJ���"$$$@]]��OGVV���+������S�����`��Y������K����w�<==�^��=���c���L��B�t=����d����������������X�������Crr2���ajj�u�����+������*���p��]������c�$&&b��}X�f
�������c���2��Q����#::���

���%n�����_b�cL�B����������/����������?v��-������$�����k�.]��K��O�>PUUEpp0���%%%���C__��]���@aa!�����3g2����H�N�k��1�
��8q��7��������|mI��>�...

��'O���������G��>���0j�(<{�p��Q<y����������+%�	)
:IIIb����V�Bjj���6�b���<x��.�ByI�����7o���`��puu���<���H$''����000����1x�`���c��=�r�6l���{���e�0p�@XZZ"$$aaa�������aaa!�/]�������6n���;wb��a8|�0����|EE��O1�"3f�����q��
$''������b�)��]���r��9��=\.)))r��������/����
�P�x{{#==k�����-���>�+++f���A�=����2�mmm�?~~~������g������6m|||p��a��

���122Btt48 ����:�������>V�^���GC]]�7o<==�LH��������v���g��o�����'���x<xqqq�bI��OE[[�w�f&������###,Y����c��)���
|������EHH39 ����AUU���X�~=!��e39 �[XX@EEfff��u+jjj�a�fr@����)�S(r����I�&!(({���g�}F'(]z�[��g�p��9�;w��WG����Gc���<x0kEYY���������
v���t��;
}}}+z������


x��!JJJ�����x�����a`` �������+W��������?d���'��TUU����������	*++���?Fuu5�>}��$������������X]ZZ-Z$�k())a���HNN�G.O�P�555x��jjj��%%%HOOg<[S ==���������6222������r���4������L��������I�������B�P�I�;�R���`ii���,_�����p�V�\	'''����f�������_	ms8w�\�>}\.k��Ecc�	�m����������X\�x��i.^��l(h���o������+q��E&t<KN�6
~�!bbbp��U�>}k������~�zf)�(��������G�� ))	/^�9PZZ�����?DBB�T_UU�������M�;������JFEE���������X��y���ZZZ�������w�i
���!!!��?z������#abb�}��������4F����$hjj"44T�kiiu���P^�G��.m�u��������C}}}'��B����-�o��ppp���|||���_q��u���/�p���?��+��0pttD�^�����{��a���|8rq��9?~\�.	�mmm���0|�p���u�H��XZZ����Ls�����V����hll��hmm��a^E�C�AEEW�^E�^�PZZ�����n���k��c��8q���,,,���x�"~��WfY��q�����#�9 ����(���6lll����\/�q����?�FE�P^{{{�7���b���MWWW���Jl888Hm��������&��Kj�����I@_��tu�^���={�n��q'����-BBB����e�?�o)�������X�^�0{�l8p���(++��3g�>}����X�j�������`��]pppP��x1�*V�X�!C��%���,t�DG:.��3g���;y�oI����
\.���>�������76,^�IIIB��&��i�0o�<$$$�5M��O�SRRp��Y�;C�����n�:\�x���8}�40e����0�gcc�L�?���'���0z�h���HlH����o��u��O���+����K<�������p8B�E(J��W�^B�+++�����I���_�����������&�o�.�9 ����b��������)o��
��a�p��}E�Ba�w��p8���O�1�{�������<�������_p��}���c���R�e]	���m������������5jF��Q�F�������;w.������
,Y�G�}k���1118t�����vL�<?�����������x�9s?��#���_�8�|>RRR����A����D����#%%������gm4551�jjjhmm��@���:���1{�l���g�����������B[���� 99��������i��G��������c����������affMMM�������8{�,���������R()~�	����hll��g���EEEHNNFkk+jkkY���`�WUUks@������r�����P������w����S�C�P�����}�>��#E���'.��WWW�;^^^?~<����077Gqq1��������x,^�w��a}��*������'��oz�����Hhjjb�����x������7��r����'N@CC��9�$077g&����m��a��m�Meee�����?DII	�Xw�����:���������@II	"##QTT������c���Ls@��;��Y�p!����v�Z�x��A�SSS��B����z$hhjj"66���;bcc������{������)��[�+W� 22���pssc�������c�$&&b��}X�f
������,?j�(|������Fhh(���`ii�4D�`+\
�+���DGG},%%����}�6��BPWW��7oBYYnnn�1T
E.���A��
��n<7n��0�p�@GGhllDfff���M��p0`�9r�� x���\��+����X�d	
�������b��=Ls"##�&�hs�X�`����{��w��_���#���/���^^^HOOg&Dw�(((�����4Hm������s�L`` &N���'O����(..���<<<�p�Bzk/��
HKKCDD�Xs���E�I��)`oo/�9 �����R����9��_?�������P�)�P����t�Rddd���38{�,sW�����~���%.^�H��.�i��5��������G(--Ebb"/^{{{4�.]�6�*�E[[�?f������Do��Q���x�c8p�Ps`������C||<��=���������������}���&�\����>"##�����o��}������{�1����OOODDDHlt������|)KKKl��/^��{�p��1,^��NP(�mmm�����9�d������lM]]]���Hl�z��![�l��������l��Ab��;l+K������,�KHH��+W������ ���/�>|���L4H��B��A@�G���U�K^^z������wo�[�;�����i�:ijjj444����())���ks���G(//���x<���������������_����1�	sss\�p��������x��?��c�BWW����hs����������OY����������BII	.�|�����g���jN����N��E4��,EY�Fa�����&��1�4LL�$K�2��&E��h,�E��-�7N�i����q:�S�������uy��}�y�g��������3f��:
�����BEE�s ??iiiL��)���������t(o�x�����PTT��9 (��^�|���F����u�cV)��i��a��5����������P:
]A@�|����������gq��Y����~�-�CVXX���QPP���C__���QPPOOO�[=���q��U;v�v����W����s &&�����i�^���C��{�PVV���*�~�����w�}999\�x�����Y������7o��0���Eqq1s��W��(((�����p�B�������>��	��O�b���011�?���w<x0����l��/d�P>uX,|}}1n�8x{{#::�����L����G��8p ���1l���)))�8���q��hhh�����<33����9��� ##WWW�\VVV��I�t���Wc����.�B�G��'������P���?��<�j�*455a���8z�(s��c2d�3���:ljjBMM
�s�C'���^�x�Q�F
���oc��������t�R,]�@�S��e|�.]��K�4�0�8q"����N1�4iN�>��s@LLL���������0)**��������={�`��1`��c�����s�N�����Z
�"�#F��/�����s�C'���\]]�t�9R���%o�9���#�I���������$����S(����o��������6n���lC�t�

��w���5kf����5k�,���7o���

���pX�n�����-N�9s�������\���.���u+rrr���_������ZZZX�l��9�W�^���������+ ++������s�^��^^^m:����]2o����#X�f
=z{{{��=***<����TTT|R[*(�O
.����6����:	lmm���WW�6���-
��������pttl�9�:�>JO���/^��'�m��OFtL�4�+(�P9


HHH����1r�H���r9	*++������\��������IPYY���@����O�>�������?������oSD��g�a���X�|9��m���������;$$$���ZZZ<
���b�yO_v_UU�uJ� 

���CC�.��B��Z��-���������f�����I���$$$�������rt4CII	x��%%%QPP���&�����<9��Shjj��W�PZZ����7o� >>������)aAWP(=���<}��g�@w%##!!!������n��www����=����9s666����������G��_���G���f^WLL&&&055e+,,������[3b�s�Daa!|}}�`����2�^�x��
����?��	11��-,,�w�(�nL��Qbb"�����o_�?�q�H]�s�N4.\���C��������|������<��O�����c��v�3f����������3���w����m�xr*)��ZNP������1LMMy����[������[AWP(=���0���PRRb�����A___�/{���X�l����x��.�#//����������1118p������"##�k�.XXX0�OOO������0����Q__���Thii�w��<�%//���|XYYa���0`���all������?�\YYY��c&M�����9����z�
yyy���z��cW�r�c����UVV�������Re
��<��Btt4z����[�B__��������c�������h0���������.�����������_�P�i�&2�
b�&&&���A����
WWWl��NNN011����N�������z�)���������F��3�����`bb�y�bbb"�,YWK���P�:::$..N�et��?'���3g����EXQ�3o�<��0����$55�_��������6l#���D���O�����'OHcc#��'$$[[[������:�K��\����i�����z����Zr��5���EF�EBCC����j@@���f����///���I������fooo���I�����[������������������;����1c�����7����!��>|8���g��i����,bddD6l� ��(����<y������2��������k2v�X���F/^L�>��������'''s�eee���~"***d����?��-))!+V� �����$/_��T^TTD������"���%o����555��7�������0�����`2y�d�����l��M�u=zzz$&&F�e�c�������IMM
�����y����///a�F��]A@��P���1u�T��y������d��!!!(**b���077���9���!..CCC���/^���a���^6��u�������(..����������R������m�HJJ��������B<z������ANN�/�C*++���]]]���3����!11������F~~>�/�_��W|��W�v�&N��I�&���>��PQQ������AGG���u�
Eeeehhh@II	JKK�>�233����b IDAT������\��/���3����?\�������HHH 77�9��yRRRSS!%%���,f���9�b@��dgg�����}���e����������!///�)�6�

��2l�0��9���KKKXZZh�&����a��
�I�&AEEAAA�:uj�����wwwl��	EEE8q�BBB����>}����
,k��a�111���ESSN�<)0��������K������#55~~~(//���?W���BL�6
#F����?���aee��@VV|}}!!!�f�Q�_w���


8|�0������c��s������r
��#%%�+W� ""��������)S'�������C\\����S`�����o�\���\NN���x��9��?�D�~����CHII���w����7n�?<x�w������9s&������ggg����+����B�N���q5��c����1~�x��'L���O�b��I�,�Bi� �Pz(�����e�LEE.���4K�j,Y�D(]]]\�z�q\�|NNN�������s�='AK^]]�������W(..Frr2���ann�11�v��8Z�'N���9�jz������c���z�*����f�1f�L�4	��Ou�
��5
�&M��h�$pqq��s�u��~|��w���/��h�|f��\N���c����:Z�-�E
����*����X,��=�7o�j��'hjj
�D
�mD����u|zt����PPP@n��Abcc����9���IXX���#�F�"W�\�q
�a�������lr��9����8>tt$���$�
j�9 (733��
�S��A�v�Z�����8::��u�����[���������u+���%~~~<{������/HEEE����$X�|9QUUm�9�:�0auPA����3���s����������RWWG444��y�Hvv6!�����uuuRTT$��)��B�9�P�QWW���31a���g}}=bbb���yyy����8������BHKK�u�q��}���C\\999\����<��FSS_�����;:��GJR(��Mff&���A��w�x�/^����!!!���2�����T���b��%PPP�z}���C��o���c�O�f��5^LL��I���yyy����u��)�����K���#!!���������$>���hiiANN&&&3fTUUE]2��@
E(ddd $$^^^ppp��7����yD�S���3���App0~��w�r���8|||�b�
\�x�����$����,���/.]�\�����s�?uJKK���#�2(�Z>�Z�}������1n�8xzz2K��s�N4.\���C������X`�K�,�j�GXX��an���x��)0N�3f����������3����q�������a�X8w����p��}/^///(++���
c���j�Q(�� �P(B!//����s@LL`��u����s�u����a�@��SXAp��=����������ASS���
�����s:t��s����#������y��������?99��������2yyy���&&&���A����9?<������U��b�
������n	mP(�0b�|��W`�X`�X077GCC~��G������������?�A}}=~��g����i�����S�L���X,,--QWW�]�vA[[������&M������`mm
��@__�i�����O�S��x��9�M���iii�1����t�N"�B>}�����+�M���[�������PPP���q��&oi���CQQ��o���;�w�^��3������c^[^^~~~x��-ddd��?�����3S��|��wHJJ���#���kl��	���TUU��������+���;�����c������P���b���7f��!��(��BoQ(��f���������Eqq1$$$�:���Q^^����vs~N�G����w�p8�����������jTWW�u|���~~~X�v-���PUU�����|��l������)�nNYYPRR�����DRR��s<{�@��dee%����O�<��U�������r��y�����yyy5jWmYYYHII���rssQUU��HMM�������:	��������K�P��+(�P������;6m����"�8q!!!���A�>}�����5k�p9|}}�����'O
�����b��t�R.�����������n.//+++.�@@@������		�6�}���z��������nw�@�>}���,��(�?AJJ
W�\ADD<==!!!�)S�0N&www���8���������o�>\�r�+o�O�>8v���;�-[�������L.&&��}��o����������������������b������a�3g����5��������;wr��{��\R(����dff������������t;h��B�]]]\�z�q\�|NNN������S���yuuu�����8Z�'N���+A����vq5
��0j�(L�4��s��������9����W�^X�b��`��e�4i��[���7c���<��<y��ZAA��-��!C0x�`����]�@��E�(*�L�OOO�����J����~���'����())	�"
�c��B
jjj��������b�����N��c�����9 (���899ASS��s�����
���C�:������S�NE`` ����v�9r?�����P(�eeeHHH0�xxx��/��ql��������+f����I�o�>������555\��!C����{��ETT6l��U��[�jjj�l�2hkkCLL���prr���-v���e���ul���+����\�#66��������DZ�{oooa���|�=�r��A�th��B����:��{999000@ZZ�����������DAA�������Y�fu8���GTT���0p�@�~�����<::l6������������=}O�����}�v���q��q��9� �Pz/_�����AAee%�����������`�X())�9�����7o(b������#�����?����g����q��qXXX�8�����o_�~����\yBBO��;w.���'''z�����(DEE�=��5#G�BEJ��

�"������Sf����=�f9OAA����.������dgg��8piiiDqq1N�:��8�����%%%

���/���X�d	�?��{�
�[���$''#22��\SS�����{7������s��4K�rss��T
��/���������***		AXX�=
���@||<�o�]]]?~����g���)^�z==�����Sa``�����q???"//���������!����u�V��?��=�������������y���������={�������uY�nDG��n�P(�� �P(B!//g�����3������XPP������S�NeNpuuEvv6���������o�>���2?<�:u
(--�P�������3��}||���sdee���{��i3ohh��v���$���O����63�_�B�����������PQQ��������c���8|�0�=���xDGGCWW����������={������=c�V�������HdeeAII	������!W#QYY;v��z�_|---���vvvpvv���	���ajj��7BCC���6l�L�4	���;�����	e;����abb�-[� 11&L���C���999���c������u�!������r(**�;��HP
��@
E(�=3g��|���I����kkk(((�����:u*����-��5k�0�*A���LMM4�,X���:l���m�������W/X[[������c��e�m�����|����!##��_�~<���e���]���B
��1PVV���+���+�9222��e�����-��������o����
.���+v�����Z��6l<<<�<������I�{������a�����V����-444rrr�����r�Jl���6mb�����n�����?�Dll,N�:��{������CBB0w�\a�I!k�����������XSSS�{5(��

�"***��KJJp��mTTT@CC���LhvDDD��fC\\��<--�i�����(��������yff&������TWW###�k�`����|���
���abb�#�,����"
�������b������L��={��2yAA� ���D$&&r��~�:<==���?CEEx��	bcc�����9������e�;������/F�
CCC��������999�z�
%%%\G!��� 99


HKKc�G|�������


|�����066���'���3����TJ%���s�f����@WW��[������oEP!��6�A@�P�B~~>�����F`` ���������/_�$h�>��9"�I�a.++���v��@'AK������|��������P(]���4�:Z�7o�DXX�s &&�qL�2�y���P<|�������F<x����������~��� ���CRRc�����#�s���k����'�������N�W6������mRRR022�������tC��������#GBZZ���<+�ZKA)��mP(�0r�H���2����`9r�ql���S���9����s�u~���;Z����N����l�����������sss�,66W�\��������R
��o000���_�@k'���\]]���P�I --�����r������)LMM��/�`�����k���������6�s�����I��s�u~��-��#?
�={� 55VVVX�v-���K��C��$''c��)���f�cn}�!555|�@�PD
�t;tttH\\����2�?N444��3g���������g��y��?�`����Ijj��
�bbcc���C�kwww�t�Rr��]���Mtuu��7��SWWG�]�F
D

��;w:�s8@������)����t���M455��������Z����9	

��Du#��OLMM	"..N


x���{�|��W$//OR(�yyy���Q��e������G3�...d����uuu5qvv&���d��%$%%���UUU����())�U�V���t���p�9w�\��TWW��'�w��1�q8J~����������f�+V999bggG����������&L�������[_O%88�L�<�����#��mj
uuu$66�TUU1�555�x�b2}�tbggG��}�Q�OOO����|��666d���$))�p8�6�UVV---!VF��]�B�P���AXX


����'O�p�����y�&��� ''����N�����}�6�l6$%%�����<<<uuuhjjBFFW���)0�	A������m���`ff�1fff8{�,�m�&�
)�?���g������***x�)MLLDLL���PXX�����X�h���$��ddd��?p������Y���~���������!66HOO�������)]!_�5���q��@SS����+V����o�����1j�(�����b�SRR���C__RRRm������9�(�

�"�����������?����q
\�p��m�������:��[����X�f
�������AyII	�����7�������.�@[y~~�P��c����9s����G�+S��n���Aff��+�P(%//��!!!011���Gq��M&oq���_1b���5�/��Y��������6����}��i3WQQa-N�����������������I�a��-�cr��XZZ����x��)O#�-q��uTVV~���qqq������V�\	8v����������z466��������?��#���J���;�������
�sP�B
yyy8{�,�pvv���=�$��s�u�O��s77�;Z�=����y������l2�+�P(����8;;�u�v�8�������={����ZZZ��QQQ�:u*�k�.����q��������
������}}}�z^�x�!C���b�w���t�n���8	�s��	�)UUU�r�
�\���:y�d��8j�(�29			���c���`�X��o>����^�()//���*�Q����8{�,���^�x����#�r���OG`` ����v�9r���)��]A@�P�����A����I�����. 88���$%%aaa�M�6�����9�V���?���u��X�bN�>��������W/X[[c�������j�����_���tt�����������P(����2\]]��@��-[�`���L��YYY888���?�z���@��y�������w�}999\�x?��#F�YYYl�����Ya������_3�rrr��k#,l9�PNN���`���\�����FMM
C����?lll������l��	�G����
,X<y�����o��/^���G�m�6���tI������G)''�fcy���x���0J����3O�>��k��{��9!TD�t���B����FKJJp��m�����d�4;"""�f�!..�n����4��mQQQ���ECCC����L��w


���FFF� ���t��#�y�f�8qB���7o"<<Re
�������b������L�hv<|���

���$HLL��w���z���!C����>��	�|�r@NN"""p��]��{YYY��������<y2LLL���c�S233!''�W�^����Y�4;���������4�{��yW|����#G��7�|���-))ATT�w		App0@QQ�k����>TTT0~�x$$$p}?�����!--
aaaL�_ZZ���PWW���U�����nEdd$�����`���3f�����T),,���P(��6(�P���g��*((������yyy���`cc���|�2�����>X�j�s $$���8u�T����,�,Y���v�^�|	h3o����n�:�=���prr�_|III&�������������R
��R__�w��u��LZZ���c\-\N��7o",,��l555ELL�$���d^��_�/��%%%��;&L����e��a��e��6\��Q�F1
Iggg���@WW��9����c���ppp��={�ryy��>g#F���c��SQQ���%,--�������j���h���������|����'j~��w�?���������:�1c�`��q��7op��9�{�zzz�.Y�;v�.]b�=z��X%%%a�D�t� �P(Ba���

e����8r��$��uk���s6��i�@�����v��=<<D3�	EEE���c���6mz��555HJJ����p�\�K�.q�J�������<�����`���

E]]���q��A,X��K�000���_�@k'���#&

e������)**���Sx�����+X[[������/_��0x��
�]�4662�-Zuuu�i��s�u�z���@LL���Q�����������������{�.���GGG(((|��D���&�������c��Ym�������XY�DUU�����u+ddd��!�������`�|����E
_tttx�X��x��9���`���9C���/����y���?����VWW'����+�����%C�e�������K���w���6����:����3��]�F
D

��;w:�s8@������)����t���M455��������Z����9��� IDAT	

��DuCrrr������8�|���������<
������7o���222��q�H]]�XEE�������.���$K�,!'N$bbb���s��=��������k�v�Z�����8;;UUU�d���������*bggG�����U�Hzzz���������
ceeE233�fl6��X�����;;;��������'�0a������Su�$��������k;;;�m�6��s��m�o�>�d�baaA-ZD?���zzz$&&�����qpp ���[��~���B��
E(p8������x��	��h��p��M���a���|�����l��}l6���|���������CSS_�����;Z0`.]����*<{�����������JW0d��y�>>>X�z5������{7�����d|������j������g������***x����������
y��?���F��������b�
���b��EX�l�

'''.������!66HOO��h�SD��i�0m�4Q���Y�p!�wC���kWC�tz��B
/^�����K�.a����s����QSS���l8p			�|�2v�����P�����������...x��
�����O?!((������EJJJ�r6����,[�~~~���Amm-?~ggg����oE=����{���s����
�hii����b�KJJx�@���5k� ))����������(���@hh(�L��'N���kLnoo\�~FFF8|�0�������oc������Fff&���������
B����
6`��i8}�4rrr�������\[
����b���Tbb"8�_������������7�����;w���'�p8��m�x�����>g��������� ����O6�Cc?l�Q(����B����"���b��i�Y��w�F~~>ddd����}����/�@CC�������FCCC�ynn.���`ll�8����;N����CCC���s������
�v�j3����O���HTVVBMM
c��A�^�D]���IOOg���w�6�ikkwIs���pvv�������m��a��a�/,^^^������1r�H���b��A<x0<�c��!&&\y���q��A<y��G�fr0���ptt��C�`llkkk������[�n����3f���/��������\]]�u�V���FFF8�<,--y�����9�_$,,?�����`ffsss���A__��#�����-���/^}}}!V��amm���DQ�A�0�
E(�9�Y�(!!�	&���AAA�~�:��_X,�L����W#  ��������066HJJb���X�h|}}��������@�m���
3f�����QRR�����[���8}�4coMuu5*++q��=�X����ruJ����iii������������������#?z


��������-[�0�iii�[���g��7b��Al�����pss��!C:����deeaoo999���...(..��m��	�������1~�x�_�jjj��)���Ccc#���0s�L�Y��'�|TTT !!UUUc���=z4TTT�`�xxx ))��.!!???������;{{{�
�?���� ''o�����}�6���D]&��]A@�P�BEE8z��B���q��m444@AAIII�<y2���@��7oBdee��SRR`ll)))�
�		��'N���$���������XHKK���iii022j3��K^�l6������u�v�ZL�>����(�B�1<}�l6EEEX�r%���	w��Err2������yyy�;eee:t�G����}��Eyy9���0l�0�X,466"!!�?f���l<hllD\\����������N�


���AZZ���������())���}����8���0(,,���:W�r��������S�����(--eNdh9�188@�)�'O���9������qqq������x��E�����������	G�9�t7h��B����"���������8z�(���������{c��=����#''���HJJB@@���q��a����;��c�233������\\�x������j7����7�|���T������
�.]BFF��|��"�U�����g��qI")
`dd���*�=�bbb�������������[��!++???��u�������#.....�����p��-?~`jj���h8;;c���8~�8.]���\VV����s�v��
333�Z�
���pss��������zzz�q�v��	KKK,_����pqq��;�ryy�.���5�
������aii	KKK�����HDDD0
����mL�4	***

��Z���������"���q'��c322DP!��6�A@�P���#���HKK#<<�����`��-�r������������������>}�������C�D3����c�����PXX��9��{����b����(�B�q�4����� �@RR��j������y{{#>>���<N���*?~��s��I�^����1c�����033�q���������M�@�<44����	eeel���o�����b������m5�,YB=��q������� tuu�P��	Ds�"E:::�,���������s}��2�|V����7��������:IMM]A]Lll,:t(s���N�.]Jn��E�B�����k�����p��+W���N�����[�:�����?���hiiSSS������DSS�XXX�p����s333���			�����5�������E�W�P:���<y������2�����Qwqq!k��e��l6qtt$jjjd���$99������#?��3QVV&�}�y��e��u��EEE��O?���_s������K�.%}��![�n%o����+**x�	&�7n0c����N�Z�"88�L�<�����#��maE��7n����.y}===�%�-V�^���+W���J(��C%�
E(��� ,,l6���x��180N�[�n������HJJb��v$�����;w@���RRR���9�^	III�X,���1+Z����� 044D`` �>}���4L�>@�]��=����������l��P�W������G���pl6���j��[�<������������jq
<|�jjj(++Cvv6sDaG���hjj����x��-��8���<y�A�!++������9�:��uuu��9&Lu)�999TWWwh��3g��
�s�-
E(���#33g��E����{�n`�-N___����������@������
����h+/((�|~,�
������/����+�|�rQ�D�t;�?��7s$\��p���kll���-���0c��]��K��������9��I��X�n�@��������y{���yOj�R�7Y�r%<GG�v�.^����]_��Ah��B����"���2��]�va���������L�������������P���;Z�����I�X,|��w��3J������
EEE,Z�<@pp0�\���a���}��Qo^�)!!��������+���
<c�c���8;;����<�����ee?���c�:Z������1c��_�u��[;���##�6��������P�-�F�����aoo�m��q}�!�$$$�:
�D����&�A��A�d���\c�����7���:�����$jjj�������S���3DEE�M�������xxx%%%2}�t�N�������?������
��|�����������D6l�@F�I���G���"�7o9r�y��1illd����I����U-��� ;v,���/_���&vvvL��)�~�z"//��s@P^YYI�-[Fz����s@P^QQA,X@ddd�thjjR��]MOw���od����?��':::�������s}
>�(**��\
����B����
p8�����������hhh������0y�dHII1����B ++�n���cccHII1N���h�X,HHHt(�8q"$%%�@ll,���������4���K^O�<���|�����uI��1blll�k~G����exWPP���	TTTp��]DGGwy�������/�������a����b1N���3yvv6			�)���eeev*oq
���A]]���x��- 08p ����@FF���B]]�+o��P(�������uzz:�����URRVYJ���B
�"�������������������<��7o���~Cmm-222�@@@������^����O�������s��������P������Z$%%1��K�.a�������z��{{{?~�����s�x�I�P>eddd`aa�f���+++;v)))(,,���n�:����9����ZZZ]^���,�^��i�����aaa�p8�w��$h��?��w���� ""�q\�v
����P���7o2��7n`��apssk7��)8�]��8���ohhh����'�����9�P�
***�7orrrPRR���������������P��+(�P1b"##QPPiii�������ql���S���yUU����������6�����Ow�9�:?t��h&�#������H���2��!o�����w�f
�555,Z��-TWWCZZ�qt5���000`�������G||<�����
���h/wss��1cp��U����r��h����
e)����
F���;�_�~B��B� "��@�u|zP�;Y�t)�u�2d���#��]�z��!W�\!��9122�������?���hii��h/?y�$���$|��r33�� ���"�^j~_***���]��R(�c8�3�k��e��l6qtt$jjj|����#?��3QVVn�9�^�n�:�����s��|����O�>m:Z�&L�� ���������������b(�NB�P(�PSS���0��lhjj�����p8�8n�����:(++#))��g��<##w��!rrrHIIa��@{ydd$$%%�b������,hq�{�� 337n��9s�����=��S��v�Z�^����u�
E���H��x��PUU���,fP�S����PSSCYY��������<!!���x��-��}��-����'O�`��A���Baa!s*L�s�uN�tw��o�������Q�t��B
���������g��wo���`kk���b�)������z>|�~�z������8���P\\///�ggffv(��������������7�|���T�9�V^PP ����������X�|9�Xll,���k�q��?������D
��Arss��p�88�[�n���0}�t���1N�u�����K8~�8�����������j�*x{{���
���044��;w��������/���+\\\�c�������������7d)�qtt���s���(�R(�A@�P�Dii)���O������{�����{�q�F�������puu������III���###MMMx�������...;v,���!))	ooo�����f�����|��=000����������������899���t���;y��>|8������O�MR(���/_������<x0�l�mmm����W�^8s���������c�b��
����0d�xxx����}�6���:�o��	��������o�>���AWW�����u��������*:��;wb���1b���/,^��V������/�)�Pr��-�}�V������_�FII	mP�
�A�M�������E]F�PRR111Q�A2���033HHH���k�����eee9r'N�X,������6668p \\\�����c������/QPP����COONNN��)))|��Wx��-���addGGG�����P��c���������@�UzzzHKK�

��"//�S�Na���X�n���4�;_�|9����|����������X�f
^�~����c�������������7c��
�����e����������h>}a�����������u��a���<����P��B�,�N���K�:<���:::]X��qh���a�������.CEE����.�"d���QYY��}�����q
HKK�_�~x��1LLL //���Fddd ""�{����R����O1n�8����������w� ++��|������7������S���AYYHNN���A�yMM����_������:�������5k����3f@AA�{��},^�X��R(ATTT@SSUUUx��%ttt --���:���"%%���{wU����2e�A5�5�\
������`ni�t�����NM+��s�QEP6w�w�u�a~���2�3g���|<����=��y�9�;%%666���BMM
������X[[���H��{�����Duu5�������=z ++��������[YYACCUUU�v�222��O���"==fff
r�E��;SSS���`���
2�X���t���?ppp���c�!!��jh��5�^!�]qq1v���/�������w/bccq�����`����+V 33��'�={��G�B,c��=r�?��������T���(**����QPPOOO�\ `��YHLL��={ �Jq��I<{�������_�������=nnn����P\\�;w�`���033����l���}�"((G����[U�dB===�<y7o����7`����������acc�_�7o����`�����;1x�`,[����
��C�APPv���1c���O>���G���rs�@;;;���~��30o�<������s'��������jN,!
211���k�n�:�c�R)>���*�.B�
!����������~mmm���b��mL'�_|�={�0
���=������r���
xzz"99B�EEE��q#�9�7���BBBrrr �J�a�8�y�����3����Usb_�1c� ..b�����\]]�cW�^
U-���_�~���s����7������#���0��z�Bee%������H<�������={xswww���"88c��a:���[l���7��s'���p��E��1����y36n��(?w����0!�������l���/_�u������:���Q�v��!<<NNN�^J�������SU��244��������CGG�/;	����"|��W033���[u�������Bl��666���u�������};����i��F��������k����?�X,���6�������a��MHNN���s�������#��u�������yq�j'��+����C�a��I��|yJJ
���1g����o��Fn�j�*�����-c�X�fM�����U�'!M5r�H��6l<x�F_���D���}���������e�Tee%��w��;w��0����

���g'��<11!!!������k�_CCC��yy[� ���Ct���G���]���H$`:���+++�D�F������>lllPVV��9������w�����c����<y�~��!==��s@6'�MRPP�.]��z�0h@@T����_���� 999998|�0s��������r;���N///���r�T�#G��������U�O9!D=edd�����s@��@�������9_��l��d��[mm-=z�?���^!BZEQQ����s`��
���\M� IDAT������@��9�{�n�������7g�8|�0���P^^�P�e���>>>���Gnn.k'�������
Qc)))������sN�<���(����v
xzz",,QQQ
���������-n����9 ��v���������$�u����0!�M�</^T���2���h@@i���
:�+V`���011��]�u���a������+�m�&7����u
�����o�E��}�y�f�\�s ++[�n��!C����Wnnnn����%�D"�������D]]]�c���������B������4�X�h������S������o>��c�r�N�5k�`��=puue���e;�.]�;v���>c�$���i��IHS��������cG�o��A���	|��GX�|�*�H'BZEqq1JKK�����4A[[��s����������1o��)CCC���(�;::6�������	��o��I�j��oy������#q��]�c���[aE�e������
�:"##��l�O�<���5�����w���S 55=z�@VVk��lnee��s ##}��Ajj*k'A�]d��+SSS|�������U�B��jh���o�;t�������U������t������8r�ttt�}�v�;�=*���>���?4�8~���N�Ws�@��s����r;	���������>�P(��_�~����� �J�������N+$�(JOO'O�d���$P�s@6M�������N}}}��XB��[7��6�j(::s��E���aaa���z��1)))�������R���Oall�k���ybb",,,`hh��<==�|���s@�<vvv�w����[hkk#66���P"���/���={����D��9 /������'���!
Y;�r///$$$ ''��s����3o�[�=z��n����)��h�B���_?��������Ftt4=z������^^^Gdd$k�_���[[[�v��;w����g��l~��9�aB�[�f���@��h@���R)�������	d@@�u��w��r6�����x������:u*�
�&�����Dr�y�b��������]^�$>|8�����W_���[�nm�9 /;v,
�q�F�����l�9�����c��������M�up�l���%���

`���-�BHst����:��������8��`�������C�0i�$���<%%����3gk��7�|#7_�jv���e���v�Y��AN��BH����Z�t)9�;v��z��������
��rMMM�9y�TVV"00��{w��s|��I������ hhhpv��]]]�v��aaa044�@ `�����kkk<y�}���=V�c!�#�H���s���� �u����������AYYk�_���{#//��s�/��	������t����BH��Q�+W��������U/Ce���������3w��IP�)���)�s�+�������9 /�J�8r�������ou��g�a�����?tuu��p�B��s��VFi�������v�v(�9 �7�s@6������@�B�
���������7oV�RZ����������w���t�5�����'�����0�6l�O?�777�����w#--
uuu�9[�����������r��-[�4����A||<rssY;	^������U�Va���4h,--�=��� ++KE�$�("%%?�����u���'���8�NOOO���!**J�\�S`��}������7Y;ds�����������n�R�&��7
��I�R������I�Ki1������
���*ZM��������|�O�>
:
��K���O?���v����S����CVV��[kkkf8�����/
:���/^��~���m�����N�	& ==?��3��s@6���S�������7n����r��ffB����<<<����+V4�X�`RSS�|��e
:�-[�t
L�6M���N�5k�`������?0o�<,Y��7�s������e���o�a���puum��=�H!Dy4  D���+U/��!//�:u�X,FRR�]�SSS�����������EBBBBB`nn���;�������A�`ll�H����[�������B��!C`hh������"66��u�������~��q�����>���5k�����F����arr�
VHQTii)z��
�H���x���������DXX�<y��			���+tuuQQQ���`������eee
����(//���W�������#??�?��������ZZZ
�@~~>���$%%����A^!����jJ,C"��}���ymm-�z�-�s�H�:�n��9���hjj�n��:���jhkks~���UUU���Qyy9v���U�V������x��)<�@�_�������K�������3�������w/o���Gjj*����H�������ynV^����3f 11�@ ���RSS�����/�T��}N�:��g�b�����������!�200���G�4��������p��A���������q��)���#
8::��O>������y�\�z��3a��y����_�rs�@�<R����Y�fa�����������A��w�!�uF5���3�����E��{�`hh��={*�����������/�����������J�uuu�v

�����S'����_�{��###����@�;�uGEs�!���1i�$���������������O�b���>|8$	V�^��{�b��M�;�7n���C�w����{y'''���"��~�-��W$OHH@aa!���k����_�~___�|����9��I�������[x5������C��}��G���?�������>}�`������z�����J�:u
x��!�r�Jt��+V������Bpp0��������K���������]�x�����{��		��Y��h�"���`��
��m[��1 ���������EGG#((eee�y@@BBBPQQ�T~��Y��u���J�������AMM�R9���^^^x��D"k������f+����v�Brr2��B�\�VK��o���d`����y�&����j�*��f���1t�PL�>��]����g�a���^v���F��������4|���ppphR>b���������-���=����������;�Vp��.��nB�z�nkiia�����|}}����E�1���Nsss?~]�t�����kW/;�uuuq�����c��y���`�e�����������c���011�����������HB!�Gw������3����~=_�s��f��jV���)7����K@@@�����E�{���������===���"&&#F�`:	p��u�����s@^�������S�N���`���o���.]������s@^�5�k+/^�_����y��;w.��G������s����������u#11������`������������"���<--
C�Eff&k��l.�JU|�	Q�������zK�.������pvvV��i���V����Pwww�s��N��N���������D"8p@n���\ ���r;����|�������HHH�������s�!�Jq���V^!�)��������s`������t��M����:d�����=��(����X�b"##666���G�������'�����%Q�_#!*0}�t�z-�[�n8v���P(�����������_~�w�}���?��?����k���u
xzz�������R(��qc�������������\�BNu�w�^���#--
FFF���',--ux������@E�$�("--
��mCrrr������QQQHNNf����AXX����e;���p��
DGG�v�������C�=��I��sK�"�����G���[�l��A��+��O?!,,7n��m�T�ZB�!*p��-��1����^J����DXXX������
:���������O?���v����s`��)X�n����y�f��/����S 55?��lmm���?����)))����1x�`l��In���.o��
ooo����$$%%�kll�Z�"�(AWWG�e^|��9P�������Y;�������i��)��v
�]��7ok��l.�9�l�2�����/g�$���v���+V`��
���_ot��Q����#w�2BZ
Q���W����EEE5�i(**B^^�9����k�������wg�		���9:w���su
XYY���X�|��!
:bcc��[7����v��ggg��l�����2e
������F�����k��B�����{��H$j�9�'O�09[�@jj*���PVV�Pnmm��S 33���G~~>k��lnii��s ??�FFFk'_�1!�VQQ����+t�������<��WE�bh@���b��ibmm-�z�-�s�H�:p���9���hjj�nQ�:���jhkks~���UUU����9�_*�B$AKKK%y]]S����������x��)<�t�u:tHn'��9��s����r;	^����uxyy��$�����K���V������]�t�=�s����*B�2p��Q����N��~�
���Ju����I���@ ��94�$000h��JHp]�����-�&�5��@M={����e}���=�g��J�111������5��x�<""�z�����R9����BCC1p�@t����������������Ry`` ���l�L����9�x�"&M���K$TWW�f�����~�:�����p��
�?��E<_^ZZ���H�=Z�������o�y[[[$''��~���6�>}���73��W����{�i�&��j��yyee%���������
��E����v���r�[�nm�gnKV�^��@����-�BHs����o����������FRRR�N���J�:u
x��!k�_��_!88QQQ��|������{w����v����
Qwuuux���� ���R�>}nnn��2B %j�W�^�5k�Hw��%-**b=f�����JKKK����['=q��T(*�/[�Lz��9ieee�������1�����t���
��={��������j����	���0imm�R��Q��w���J$�����fR�T���� �2e����#��������/�~�P(��1B����T���%7n�4%%E����'��S�J�?�T+?~��W�^���M�&�������Y��������^!
��������z-&88X����|�m�6���+������nnnRsss��������o���5k�H�����|��411�������&&&��+WJ�={� �����g��%522��[�N����yNNN�|��a���@�����&���������������M�~�z������W��e(����R;;;itt4�����?
�IMM�2D�f���^!r�jj��ptt����G�_������Y��C�����J�j�+����f���������{rs---t���5���Cxx8�����;w��k���{��
???��!C�`���puue>��@__G�����n��1x��wU��V����7��%�������;>|�^�z����Q'App0aoo���
���<99(**b������0t�Pdff�v��R�T�g��&N��K�.������#0d������_~AII	n�����(���?�����KH4  ��x��!��#��@III���P��!�JOOGnnn�������v(�9 �7�s@6�������Z����={����;w�d�Xzu����'������Q�	aEB!�H$�:u*.]��{l��c������m��!99�Q����!**
�����>>>C\\�B�l����n�����h���\�s`��}���BCCY;	^}�E�������?��O>�.\��P^^�A�a���#Q[4  ��#G����[�6m�����.���!===U�BB��tttp��Q�7.dZZZ�6m����|������+@[[s���������)S�(�[XX0����q��=xxx`��9�3go^?tX�r%�/_www,Y��f�j���A�-���}c��&o&BALL"##��W/�c�^��
+"�(�����S�����������B!��������<���PZZ��W����pttDUU�By�n�������\�t	x���P\\�����\n��sg����������P(��Q�������87��vB"�-Y�d	�3!��j���������`�kjj��}{t���W��WWWCCC�uDE���*hjj*����������k�������������������������i���J�����|��/���CMM
��|�D"AMM
���zj���B�X�re������8p�"##q��/�T���p��10�|�	"##q����#�'N`����?>�]��P����t
x{{c��	�5k��=���O��\ �_�~������/�����S�����Lg��9�N��U�n�R�i�j���'���?�� **
������e��������+�~�m��|���7��o_t��M�\"�p�����+:t(,--Y�/^����aff�:����;��'������+�O�6�sp��)��=�3�H$���d�D"��=��?��u��WTT���K�<y2��/�o��0a��/���Gtt4�����N�:!++�����.\��VDQ���-z��
/�FGG###��+`mm
TVV���Grr2F��%K����
�/�����F||<&L�WWWt��	�}��B�_���ss�����sall�t���CBT���kL���rrr�����VD�����,Q���D���p���}�6��������������G���V*

Bbb"D"�R9����/_FRR�b1k~��y���r����O�����P$����\��'�������Ymm-N�:���<����
�={������������������\DDD�6Tm��U��q�F�n�urrj�B�V?������	��K���AWW3g����5�O�>FFF8s�,,,������
���ErMMM����W�^�6m:u���|ymm-�?�!C�`��)066��s`��E�re�N$�u*))������+22��nYBT�� PS3g����#g��7���z�|��-��w��������z������4+�x�b��7o���kjj2h�tuu���|���9��9�t��gO;vL�|���pss���+�1D�����?���/_����c��A�w���q�!��~8_�9����o��Q'���W���GGG�D"���<##��Gii)k�_���'''����v��4�&�����y�&,,,8k�R_�;f��Z!!��!�|��g		�X,�-K�z�����������9 �I�L��l������s@6���h�3JHc&&&4hP�v(044����k\!�GB!���������gO������T���B*�$D��x���mCfff����c|������d�8�<�������P.�)����7n !!��s@6��������%�����I��'����{-}��
%D��B!055�������x������8ddd���9�@�S�NA 4��0a������S@OO'O�����B�l�;vo��6k��l.�9PQQ///<�����9$��C����b�w���u-�����B��[74���:�G���"B�����0x�`����Q\\��)))L���� IDAT�������)���8::���J�����N������{(..���y��B����P�Q�F!++qqq�r�����;v,LLL�������c���r��	Q%z�@M���������������g��P�����M�|yUU455���TUUAKK����������/���`�"�u�����[*�9�_*�����uCE���:����na�H.�H��6h���
��+!�4���18��9 �I�L��l�������\ ��v��I%�����0k�,\�z�������3g����S�LQ�
	aGw��'O����G���e�������c�m���������o�����t�s����r�
���8�%�x�"���9����s��1��(���#����Srs�D����H$���g9K�����
\�p�����KJJp��e�-2����|DGG�f���j�*�[!�gkk���{c��9pqqAPP~��gf8�b�
&���p�����/���%K��G�X�x�B��������2/�]]]��[7|��gptt�����/���o�p`��������u�0`��Fy��U}�	��������������� <|�O�>Ett4�����o_��7����^*!
��@M%&&"&&��E����q��]�i|yhh(=z���j���� $&&2[)55��=����HJJ�|r��y���r����O�����P$�wk��'�������Ymm-N�:���_^QQ��g�r��|yqq1���QPP�T���������
%�J������H�K!�p�����s�K�.������n�N�������g�����k�_���	___�����s�/�������1d����\��	i-���x��<x�]�va������?z����C����>Cxx8�n���w�.�55s�L8::r��|�������l���|��]�����w��!����O���/�h~��M����&s�&KWWWn�-_nnn�3g�(������S:8p �������yQ?�v�����#�J������<4����:�����			ppp@���q��}������B�W�^EJJ
!����XYY�������3220|�p�������077����9��������	999������1ttt�����D���yG����p��u�w����8�$�����Bbbbxk������ziiiHKKc���$P�s@6oj��l��9 �s=bG�����a�@�������x��w[xU�(��B`jj�>�[�nm�.�X,Fzz:BBB ���7�0�B���/�m�6dff2���������1���Hdff2�VVVX�x1�������!%%E�����:ubn������7����t�����ccc�[��v����',--q��]����<<<��O*!M������jhkk����{{�VX!��!����`��99r$k>l�0��9�=���;v����+$�(J ���S7n\���	&���;8z�(����)��'Ob��)
����o���c�0g����\�s <<^^^X�d	k'���{��'N���sS[WXXU/�4��I�p��),Z�H�q��������[ie��{3�%%��$�/�������c��HKK��� ���P(�����: **
]�t���JJJ�g��1ytt4,,,`ll�<�����1c�@$)��w���3())��q�PZZ���������;	���������j|������FLL

��|�?oCCCU/�4�����r�JXZZb��q��TVVb��X�h�B?	i-4 PS555�D���d������C�P����JhjjrN�����
hkks6	��|���������b�hC(BOO���S*/++��MRs����f�����/�JQ^^}}}����:TVV2-�M�%	��D}u��M�c������$��LMM�k�.���2��c���������c����?>bcc���#F����8�<���0{�l��y��_�������;� 00/^��I�0m�4\�t��,��kiia���������1o�<L�8>>>Lg�����W''�V:������6o����������;wf��-..��a�0h���\&!MF5�:`��!�C���0���`���C�������A��}Y�|y`` ������~�u��sm?X��������5�?�g�����3,--Y�|���'1c�����~E�y��q�9���s�b�B��5�����'�`��!_.
q��i��=�u��"00��Og������|�.11���W�2!z����={�k�����DGG#??C���%K��Kt��UUU�~�:������'''�����������������1i�$��;���Lg_~��i\�zO�>��y�0c�2�����Gk�RB���������}{�7�8�,������w��������^.!
c{����/���STWW��O�<AJJ
jjj��������sf+���<@FFjkk�����X?_���;����X,f��������9h��#""PPP��Ery����������PZZ��I$������D�����o��������
DGG���L�����?�m����"44T���� �����'��%B8���x�9���SSS\�|�'ND�.]����:::�x�"LMM��G����Iy�v�p��y�����?���)���'N�����p��Y���������^[[�q����BBZ���	lllPRR���+���D��jj���ptt����Y#���r77�f�[�liV���_������8q�Es???����&s�&KGG����_��������S������J����k�����+�1D�����8w��B������k&D����PRR�+W� ))	#F���������kW������x�����PWW���t����P$�����q�P^^���X���1�~~~�yYY>��C���#66FFFL������|o2����agg���%!m
!�������������c�F�ijj���&L���Qs��?���OY;d;	������9 ��u���}J	id��L�GSs7
!���B`jj
777|��7�^
!��rss�m�66�^vDFF�����S�����������P.�)�������#==��s@6�����F`` ���Y;	���Z�|�E��]8���l�B�?,x�+#Dy�!����{rk"��������g���s���	���L��)����s�����X�\�S@,���3���k��l.�9PVV___����v�#�������o�>;v�����"D�B!�4i���@yM���1j�(hhh4��r�
������S`�����
�]�ti�) 
1v�X�B�������A�@mm-\\\�����I@%���HJJBhh(
Y������Y�M�*��@M���@$�nqUUU���g�_^YY	MMM�-�+**�������"9���r���p��%
9��Q$/++c�"�u�����[*�9�_*�����uCE���:TVVr�����UUU�k'���LMM�k�.���N��g���9 �kkk7�s@6�����94�$����JgVu

����|������_U�����c���r��655��;��������xt��C�a������`��7n����
����:���������C�\�?������������uHp��8;;����u���<y3f������W$�7o����#X�x1g.�!
Y����8q,`��B��O�����Y�|yaa!1}�t�!_������p�?!�����wo�����@tt4���uTUU����GVVk�_~��������|����q��U<}���s@6���h��=z4�����cG�7V������+7����|c������J����044�|�D^^XX�g�����}�v�������|���4iF�KKK�8q.�����w�����V�R�j	i�j������g�a�������O�>�?�����x@��=Y|��`hhkkk�f|9���w�����
���X��QQQppp���9������899����u�H����9

��)S8���:����f�����8q"��/�����������:��+**��c������R<~��n%����������(x{{����o�I����[�n��������|yPP��?��S��v������\�����c��9�����
���7�3�����?>��z����_���?��/X�`�nX�bV�X��;88�^7,X��}����#7���o����?��S����c����c��E��"##1{���%$$�����/����K$�
��������Y�F����nnn���l����k�^o���r��6+?q�D��~~~rsMMM�M������9��/733��������
����tnoo�5k������B!-��������$�1ZZZ�:	.^��/^���	uuu��|y~~>�����r������~�!���Y;ds�7�m����]W��u�@ ���"��������5���AOO������sk/�V4  �By�<�O�>e���$P�s@6oj��l��9 �WTT��)%�I���}n��8s�L������������
B!��Arss�m�66�^vDFF�����S�����������P.�)�������#==��s@6�����F`` ���Y;	���Z�|�Tb�"�999())��0a�L�<��c4p��-��;W��%�!��xB!��&ijj����y����'''29[����&��;ccc�r�N�X�3g��[�n����l�@YY|}}agg��I��cD����=nnnppp���q��]8fffppp�����������#���W��	a���B!�
R^^�Q�FACC����_'Azz:�������t
�=b�X���t��S@(b���
��������������������Xs*�%�n��1����X,���3�:x� 
�����C�b��
X�`tttT�bB��1PS������a}�	x�$�����]_^^^---��@�\(B �6�*��)++���.�v@������gmV$/))�������������`ll���#�JQZZ�����uuu
�rwP��K$TTT����H.�QYY���7�D"����z������?q��=�������G�����q��e�9s����{�������j�S���kpqq�������@��������`���4i�^��K�.���Zn.�J1p�@�={���X�x1���q��9�>}���
r��eee������������zzzJ_W��u
E���k����?�X,���6`��!��M����ggg����*^)!
��@M�����g��q���x��wX�|������gO0�u�����a������e���������prrB��=Y�;v�'OF��]Y������ann���X�|����C�}��a��U��X,FII	k&�����O?���"�/
�8r�/^�:��

p��9��?�u��gff����6�f:t(�����e��v��a���������������~�������r����h���c���X�p!,--aii���j"""���?~<����N�:a�����_�t	���(((���S1c�3���_��_�pW�\ANN,X���'�����,������F����s�0a�u�u���/���������u���u�����9d�D"�����C�F�����W���G5UZZ���|�D"�����kkkY|ynn.

!�Y|yvv6��� �HX|9�$<33%%%���c�A������R�������������J������g�����R)���uuuHMMEyy9��/��HKKCEE��/�DHOOGee%��/���Fnn.����*//Gaa���A�� �U�����������5440l�0���39r$�����hhh`���

B@@�����G�S�N^v(����!$$�&M������}���=z4����7���1s�L|����&---�?�.]j������9����{��w]������������\�] ���vR��W;�{���'����������D�3����#G�������S��Z���S1u�T|��'������V�k!QQQpuu��'O{�����wq��Q����3�W�f�QSG�����k��{���C__�y&��^�o��������(((���gq��e�������f��	KKK�����]C�N� �1|�pL�>�:uB^^|}}y�+W��K�.������c1y�d#''��CHH��������'���1y�dL�0�����������v����������]"���r�k�����s�N����z)DA���C||<6l��h 5�|�����������
T�RB�;!�_BOO%%%���������\�R)


�c�5�����2���g:�om��$�v�����S����|���L�����4�$��,X�t\�pt����������l��7n����7s��<yR�!!!����q���BB��011���=z�Y��G"��O�>�ye��������oGeee������������d��x�"������)��v
\�r��_GQQk��l.�9p��9"77��� ,,�U���IMMEZZ������Y���?��]���q��1|���L��];�=g��E��}U�JB�!��KXXX��w�Uz8����!j,--
���HJJ���!^�x������y��9���ahh���,�;w��kjj���3������M����������b���������M��>}�<����OO�y~~>���^��k+<<<������1b����4wwwDDD���?�G}����
?��S�n/kkk����p��4FB�����w���(((���"  �u.����W�^����&z�����{��ZZZr�������aoo��|��r�7uG��X�~=~��U/���)/�]]]1l�0��5;v��?��___���0�t��Mu$�
�Tuu5jjj8VTT@CC�u�E���rhii��P�H.
!Xw(P$���_���#.))�[�TTT����T���R���/����P(d��@�\"�������>�\,�3�o� ;;B������T�$BkkkL�<���W�RZ�������n��u���>�u�uEYY������h���Nqy�m��������O�>�����u�p��4����#;4�"�F��LI���>n���������������/�|�2>|���SLL�={���Z�����?��z�\"��~����/RRR8�;v�2228����:$w+>Ery-��������b����f"�J�B�G���n�//((���'QVV�T����7n�f�������o�>;v������u��cG�k����5h� U�f�;w������
__�f]W��������e�p^���w����+�������w�����O��T*�����Ws^��Jt��*--E~~>D"�d1??P[[�z�_��;��[�n����=Z�����QTT�D��{��|�p������+Wt?byyyy9�����grs�T��.{]]RSSQ^^�:����b1���PQQ�:���E"���QYY�:�������^�������P��������+O������S�PZZ���Xf=Yqqqx��	����o_���l�=zzzM�#""P^^��#GBWWW�����8~�8�yx�egg��n������l�uE}�E����k0QO�uG[��h�1f����9s&��9s�`��}����@ P�
	� %j�W�^���(U/��$$$H-,,������S�NU��Z��)o�a� IDATS�G�a>677�&&&�nA-,22R��wo����wK]]]U���7z�h���gU��f9t���}��R��LMM��w�V�R	Q����4--M��h1���R��m��IW�\����a��I��H���U���u��y�����|���&]�~�
W�����+
W�2��{�n������o����wOZZZ� �D�/�����J�:�;��$	���`ff���������T�C��������/���I�0j�(XZZ���X�p!������{FFFX�j��WK!��/ggghii���'N����6o�������1z�h�]�V�+%�1z��/%��~�z>|B���w����1y�d@bb"v�����$������*^1!�%������X�h����H��=��q			�������lB!�9lmmakk�{���1q��VX!����)777���={����3���0}�t�����!C������S�T�ZBHK��
�������W;;;���5(_"�B�rv����%�
����������� ��wW�\AFF�����K�"((�9��R��W�C����u��8s�L������?n�eB!o��z	�4@5UUU���*�\(��E^�%K�`�����:t���+W������k����w�QQ���� ��.��"�
�F.�DM4b�Fc�(�h,�oLr�(��h!R��*��XP��� �`��"Uv����a"�����"�����w�}���23����;��k�<��H�;
����������Zw�?u��l��{����{����===t��6l�����|��z�D}0�x�/�WUU��X�+++!���K$s�D=I�R����]�9r$���k��:w�\�wa'D�UTT��Q{���������������yii)�ty��N,��
B}�H$�+����y���|��w4��B�]�|c���5I�����1c?������3UOH�h�@M]�t	�N��\$HHH��s�8����"8;;��y�����gf���;�'&&��_�\��F�EEE!##��`�p��������c����3g�u����(H�R�����?�Dee%233��W_a��������y�k�����R)�����

�<X������e����g��!<<��`-�?z��3#����?F@@���������T������nnn���?p��%"22��=�uu������s��������\�/_�����s.�III8z�(�"�P�������o�+���x�
���:��E~���x���`�����3�����W����W#..����������'�q���:�n�Jt�B5UUU�D�y ����D"�<���=z�@BB�k;99a��M�5kV��l���k#��N("�Je_]o�B�777���PTT��k����~���5��?�y���������~�:���PRR�}��!  ~~~��x%	��Z(g���a���%��������q���Ri���D5�7n@*����H6;44��)Sd���7����*��za�����������u\�7�?_^QQ�������oP���7��}������Pg�&M��S�0e�hhh��777��q�����r^��CNN�X�"�F�H�@�.]XJJ�R_c������+l�����O?�s���4fmm���Yo������d�#""���O����N�>�V�^]����3###&�km�a��������"##e�---Yzzz���:INNf��AAAl��)*�H�
������2&�HXYYY���\��F����������/TT!o����eff���9q�sss�=^�b���SaE�����d�0�H����+..�yyy�0V�|���
��5�������orm��gO%WC���3��5k�`�����c��iS�6...8p�����5,�H��}��x�����{��W����x��ic�G�Z�����V�C������UT!����8�����\
!o��A�L���!$$����w#wss��������cG���������_��������.��&����BHs��E�}�������C�\��-k���uzzz�T�rT�	�p�Bt��]v�����y��	V�\	�X���$���[U���<<<T]!��V�={��K ����9~�8bcc����a�����F�~�z��9���u��FFFb��e��k���k�l�RU���+W��gOU�AIZZ��U+�s�����V-??�.�!����������
�#;;�wz!�@j���eee�w>-**B�V������������t������W�"&&yyy�H$�������?�j�
'N���~�{��j��������EZ("�`hh�9��������������������3ajj�~�����r~~>���8���\XXX�U��c(((���P^����1����un[YY���������\"������j#
k��e������O\�xQ���%K+�>LMM�U!JSQQ���r�c��/PQQ���'����������;��z|!�������000����
�H###��B������ajj�y]�P������UUU�����B�P� ������c���
����D��%j���K8u����			8w���t�����B��m��a��5����������

��/0j�(��w����1��k�bLL�_��9�F(e#4�Xh��j��
���Scq����w^1��a�1����������x}.����=����G8x�`��FV^^�����?������Y���W_���`�L�0�����������;w�z��v��
���r�I#�_�|����q}�<))	G��-�i�������o�+���x�
���:���<y"�s�A���������eg�"��
B��233���&>��c,X����I�T���j�z^2��Fee%�<���J��������.tuu1p�@0��q�F���[1~�x/����W_a��������`!��+����9s^^^���������vvvu�
1�Xh��"�OMM�����U����y�f���;��1�TZ��=Q���@���b����f6���c��%������2K$D)c����|��>�rW������WTT���/o����+���4D��G�����-\�<}_�������������C�T�vq�"�S�.]XJJJ����o�a�����W�\aX���k<�c�}�+,,l����[������qDD���i��x��1���f;vd����=�|}}��I����5�x{{���H�cKKK������+--e]�ve��������pvvfFFF
��������A�8((�M�2�A_C�4����G�e���S����������Sr5�4�����2�������M�x�����O�)���;KHH�=�D"�
+R���8���%{����UX��9::��g���^O�<aAAA
����D������;��Y����d3�P�>�z�BFF�y��F���c���x��N�>
��{7|}}��u��c�0t�PDGG��T�������s��_?���Gp�Q�F5BUD�yyy�����_%VB!��?kkk,X�@���1���A3����k��a����={6V�\	�4iR�m�������:�Dh��<==�t�R�7�|��������G�������We�J��o_�9sF�m����\
Qw<���;�["�BH^^1i�$|����/_��o��������D�Htt4�����������O���R���������,Ua:::5��|��!���MMM��5��eK"11������s��r�=s��Qr5��������Saaa�p�v��I7L"�B�c����a�����};�;&�z�����c��	���.h��i��5�-[���Ldee!00Pv�2///������kHNN������U�����2
��(���O�1@pww�u������9�����m�~��\���6m���bLQS'������/
����k��!���'55_|��M��3g�������5�6lBBB��90!���TYY��C��_?�F���n��^^r�p�B��y��*��D�wj.((��+��	�v�Z�^�;w�����c�������S����G��Nh� ��C!�1����(//��?�����J�\"����X��Bee%�GUU*++QTT$;{�9������{{{�m���F����UQQ�9�x9���t_�����s��<yii)�C������}�P_!�x�
��C(������2���P������a(O.�7�MQdd$����
6���zzz5&U���E��my�il�@����;�#G�p6���HLL�\D�_�z�j���k5NK�9���T��8B��(���`��q�s�u�����;�{]]]DGG�����0a233��_?��;������Zc�/_��r��/_���l�����;�\"�p�������?���g���9U�u����o�<y��7r6YYY��?����{�
��L�7o�������{���CCC\�rE����#F@GG�-BZZ�v|?������tDFFB,��_�r��oGaaa�����c�����B���'�o�>�V����������`��B������������uf����w(�W��b�Y����_(����HKK�k���;�����-��7@S����tuu9s##�Z��$��?��o������\BK������)Z�j�����U�W�������,,,��c�*;;;?~<@EE�v�*������'O�������Oj|���%o������mee����[SS����<yii)&O��c����w�EBB���G��oZ�j�Q�F�j�����eK���q��P��U+r��a��������u�0{�lhkk��&<<C�AII	8��*�K`` RSS������ ����]�v���rss����Ij��5�
Yutt`ddT�\OO�����93y�������o�+���y�
��C(�������&����}E�-Z��<�MsE���H���W��u��
Sb5��!�W$��t��RRRT]����u�YYY�GDD0�F�����`���c�����_����EFF�[ZZ����}�����.���`6l�0�cW�^e�XHHH��n]��������qPP�2e��_�u��]c�'Of��w�l��q��?~���5h� �g����*�&Mb���6366������iii1U�K��Xff���P�'N0777��+V0???V�|���,!!A��D*�H���������q@@���WaE�������=��2�m�������5�����jmw����!��.1 �����q��������>Su9
"##}������q����_~���"�7999HJJ��={j�I�m��G���b��������n����X�z�������Q^^�HT��X,�H$��+(!���M�:���X�n]���"**
���E�TP!!�h��4KZZZ6lU]J�y�4z�X���$/�ml��
z����{�b��5�(Q%ttt�f����a���u^��,)������������u��B!
�����/����ajj�^�z!66#F�@�~���ML�:���������!o	;;;\�znnn�#G����
���5�V����w���}�v�g�&�����o_,Z���OWu9j��o��{��/*�B!�����C��1o�<���333�����u��`�U�HH�h�������c��'�`������6m����jm������7����FXX��[���TU��V^��D"�?�����2��LE"c055�A(!�B�������[�z�*���P\\��={�W�^*��3!\�5URR�{����B��B�X,��#�p�0�'����;
177�w��P���3�;�����q(�1����}������0r�HXYY���3����W_}Uk[


�;bK�R�QCB���qU�����%K�����R�Naa!�.]
888`��1�L$��O>App�
+$��^�x�9����8G�����r�0�'/..�a(�7w�}�P_����P_����/������*++y��
���M]�V���;���/����1p���|?7��-����d=z�s� >>�O��\�cbb����� �GEE���+��B9�ABBBp��M��6l���w�r��
�+W���G,O�w0��������///G`` ��b��������w������������|����H$HNN�1��U�����i��Z(���D\\\���$�����e����B*�b���X�~=<<<�d��g�t��	�FII	�o���J	����DEEq.���!&&�s@(ONN���{9��S�N�����Bys��7�!!!
���"}����������;�+���������[�rE���]��}U]!5�%jJOO����WAGG�����I�����MMM��U�z�B�|���z���%g��#��~E����?���������TVV����s�����[�j����~��w`��8p �=z�<UVVb���<x0�����\m��zzz�w����.������oL�8'Nl�	QH���all�����p�/������N������7o����x����
sss��
e�B�9��C���E�����w�h_�6+..n�#D��`�"��K�����2����[���J�8""������"����f��������,==�Qk���`K�.e!!!���R�����\c�oPP�2e������aj|���2��^����=z���]���9����_
���A��={�4�~��9sXyyy������c7ndw��m��Q������TuJs��	���&{�b�
�����������%$$�`"�H�)W\\����=`���*�H����gU]�m��1ccc�>���������Bj�?��Lt����/Wu
���D��}��_����8y�$/�������e���MMM���`��EX�h�����x47ZZZ�g
��1���\���+�*B!D=���C,����gy��1���<�{��
�@@i2:v��������
c����D///�N�Bbb"N�<����^^^8p ���sssTTT���;�@�
�T���b���c����_|�H�B!����NNN�~�:45�w[���J�{B�*�@@i2:v�����Z�������>�G}����e�������m�����76Z�M���3>��s���s�C�1��3gB[[��'�B�����
�^^������B�[���������������SHMM���	f���{��h�����};���1m�4���YYYHII�X,���'���"//��]Su��B�J988 <<\��8p��!����C5URR�{MRaa!�Cyr�X�;2G(/((�a(O.Dh^�������aM|^qEE�?������%����+W���������KR;ZZZ������-~��Gx{{c�����������j�*H$����C��.��7�����PVV�9�P�����s��<yqq1�C���+((���������G_�(XE����;�z_���6m��K �Z PS���8z�(�"A||<N�>�� ���� 99�s@(�����+W8�r��4 <�X�y�\�����r��1�<b�H$���>�833Sv�?iZlll������0�1���044���t�R��q�Vu���KFF���8	����� �'''c�����B��S�p���E����������������M<x��s��\��h��M��x��;wN�%R]b��LMMaff�yG��m�������'������������o}}�z�Bwz������.�v�������w�����-[r��<9���n�����y�-x�/��l������[�n
;;;���\WWm���3#�OCC��O����U]
!
��
� IDAT���666��]FFF����wnjj
�DR����:::����:��
B}���o� ���r<z������B�w���������#��e�B����FNNNUDH��`B�,�F������h���;�.E)���1x�`dee"##��_!66V��)���|||0u�T/ol����n����0%III��)S���xyFGjj*���T\��<������cU]J��J�HLLDRR���0n�8�����,B�fhh�7n�}���.E)N�<�E����+���@<|�P�_\����~��>���M�Hccc��^RR�*��R�zzz�������x�[��N�|��7�����U��5�����n�������N�v�����~LMM���D=��B0n�8���@[[}����;PQQ����N�����={��w���.�BE�����������u����a����TQ%333XYY�������z��Oc����K����B!�<y2����y�f�_�V�\�S�N������}���U+��s��EBB��+&���3u�TXXX������No�����gO��566���eVE�����>�B����S��m�lq�1���76m�$��S'xzz�."������	���rm�����j�:���;~��w��Cc���3!���q��[�������;�K�.5����n��M7�$�4��u���+���������6m���s,X���,b��t<%j�� PS���())���b1�Dy�������;����a(O.$77��3����E$�gee���'�����\h�1������J���r����
zs&�8LLLj<>|�0�y���O�B__�Q�"���������3/--�}��KJJxG���q�H^^��5Q�������������\��AGG��F���LFFF�rE��{������+//������?�����}��h��
��k������/8����Dj���3��?�"��]�p��1�E�<**
g���\�CCC����� �s�!����4�����+����y0����{�����+O�w0����ys�T��KzYY���;���P.����?s�_(�����5k8�B��{��k�.�f�����������6lX�������4j}�(����

�\$�|�2~��w�E�\[[�w�LGGFFF����3?z�(����� �7w[�l������� �������n����y�.|���y����2�s������#**JV����kW���������1c���s���+����*��{)))HJJ���{�n\�p����I�E��)+++�k��s&������8g�
�]�t���9����n���������B���^���add���...������P��W/���p��<y�5�u���/o����9�XKK�w�B���6\]]9�/�����{�������A(744�����=[gN��|???��3������'��S'L�8Q�Mff�l�#��nB����	8�����yg��\�}�q�]�v())���P��u����o�+���aeeU�����9s^^^�����5yyyh��m����}���������0`@���9s�l4��]�����U�V����12"�			X�p!���9kS��h������'��i1f����4NQ������K�����2����[���J�8""������"����f��������,==]u)Yrr2spp�=

bS�LQaE�7h� �g�U�����73CCC��������c�������ijj2�M�6����*�������Fy-�T��={V����&�H���'N�`nnn��+V�`~~~Jy��
����;����;KHH�=�D"���}�������7���#k�������X����&M��8����%..�yyy�0����'OX�����3g��{�Xtt4���g��Og���5~�����������O�GGGv����gcz��9���am��e�F�b�f�b...���������'�n����Q��R���TG!�����???��'�;�����h�c


��!��J����GXX���`gg��� �=����5k����;���bbbT\q�:t��O������	T\����`l��<�����w����/��g,;vC�����6�q�-ZOOO/��xxx`��x��a��0����l�2\�~���X�z5F���7�u���E�a��u5����BXXf����2	�-B�����u�Bt��AE���~�z������iii;v,bbb0n�8���111�6m"##����g��nj����X�lJKKq���F�L1"����C�v�d�(��7��~�	�~�-$	�-[����c����,�AUVV�����s���x�����D�����������V�r����Z�}��gX�x1���```��%��!�B�I$!<<G����C�<� ,,��O�����f�|��7U������O�r~}��������}�u������J���>���w����Y�fZ�l���@���`��yo��Y���OOO����]�v^^+_��7o����k�����~���6m������������k���c�H'�b@!�RO7o���i�d�������������?>������M���+�^��3f ,,"������7�b1�<y�=z��d�8;;#>>^��z�K�>}`aa!{^CC����y�f���,:t��{�0h� �����w�5J�Mrr2��������K������UK�N�������y�Ifff��E�<��#�[�����t-�X�9�P�����wd�P����9�P�\�������y�B��������8��3�WVVr�0�'Wt^qEE��pBQ���r��PZZ�����������quu��={0c���WTT�;�P(W%CCCl��	%%%X�hQ��CCCFFF���F����RC^^o� �W����A9a��]��W����;�z�ju��������_�h����}�<}E~~~��BBB0r�H,Y���������3Fv�E�����w����>}�����?���'���<z�p��y�]�*����Gj���3��?�"��]�p��1�E�<**
g���\�CCC����� �W��r�W�r�J���s.���#����|����_?�/���+��E"~��g�����+�w�v��%��BHc�y�&BCC9	._�����s��+����^����NNN��if����p~��Q����s@(WS�L���s1{�l��'!!!Jy�-[���
B}EPP222d�uuu���c��	���D�~�0w�\5��X,8Q����m��C�o`������s:::X�l�����-^�7o�Dzz��Y!��M����q��a\�|���x��1Z�l�u��!>>������>�}�]�����Y)��-�)+++�k���tD;;;XYYq����t�sss�����u���i��~�����&4�����������G�7O��G�����U�g^1_���
WWW�����+644�������B���	8�����aoo�y���mll �Jq��U��5�'O�����w���Ke����]�v����|}�\]���#,,qqq��qc�_��u#�n����
B}���3tuuk�E`gg�������������s�d�;::������8{�,�v��[��}��������s�������j�\�R��h�����m�6������s���|��'��u+���PRR��={"<<\�������H�t����������u�����=���`>>>*�H����Ydd�����%KOOW]AJ����d������)STX��
4����G�eB^c``�233�����l��Y�������snw��fjj���}��	���&{�b�
������Q_��g3f�`�
j���������cL$5�k���bX�~�����������c^^^�������_';;�����,''��������gU]��H$���3U�AH����:B!����CHH~��W����������F�L�WWW������w��q�<y666pttTu9
{��	������4TUU�n������U�V�8q"F���J�ZZZtYQ[�@@!���s������333,]�T�e48---����App06o���������w�����K8�;��C�"::Z��6	<��	��W/l��E���F��B!o(''�w���g�T]�R���`����v���t�z,i:D"��kOOO��N�t��~�	���x��lll�~�zU��$��������sg��Z��!��1����������BT���'�5k����o�������0~�x|���8x��
+T��[��`�������c����
�����`PYY�����?�����;Z�����>|��w�BSS�f������@$&&��U�X,Fbb".^�(x����F�������w\PP�y�Xy���<����;��^�xQ�\Hvv6�������#��?~���������o��1������x��i�s�D����z�/^���5N��#G��}��4h~��|���X�p!������TVV�;����������V�����~y��{7���?���/_��i������������B�;oh011��Y�`cc���8|��Wpss���9��#[0x��M�-���Xt��S�Nm���999�}�P_����P_���C��!_�!�7/�8����WO����O�k�544�����7o�����Rj_�}���HKK������?��c#TD��h�@M�<y��������8x� �"�P�u�V?~�s@(��a���8�r����+W���K��}����~�:��X(�������9���|�/���7�H$����R,Y���`.������o����P���c���O�k����;���n���4�_~��?�H$��?��_��|�
���{��<Bx]�v
6l�\$HIIAHH�"�����tl��bq��OHH@LL�"�P���������"$$iii�����={���_������5|||��W����
-[���Q�����.]Rz�AAA�}�P_�r�J����\������ufx�h��B}L�0k�������s�N�^�0f��Z�:99��wTVV����)1bttt�h�"���qn'�H������"�nR��:w�ggg����{����>�
��rXZZr������x�1�B�|���m�r��5|�pXXXp�-Z(5jLLL8__�\__�3;v,o��E������j�
�G���|�\OO#F����Pnll��C�r�'�[XX�W�^������_�����1c���6m�`�����o$�\7i#D���������[��w�����]g.�Je�������e|�c���`��yh��%���9AtttDYY�q_(oh����?���������c�xy�abb"q��I�����mll�w�}���HLL��3g�^���o� �W2D���:��h�!����w�
������h��1'N����s��P��_,�S�N�����Rj_�"55yyy

���.��kW�k���Eii���$�C�NU$����KIIQuJs��-fee%{�|||TX��y{{���H�cKKK�������,99�988��)S���"�4h��g��� ������eff6�>���k�{��y3��y��Z�._��]�r�A_�U'N�`nnn��+V�`~~~J{=.999l���l�������ihh0===�������d�0�H����.��������q@@���W�����edd�x�s���G�,//�M�>����+��c�����={V���L�&Mb���6366������iii1U�KH
t!�B��0a�
��w��C�ot:���M�6?~<����i��[��AQ?vvv���������1j�(��5��L�����O����0���������HU"Z  �By����\�M������8y�$lll�����r��������������Y#TD��h��B���d�Ajii���~��1BBB���+++��=^^^�,��`gg����������@��]e���#tttp��I�={�|��
+%DqZZZ6l���h2�oZ����"sss\�x�1J"Dnt�!���7�;w���������O,_�:::���#���K���C���6���j,/O��~���.�t:6!�����
- $$��=�L�B�T�vh�@Mq�8�������yyy�#s��g��q�0�'"4�X�����	��8��3�y�Byee%�<b�\�y�/^���%N�S��@JJ
V�Z


,Y�999X�d	<���@\�xQQQ���QGeee��())�}��_u��q9r�������d����s~Naa!�C�������������l��
e�|��w4D_�������m����b�����m�m��9��U�5u��I���r.DGG������B���[q��q�E�|��
HJJ�\������by�s���#����|����_?��Th^�P����;�X(Wt^��;w-���r��	��=[�X"� 66ZZZ5N�l��F����LB����k��a�"AJJ
BBB8��G�����t�W��~��9"##9HHH@LL�/bBys��7�+W�T�����+n��]g���6��}���U�W4ew��AXXV�Z�������9s&!�JU]*!2t5��sg8;;s�;���7���9��
������D�Ms///����f@�i��|5�y���#���G<j�(�y�|����_?�
����zzz����rE�[XX�W�^�t�R�9QOFFF5�������z����i��m�����D����DBbmm
OOO�n������\�����������XVV�w��y\wttDYYY��������o�+��P_Q�sQ��������M��h��������{f���9��Yss�F��~�@�������wo������/�4H�����W({4j�(����>R(�a��������E�066�3k��%&N����B���|}}������9�K�����������8�!�������Cww�Z�fdd`����R!
����������=������~��r�m\]]y?_(o�F��y\��
u�;������W4E�����d�!���Ftt4&O���E���011�M?!D]�!�<�\��O�D��{�|||jl������/c����(�BQ{k��Appp�����d|���5��u�����`��U�]"!���B0k�,|���X�v-F����t6�����7h���F���1x�`WK!��/�TZ�����TUU�x���	������j���E�B`gg���7#11���X�`�������O�>X�lZ�h��� �I!!����{������?������#222�,B�B�B������������1|�pTD!�4=R�����X,���F����G�����q��s��	�����Dg����������y^^�����?{���������y�9�B�>}���
������#a����:��Ms>B]�XUU���\*���3�+**x�������������H$�s��]�&{N$�=�uTZZ�g��q�����#���?��oD(��������.++��o�+�>}�P_���Cht0_���������?F@@���������T������nnn���?p��%"22����.�Z PS����;9	"""�� �o��	��\�W�^���D�E��kq�~�����s\�z��`,���7�cyr������ys�D�y0-++��9s8�By~~>-Z�;��/���.]�y�����o���63D�b���011���C��J�D"|��'Va�����+W�j�*�E���$l���s@(?z�(BCC9����xDEEq.�����+y�����~P�����p�� IDAT�+�N3/++�������M������cGH�R��

E~~>�L���}�b������O����i�K�T�^�����9�y��a������,����033���,���G�����#��h�����M�8�������G���?���-�~�r???XZZr�[�'}6��,X��kii��;_M[[�g���$�b������-,,0y�d�+������Cq���:s���R)F��.������g��a�N�p��a�Y���o��E�:��������ccc�Y�By��=��cG�F_(���@yy9ttt��7w����}�P_1q�D����\�������g?V���h�}ES5�|��3R�T�����g�������w��������+U\)!5�������=��g����/����;
����W(�:@V8p o>l�0���#G*5�����555a``Pg����>���s�r������


1d��z�fff���gN��������{������p��Z��������i��49VVV�����mmmakk[��S�N��/�w��U���������+����Z����w4���)������sssC||��*"D]b@!���Cll�lq�O�~�p���F��By{�x�B�%"�!�@KK�����1�������!���o��m2dLMM����=z�������.��:�!�H�R��'�c������k#TE!�4Mb���
�g�}�'N@$���7n�@hh(����R��h��B���������We�a��������B!<f���c��a�����BRRn�����x|���h��&N���w���TBj�5���s�F=//���}B��g�8G��gggs�0�'"4�X���������y�M}^qyy9���9s��f�����,8;;�����_����,�������@����k�.l��E����JKK9G@qq1�Cy����s�0�'���#���.++��o�+�>}�P_���Cht0_���������#8t���9��b��)x��w������G��~�?��___�����\Bj�5u��a����s� ""�����B��M�p��!�E�|���HLL�\�%I��W�W,�<b�\�y�|9���o1����:�6�y���7�����^���[[[����������;�������c��U�H$���E�T].!o���+X�j�"ARR6l��� �=z�����By||<���8���n����}�P_��?(�WT���uf��c?�����MQbb""""��������.���QYY)��%�1��C5��W/�������n��a�������P�������s��P��G���-[��W�5G����by�s���#����
�������q�n���mll0t�P��q����/$%%!""{��AZZ�����gO���_��[7��4���;v,��������`ll==�z�={�D�����[���������������/o� �WL�8Q���:W������3���U��;�z_���}�}���v-Z������4xxx4Be��5$���/����@��(Eii����>�X(��G�������>�����z����z�������1}�tU�BH�������gnkk[[�z��:u�}}��k��
�����'�/��p_��}��F5�����MQ�6mPVV����WI$��CBT��PUU��t���,H�RA$�1��m�������x��)c022BAA�`������GYY�<y�-Z��������������`mm
]]]�������h������V�Z	�ffft�9!M���a�U�A!���q��!88���x��J��x�"f��]��I�&���~\X$D�j��������?����c��������!C��������HNN���G���BSSS�|�������c�
���F�)�������������;`��1r���o�<E���c8r���� �B�����q��}l���s���2��93f��q�cw�����e�3������fvO�<���=���d�jjj����=BVV:w�,���K����/^ 33���())����doX-Z�@YY<x �z O��
��=���8hhh4��WU177���SU]!�


���o������i��{���*��Bi����. ""+W������������Gk<_\\�XLDeh�@
U7���q#455�v�Z���b��m���A�=p��u�[�&&&

�������3]�t��+W�z�j������'N����7��7������b�
�������+=zt�����vvv044���9<x�			���@�n�p�����{���~����k��8w�lll0h� �n�Z0�}�6���/t��HLL���=---�<==qqq���p��!899a���P#��z����?K��K$�g���#<����Bi��b1n��]]]�����M�Y�O�3NHc�K��D"������L�6
����3gZ�h���Pl������R)f����c������ 88;w�D`` tuu1s�Lx{{c����yvv66m����w���~��������`���r���mCee���544������`jj���2t��7o����C����y�N�������G#<<�7oFxx8������t����dL�0QQQ��i���!�HP^^.W~��iL�6
�����q#"##QXX���rt���F��{�w���CUU��<c�\*�"33��y�Y'�����������
kkkl������K�j}\�x����BB�:*))�=�����s�<yaa!�Dy������������9G/G�	�\# 33S�����#���2���]|���������s��EII	D"�}����W�^�?��(#j�C�����������VRR�c������u���?������'�'N���R��k���/��������>��%%%���r��+W����'�=z�3f�K�.�/^0��J�r����>311�}�����I�Rv��E�����w��f����_��$����sggg6�|v��m&�Je������Q�sGGG�x�b�������d��3g���C��XVV����H$,11�yzz�n�������Ydd�l[cccv���:��EEEl���������>}�F������z���77n{��a����/�#F�.]���

bS�L�s����A���={T]F�M�:���m��=�\
!
����eff���D6{�������o[�x1����W�c��l�2���[����~c+W�d���o��8q������X������������;KHH�=�����;&�9^7q�D��������u�G��+����34hKKK���z��-{����kl��Ov���:?�)��������un�,_��m��������������"?��@
UUU���/^�����l�I�=������\�{�����{+i�tD��%�/��1��M^{��b�X�hD,���;�K��5�
�#�(�^g���2p��Ds��f��5��z�<��{����f(�eeeHHH`�>[��2_RR���XH�R����f����D�w��>::(--���&s����J���#�n���*���	J�D"Aii)ttt��0UUU!""�������Dad���


}}�Z�:-Z�����k��
������[/���OOO����
���mm�zysssL�8����^�i��{�	
x�W#"��ccc


�Qx������	�,w>?l�0����s�;�9r$�����]�z�;������5�8�E����H�755�<!�b�
XXX�z���k�����1���o\���g���������������8WDD�4�o^�����u��c�p��}`2:t��M�6�s��8x� """�M�6������h��=������x`2�yooo��������,�3�|�~�X�W����5k�`��a��};
��O?1G:�{�z�
[�n�T*��q���;v,���s'bcc������2��+W�|�rL�4I���6l��\HH�������]�v���������S�Vt���|�	�����������;��`������S����1\]]� �fF���q��=A�-))y�W#"����cG���������lll�M��zt���3X������������ttt8_T�����kiiq&8P��b��!��KB<_k������y�����C�rn��V�Za����Vu����0`��U]}sD"�4(|[�iL�M�-Z��>���v�����w#::�/_f2���{������;aoo��/�zy�����w���������
��S�x�<S�G�055�����c�0�������+�933�V����%���S'l��	~~~���?~��'�[ZZBCC�����y3�����7�_�~puu����Robb���[c��5���{���#F�������S'^������b���X�`���|vvv������������6m� 99���000���������3^��cG�l���?���:u�UUU����������R���,^�|	]]]���AEE���HOO�����H$������.tuuQPP��/_���)"�$_�5����[�J��h�"<|��-]����������[��{DjcaaA���TUUEqqq�`�������5kY[[�l��'O&kkk�L���-S����z����9P�?~��������������83��C=z�`����1��w���9����u��4s���3���je�����
zzzA.\ ;;;���'}���
������|�^��O�>���M�/,,���O�$___���b|^^9rD�:t(��������������y��A�4������H��������>�%K���#G���kt��u��/��B:::����3�U�������xEo��g��������2�5�{��HsF<A��QQQAEE^�x���T����f<��^�B��]y=[�@JJ
���PTT���2�>}������Z^^���b�����$dee����b$$$���%%%���|QQ�����������./�������g&ALL��;555���#66:::(++S��SUU������S'TTT(����� //��'$$���UUU���#�%	rrryssss�R"�(�� �8�����6m��j�d��8�PDDDDDDD��Dlpi��G����`��mPQQ���/

Y3455���'��e���b��������l��{�F@@TTT�����G�(**b�ppp@```-/�?~<�����9������M������9����nnn8|�0g&���lllj����[�������������P&�������� �t�Rl���o�f��JJJp��Y�����/_�+W������o�>��y�<y��������/����^g,(�$�8t�����9���WW�:=���'''�q["""""""""��A������GZZrrr0c�:�
R�9��_?^�e�����666���93�v��4�@�<���*�5kkk���������@�.]?h��Z����J3	����h�������~��%��53	�<y��^�L����c��)pqqA������7���X�j>��sA�m��PUUE@@JJJ��S'������	3g�T�����h����8t������}{b��	�2e
�WQQ���*�?����y�"�����S�N5���mx��4u���PPP���^PP����$w>/�JQQQ�����srrp�����v^�x��m�r�8>�zzzJ}�N�8����0@��O�>U:����m�&$$�k���6%%��������HMM�����������CC�zy��Lc�8������,--����.\�@EEED��L�������g��2���c���o����3s@���M�<�z����9��G�E����z���K���g2�������3��������93�����e|����<W����Cke�7N!�@CC�����Z�!!!4d���e������9C������|^^;v�
��9��e2egg��}�h�����W/255e���A�4x��m����_g��e���������_��s�*��]�_��/^���j]��c�����233��i��
L��P/f�� prr���/35GM���+^��_15GM>��SA����������8{�,������-��_�~���

��������z��/_���#%''��������={�L�3DD�AD&�!''eeeh��
��.�HLLDff&���X3����2$$$0_�-s@�/))All,�R)���X3�|bb"k��GGG�����������(..Fii)k�@dd$(�������PWW��\�aaa�����kRZZZ+S@*�"""�;wf�P���QQQ022��������������)k���gdff2���H$����9����O�6�%�"�5����t�m����W�|DD^�xGGG�_��M^���������F���abb�9j��6�z��{��W/?r�H���s�����v���kkk�w�-Z###�����s���+`aa���N�]�V�	���k<����M�6����<����������P3����=\�g������EBl��D###L�>����J��9s&������������c�����w!��0{�l���S�_�v-��m���G����PWWg��?z����W�W�Z}}}�=g�����>\]]add����k����������W�����o��������:ttt��C���kW���AWWw��a���~
����-B�p��
�X��������R?v�Xl�����>�����U+\�r���1b>��c^�f��3��-�:s@�V0j�(xzz2~���?~<���CCCL�<nnnL���U�0n�82�6m���~*��3|||0n�8���"  ������sy}AAN�8���@|���033��C������������;vAAA���O�����"%%p��il���Q�>�M��]�a��5�e�"���s���{��?W�$(**���bcc��~q�H�����Cdd$����R���]��E����#�������3&s�]d��AX�z5>��c�7�sss97�;�������q��
����!���q��F��7G�=�k�.2��/ED�_�x��	��E|��000�����{�nDGG����
��{�V�9���g
t��]i����)`jj�4s���;��_WXsff&��_�!��S'�LKKKhhh(�P�MLL��uk��|^Y�@�L����***pss��}�83$��L���d���f�}yy9k��������������������C&�>��s|�����_������s��h��5$	srF���:���{<z���-�����JEDDDDDDDD���� ��������L&���Z�hu���&M�D�o�f��d2%%%��9s����Syy9������)S����9}�����z&@UU������������������w������C,���X&3�������h���djj��?~LdbbB���������	��=����1�\��^�z�d����J��>���������
�������B���EFF���7����,,,h��
s����{kkk��e���1����BBBx}�=�w�����OR���t��iA~����g����'"��w�������r���W_}E��������sfc���}�""M
y����A�:�����]����4|�p�c��w�KA\\��s�(..��1EDq�aF"�@*�"))	999�J�PUUe�����%&&"77W�o�������
�������T���R@A IDAT�\^��U+�OEE���HHH@AArrry�����*dggC]]��***HOOGBB���Y��W����Rdee�}��L�������x���#33�yg^�WUU��g����J���+�KW�������3$&&������
�#%� ������r���*��RRRx}rr2��� �Jzc������R(Ig[�H�EUU-Z����g��kkkDGG��+y�������%~��G�k�!!!�:u*������&�/G� h��G�DEE���-[���?�333���aaa���0l��zzz��k� �����{�����n��a����������mCrr2���;X�z5���e���|VVV�5���������HKK��qptt����k���/c��e�������l��yyy����d�������HHH���kQZZ*����
8s�>|�U�V1k��mmmk�����X�f
V�Z����#44�	��������~���m����-[�JJJp��ql�����[�^^^�v��������G���������K��`��}^���6/���?7..�3�JDDDDDD�y�mFFF��o��@QQf���;�RD�M!f4A***p��9������s����A���_?l��
?�������-[b���������x����u�V<'N�������t��>>>J���k����A�a��}
����������w�FUU���555�f��^��6m����m�6���...055E���oooooo|����7o����+V���P��+V��/����+ttt��������~@���y���f���y���C���};���[@�~�����2���
���d�����0k�,���c��uX�r%***`eeOOO|����~���h��TTT�q�F���>>>�9s&�M���O�>���PQQ���?�R):t��]�v��o��W_}����'.:���,�x�B� hf���2?Se$''���c�t8���Iaa!�����sgV������b�$x>������J��3>/���>=�.��������Mf�RMRRR�����pN9HJJR:��'$$����s���{�+++�?�����]���WVV���g033��/++CZZ��>���v�Zt�������$	�����/_�'1E�Fmpa����LMMi��	t��U*--%��e
���Q�n�83����x�={6YYYqf(�1114e���������F�"


f�{������3����dnn��I���Lfff���|�	�711��1b� ��90x��Z����S� ���}����2n��E�
��P��������4`���e������=K�����P�������c��o_���&333�����w�q��)j�DEE���&�\��3� ((�

����-_��H��g\�|��N�J�����;}�4�����W���8@������Q/�}�vZ�z5eee���������G�v����eXYYQLL��+??����C�����/^��a��Qbbb�|tt49::Rrr�`�o� i��'� 2�EEE())�D"av������(,,Dqq1k��2����'O�������|ff&���P^^�T��9�����X�-�����L&C^^k&ADD$	rrrX3?~�-Z(��Z�BVVk�����������2���`ddT�WG����)�������������e
DGG����3s��WUU!99������`�P�+**������$t��Ya�[EE�F���e�PZZ���L���3�[�)**�T*���N�|AA
�����N��J�(--E����-ZT+��9��Gl���f�����.]��E������������^�z�����/WD�����&&&���`gg��=�=z48G��ygggTTT(��\�oGSS]�v��1c�G���8y�$*++ann��[XX`���PWWg|LL~������k�����/�P�7=y�G�E�6m`aa��>�L��0a���?~�����P�����Q������?�t�R/��������&&&��y3��>/""��i�


�����/_N��M�������=zD&L�I�&���g����f��I�=�?���������~���g��9s(::������o^�������s����i��)���JO�>%"���o��'O&]]]f����_'{{{Z�`]�z����i�����5����7��O>!www�]�K�.Q�����������_4b�Z�|9��������[�n�r�JA~�����������s���{��)��'tuu���������������������������4|�p��������G������?���i���y�fA^*����?�����������4r�H�����������H;v���k�����^???�2e�����>��Y� �s��Y222����D"���g�N8ij�S�=�N+�����W�6������#F�`�+���K:t(�yq�A�G~�VD�)"� h��h�C����1~��g�������t��B�������6_=S���Ji����)`ll�4s���;�.]RXszz:V�X��9�����I`ffooo���|�.]��9P�+���IP3�Q"������m�s�@M/��X3(�$����2��J3	���-[�����5k���p��=&�P�y1n�8|��G�q�������	[[[4���UDDD��4h����f)�+LMM���]��B�����]W�������b]!��i>�;w������0e�H$����������������-[�z"RD��h�
��XXXPhh(�d2JII�E�Q��]93���#��eL�2����93	�{�L'''233����#""H__�Y���{IGG�3s`���djj��?~Ldbb��9��?z��@�����\^�9`ccS+s�����V8A���G���t��M�������2BBBx}�=83N�>-�8����C���DDt��]���d�+� i,��l'rss�
M�����b�+��=K��g�+� h�xxx�{��GK�.��������IUU���iC7n����={������x��	#�H �J������H�R�����D���
�l�����J������l�			(((@NN� ��n_UU���l�������W�^!>>UUU���b�P�SSS���[#33�5s���3��������I�����Z��'&&B__�5s@�OJJB�.]83�|rr2LLLX3�z(�����w���B�d2������HSCH����
�u�������+��s���6HNN��!C�R�E�����`�����.\���*���O�>}:`��Q������R�n���.WDD�Y*"��|�MTT|}}��eK����033�����������]�v	������w^^^������mmm^�m�6$''������Wc���8x� Z�l)��<n666(--���/���7n����q���Z����X�l���+!##6l@^^� ��,Y�...8q��v�Z���
����pss�����9��b��U���{[[�Zk�z�*��Y�U�Va���

�����t��iA��~��m����b��-���?~��m���������]������y=z��.]�?���i+�J����f���q��-V���������&MBdd�[�:�����?C"������P�u��
o���|�r���.(�+�t�� "hhh���vvv044Dii)���`jj
������z������FFF�H$������lmm������
t��Q�WQQ���.�����gO������
�������R��eK�m����+��	W������;w����I�&)<w��Q��""�B�`a����V�XAS�NeF3#g��I{��e	o��M%%%��<x���L ��������q����>�FDDPYY3���O�2�ttt����������0\�p!1�A���T^^��O�8�%''SEE3�������>}�	z��UVV2#�/_.�W?�W}�����B`avvv��B���m���rrr�����5k�0��B|nn.3�p������n�������1#G�I���g	���y�����G��M�h���dhh���z�Aqq1={��������s�/�J9��	�999�c�����b���G����}^QQ999Qqq�[�*��#o1h��v�����q���l1�7������n��+���TW�}C��n����&L {{{f���-#www����uENNN��
�oH]��[�f�b�j�*����;G��������� �z��[�2~�
�&���1���2����D��L777���g��2/������P��/�-,,83���Q�HCC�Y�|���7�������9{��������7��O>��&&&���#F���2\+���A���o���)p��-4hg��2/�Y0�3s@���������9���7	���K���dff�����������I�7����2��l����t���7|E""�h3����u����mnT���������077oP]!�
�+V�\�ZWXYYQ�>}���3��D���h�k��U�x��9��-[V��K�,Q�y)"��[� 2�())�D"a������(,,Dqq1k��2����'O�������|ff&���P^^�T��9����Q�{#"" �������;�D����������-Z ++��7P���C�6m8{��,jf
��� ""-[������������g�����Brr2��������9��WTT ))	III���
kkk�[�zzz���������U���d��������G���U�,se�]'**
�w����Nc_��� ��oWWWt��C�E`` ��$���.���6p���:�����5�������p���:���hL�4	���ptt����^'�{�n7����������r���"++���x��)������^W4w�-����8}�4TTT����W�9�o�FAA:w���("���A�DY�hlllp����{��2ttt�c��f(�^^^������?455Y3����Wc�����k��:t(�iQyo��Q��g����5
���Czz:ko���y�����8{�lA�+s`���8|�0g� �l�O�<a�X�r%83��<S`���X�j6m���9������5k�����9�����q��Ac���������*����������w�{�=�����kjj����sd�������Q�}s���;6l�w��<����|�r��Ut��
�;w���
:w�����7�2DD!��
ooo��1���;��9x��9v�����l�����8{��`�����~�	/^����F��'N����|ll,�n����Bl������Gq��5A>**
��������;��
|u��={TW�}C����x����/�`��WVw4v]QRR�����M������O���c����X�t)lllPYY�+W�`���x����7ED�
��W�^��!���;0�||���������������e���;w.�
kkk<z��o�Fvv6��������0w�\4666�s�BCC���������)�fffpqqA��}��gO\�|>Dnn.�l�KKK^��_ 88K�,�z������z�*3��W�^���Epp0"""���ooo�����W�^���_�T�U�V1��{����w��vvv��w/�����K�2��-,,x}�>}��O?!%%���y�����D�GEE�O�>������b���8r��?���xzz��������ajj�n��!00���|���=���f���3f��������o^�x���z�
qqq��k���L�<��������C������###q��q��5_~�%TTT����c�����P�z�
�}�Y���z�8ph/�


1c�|���x���p��%������YYY����l�n�&L��C�87hDD�^^^pss��)S`aa8u����p��
�����5k��KKK��� 88��gff�����������1f�XYY!;;���Gzz:��������#G�{��x��9.]�����;wN�?~�8rrrP^^��s�6�w��X�f
�n��p�
|uE�^�TW���={�]W���a���������GL���+W�={������
�+�?�lj��������z�w�����������~�l�������
###,[����^�T9rD�^�z���������l���?�N'�H]������P��d���B�-��]�rf��3G�g��2e
���sfT�l�NNNdff��9P�GDD���>���{����N��W,���9�XNu�����A���G���t��M�����
��zCBBx}�=8{O�>-�8����C���DDt��]���d�[=��]�9g���R��]g��4'������'��������GVVV������������^�7322yKKK=z4�;w�������+������O!!!L��L&�/^���YXX��	&����RPnn����)�UUU�u���gi����z�-[F�����;������ZZZ�:�@D�9���"�������������\H$�L���,���!77W�WSSS�HOOG\\��������[�l��) �Y����v����
h���Bo`jj*bccQRR���={���X�{���k��������v��!--�Vo�2������D���@__����z��zO^M�����
�`ll��S�CD����Oaff��������J����yyyh�����it���g�n��yc���3�]ZZ����|�ZZZ(..f�D"AQQ� ���===���1��%	


/�w��h��
�������L���+�R���Z�={�d���������R74��BEEEi]Q����uE||<LLL�]W�}C����[s��9����]�v!22m����]�<���'�b�
��ID�I���"����Shh(�����	h���������E�h���t��=""�w��;��N�J��� ?m�4���$"�;w���~H�f���W���9sx���3)!!����_�N���4�|�u�M�2E��~�z�#F� '''�3g��z��%f����wk�������yzz����i������J999��|$������������QII� ��	���&z��	
0�/^��������j� ����.]�������������������������O?�D7o�������u����(��;w���9���s'�����#h���D�z"��-[���Z�?}�4�9���������djj��W<A��������4N���I���o��DD���iC>>>D������}��t��1
��c�RPP%''������'O���}��gt��9""�����s����� ���M���t��E""����i���������s�����F�A={�d������S��������'���7]W�?�Au��s�X�
�_�5g��������Au��7��055m�'�=J���c~gMLL��A�G���"Mq��	bhhH�/f6���Ceee���KZ�x1M�<������<���rA~���4m�4
d^�GDDPyy9=���O�:�f�����?>���QEE����'N$f��1�O�>%ggg�3g8p@a�pee��?|�0s���NHH�1c����+�

bn����TUUEqqq��Z����

�v
�����@AAA�1�:::���A��m���B��������=}��w�MZ�/**R�g�b�
��B|�y��V�bn��������34r�HZ�f
��;��t�����AQQ%''s���������������������J_(s���A����k����&O�L�j������ IDAT���:988��u����������_�������]�v���ci��
��!�������i�����g�����������|ff&�_�����i��-�������iii4y�d����^ooo�3gN��CZZ��q�����*����9�fV�����b����� ���WZ7��hP]!�
�+���X��q�����=��e�����;g���������uEYYY���n��5�
����:�&Yaa!-X�����={FS�N}�("�q��	bllL���<@&�1������y��/�066f^��{��x��|CCC��]��Q�HCC�Y�|�@&�17k�Z�}�}�N�����wO&�17k>��������d2�f-��o�r����oQ�
�:���K��V"bn����S�I���u�>}n�B��fmgg����}�B�|������������q�7���C�����!!!�����	���?N��O�����v�"WWW�M.��oT���>R�[i��o���n�J666dooO'O����R��7z�����_��oXYY1/��Y@|^&�1����������:u��w�����6����Z��������)���1c����s��;99��c�87	�{�
�N�:)���
��r���������������{3�_�l-]�Ti�A�������7�
WWW�v�������X��l�2����Hc#f4Ad2���PTT���&@"����GEE�R)�����!>%%�{������*��N�OJJBXX������"����M��D"A||<�����uk�z�
���Lo_u��];<�-Z�`z�$	bbbyMMM$''3}�r���p�������x�k���***GXX�v�Z��\krr�B_,!<<QQQ���+�>}Z'_YY���#66���HIIQ���������c$&&�[�nHMMUX?�/..�������CCC������O�>��gtttX����agg��;���=���~����1~�x�4a>�������7�������Z>%%��_gu""M������BSS���
c����������!;;�N>;;������Eee%�R���e^"� ==���(((@YY


�����!��x���2l�8���555�~h>�a��j������w��uuu��J]|�V���
|uE���TW�}C����d�����������f������555888zn��]�!C����Jc�N��chhH[�l!OOO���/����D��)p��%���-s�����_����epyy������v��e~�������W~��zo`hh(s���w������>��@>��7P�W�9��k� �����={r��=x�@io`M_��O~���7�������c�
d����M}���}���������Y��A�<��k���*�������4��mK}���C���#G����5S ((�i'��g
�:u�i'`�`��3����v��6Fdee�������	���/+��������r����������6m
:�������������������������E�(%%�M_���`�
�&���9��������ll���^�5}]3j��d���/_�R8p��:���7P���X�+���\+�������
����(���
����G����b�v����3�7�>			��m[?~<�����c�h��1DAAAHs������3mK""��6m�P@@���P~~>9r�^�5}}2j��f��&L �Z!���
����:g��u��7�����c�+���j��7���hh]��w�5����������z�`���t�����m���)��i
�M


%�LFiii���N�����...��KA�-s`���d``��IP��e
899Q�N�83j����ZZZZ�����������h�������������Q��}��ry���[�n������f�
���(z��YYYq�
�������7o������.\��o��{W��'n4}f��M���W��; QQQ�t���uY""
�]�v�|���O���djj��9 ����pf�����<W����������O�8��o�Nvvv����n���
��r]!��X�
�)��luGC�
++��r���BSS�Yo���������2k��A���G���'---�����2EDXQi��~$	^�z���!++�5s &&%%%�<[�@ll,���������%S ..UUUx��� /�����/X{���8}LL�����������@e>**
			h���>}������			h��5g&ABB��UTT���c<}����5{���������FDD��/^ko`dd� /��V�D��si�TVVb���
�KOO�����G�k��^�z��'"Ro�H!3���O�<AVVJKKY3����\�f��������������yyy�y/�F��
M���H$J������q�
�+�>}���B�RW4wlmm�n�:,^�ZZZ�����9GGG<����6m����g7����( n4A�yxx8��_��m����C���B@@�����>��]CCC;vL����CTT��������akk�_~�������Dbb"���X�r%p��)�i�F������f;;;TTT`��ux��%��������������������x�b��9���+����z�j���
����X�`���q��y$&&b��(--�O�<�y��a��
���?���#,Y��YSu��O�Zk�x�"<==�i�&�8q������TTT ((H���y3v���?�����^>|�7o��~~~������W�e��T*������~A�������L�H��� 9���8q�D��w���3lTD��!������/_"  QQQ����q��)���/^�p���C���g���;v������l��iii���~����?�<y�>>>(++��x}������������~O�*|u���+.\����"88Xi]Q�	&p�
�+6m����B�RWhhh�����9sp�����GHIIAHH���UUUl��g��i���M��]�����/^L&L`F����+s���k�@M_����~��������WRX������}}{�{e�53	j�������F�{����V�u�
���#G�Ik����s�R�.]��Vo1(**�qH���/�C!>//�s������9�P�o�-�f����2JII���p"z�iddTk��������n���3������@���#����W�@M_�������5}ZZM�<��u������ --�s�!Qjj*�C!�����#����d��5=[�����3j���r���������7n���3�]�l���s�
�+
\W���5��h�!��)++���P
���7��k�H*�6�e��p"n4A��������(//'��e
,^��LMM93�y�&���1g��2/�ohh��9��G�E�z�u�W,t1�:�X����c�G\s��C��t��:�#n������$���%+++233c\�
�;w����#�&AHH9;;sn���������97���]�����s���7�
�+W����ISS������o��dllL�{�����7ihh(-�ED������[����
������'ke
����z����9���7���83��<S`���daa��9���:u��w�����6����Z��������-[87���3h��]��|�����;��oKu��A��S'�u_]a``���B�RWxyy����wo���)����]Wt����� �#**��/ADD�F>� ��L&CYY���PRR�-Z�_�@xx8*** �JY3�������rrrX3����$���AMM�3���sM���b���������y��<W��<��kMNN��<b>��������LCCC���>}�`��=���a������:v�X/?z�h������'N�������Y/�\1b"##QYY�:0�;w��	L�2�y��������HS'&&������Dfff�L���pddd@OO�5s@����Fxx8�Z��9�������(((@YYk��2���]++��:t���=<<���������o���Z������;v@]]]��R��U+�u_]��u��r���"99�3S����������^W�[�4i>|���!"�?swB�CCC��e3�����DDt��=�m���KL;��{�{y������v���H"z��.���
��}�i'HHH "�����3f� ]]]f��u�W,t1�:�X��>o����#�y�@WW�z��)x���W�7���gdd0����G7n$CCCf����CEE�;/���G����R�=h���
����4u��mK}���C���#G�����������uy�@PP�N ����3m�N�b�	��;'�GEE1m���L;������0rpp +++f���)�/_VZ7�����
�+��!u���k]1m�4:t(�y�	euGc�EEE
�+���)�g��Qrrr���K�jb����A�177�?�������M�����+s���k�@M_����������8���+�oo`u�,s��<xp�1�����wo`u_��@��Oo`M/���:�v����3�7DDD�6m�P@@���P~~>9r�^�5}}2j��f��&L ���'���AVVV�3���B�RW�����AAA���7���hh]��w�5����������~�������������Vc_����A����BCCI&�QZZ������!g����u��E�g��:u*pfT�l�NNN��S'����>22�����V��W,���W��555kmDEE	�G���G����#���7�����K����s�
��K�^k��H�v�(..��8??��������3s@�711�����y�����W�����8q"m���������o� ���T74��B&���g����A��M����u���U��
�oH]�����7BBBijj��a���O>��3f���O!�KD�) �9l��3"##QTT���L��������Bii� _YYY+���'���@ZZ���d
>..�����dx��� /�����g���������H$V���X���!))�Vo �C\\Z�j����Z������
������8�m�����z�^�=����
<x���D����
������U��������y��������������G����[���Y��s��a|������#�����gO��3iii�}i""u��2�R)?~���,�����$����sssQXX���\�����LDDD�R��V&��W����|^������V74��B"�(�+�����Yw4��HLLlP]!�
�+�;.\��S������7o��_������p��=���5����( n4A���>|�~�8s���������w�����U�V���������M����c��[��b�
�������t�������r�
�.]��?�!!!h��� ��"�o��������'^�x��?��-�W_}�K�.������?>���[\�z999�������#��<y...X�z5n����O����
%%%����G1k�,����o�FXX\\\�5U��������~�
��/���?~��w�����<���
<xP���s'�=�[�n1������w�^�������w#  W�\������
��}�������������������]iZ������?����q��&�422;w����5��;���)"R'd2�9x���m����h9rs������q��!���O�y�fA>((_~�%:��'Obcc�i�&�����G���={����"""������*�<y��2���L��o��nx�uEppp����'O*�+�3i�$����u�����
�oH]����KJJ����z������:���D�144�o���>��S���/����TYYI999�����~��G4}�t������*A�����42d���P\\UUUQVV��:u*M�4��7�x�bJII���*������G:::�z�!��������;��(���A
�R�U,���{T�5Jb�+&���5��)��1��F�`�`�(EPDE�������efwvW��������2;�d����s//L�2;v�����,Y�.�S��v�R�����������C�����@*������g� �������}����?����������
��rdee��w��_|�}��)q��B�T
�����?Guu5RSS��G��7;w�����`��;���_��_���q��A???�_�m�������r���`��X�x1|||`gg���b�AII	���������Sddd��yG 
����x�����Mh1�0almm�`��={����}�6�^�
���fffHKK��C%J�$	z����K������w���gQYY������+V���9s��_?A���
��=��m�0|�p�Y���O��!Cp��%A������aF��u����O?����%�b��)�B
>|���|��Sff&
��g�k����SZ���s�l��E�o��+v��a��`�!�B*�r�
OOO����=_&���w�_QYYi����c-Z$�Ug%j���iS�8���`�-Z�P����"���-{����	��M~�&M��]����R�S �^�����.��nee�9���Xk�����EZQ��Zg.��/���@}����%�-[��������u�.]�.�B9s������EZ(g.�:t`/�L���	��kggg�����p�����H�������}��a��q�Em���3f��-���^ 

E������u�6m��A�^�Q�e�����}�v����{��f�r�E����)899)���L���Q��_(?q������|�o��K�.�-��5?��#o@������[y����a��w�^�"�"�*XYYi�
�|����A����������W8;;�K�.�v�@��wu�W��ARRV�\)���~��+>Q�tS��^� J]r��Pqq1=y�D�g?55�bbb����


����:���d���%SSS������R�wNOHH���8277���L*++�������{\\]�v�lll���{TYY���������T�>���h�~��VnooOIIIj���>!<..�������W�.^�H����������>n�������.]�D������N			:���

���4rwwW��6^ZZJ������N:t`{,���O�����);;�������{��IAAAJ}��2d����w�6�����Q�x��������)Sx����U]�p��������/�����SYY��;��*66������������>����(""�
����233u����I%%%$��)''G'���A���TQQA������������+V)�)(j��Mddd������s'��_?t�5h��w������F���W����+n��HJJR:?�W���S�.]��Y������.�C����H�}�-^��,,,8_���}%�V�&���eoo����c��3f��?���d�"""�v���H��i���a�	aaaZ9�6��0������g��	[[[�|��N�b��%''����oz�����e}L5_q��6����.�ct��B?��� �,�c���/33S��� h��)��o�4��Y��c���u=z��KJJ��}�w�V�g�������}�b����x^^�/_��;������y3�������~��1C�k����~��U�eff���;������#G0h� x�l�i8y�$���OOO����[l�@HH���1|�p>|XOLLd�BCC�v��� A��,wssc���:� 22R�o��+���
�7�W�����W��9}��a�3+4����%%%�
77�Z����������������T4�� IDAT���M������Wz����q��5}*�D)I,�B9;;#""���l�`��
ze�r]3T�>��<,,Lm������s��>���\��@E�)s@����Cm������
T���2\��@U��;���J�����������s����L�k�l�����W|D�D����b�������L&���G��P��d�r]3T���#���S�N���[:g�l_���c�������G�Qs8b�^�a���7o�A�����
;;�Z_ 8x� ������uM��(QJ�Pm��Att4�����i����s���T*��2�N�
�LE��)�������f����d����AOOOXZZr����������xvv6�~�mH$��@>�\�]\\8{�����Z� %%�n����3oo���������j���7������bq�����m[��b���������g���UUUa���JK�D�fI$��{�}.���s�N�l��7s@o��9o���-[q���5k����V+��������~��������7�f_��W?~\�@P�~}^�a��pvv6�W0�_aeeU�������-���c�����x��1n�����������$q�a-���w)!!����(//�3s ))��H��HNN&ccc������2n��I
6���t�9####�s�go`jj*���q���hJKK#sss�y�&go�&~���{�.5n��9{�8��w��=�J���;��IVU�z�(,,�222�����7P����F�q�2��xnn.5l���70""B766���4%���U����A���t��Y���d2�:u*M�2��oZ���(J�MO�<���X*..���
��!\&��L&���v�� ���S������SEE�V���O���/�wV���7�f_AD}��LMMy}���"##� _�pC|�W�m�����]�R��I*�����N�TJ������������$�@P��
]�v�V�ZEVVVt��1j��=m��������(**��-[F�[��'N�?��%&&Qxx8}��w����RPP���i�k�����4""


�E����'������� ����v�����k�W,d�&����W���u��v�AAA��k�B��q!����u���?��C[�l!"���������.�����c��K�����i��!��eK���W{4m��>|��%JTm�\.�}��QVV����t��M��o}��t��!���KDD����i�&A������M������#D��(��O?Q^^� >l�0���?)88������h���T]]MG���{��E'N�R�o�6���}��'�G���+5q�D^�a�����7�W0�_��q���'�J��}{���c�~�=��F�����\� �[����7oF���:����+s@���9����P��F�B�&M��eB
u���7����*rM����!�R�&&&z���y����rf����x�b�������=_����������|#����B��Bx~~>��CM�.�9rDcccXZZ���J�G�V�j�TD�,�D���{c������C�����P��d�r]3Tyaa!�L�WWW�|�Z>|�;�233yG
��#��{����8T�\-[�l�9s@��+n���J������={�d��	)����WTVV�+���C�E;���q��5�E�������(QZ$j���iS�8��)����-Z�fh�L����7s@gn��4i��9��{xx�����������#��B�k�|�\��U���X�l�N��k��bl��]�vpvv�
)G�~�x�AAA>|8o@��o���[�����1c��"��.�U�Vj��D��277�����������#88X-S   ...���8Sprr�����"���#o��&~��	������
�|�
�.]�[$�5k~��G�"�6�����[����a��a����EE�U ��e$�WX[[�+n������y3�t��ng
�|P�}E]/<{��{�������j��x�"F�����8BQ���f}�$��	��'O�2bbb����


834���d���%SSS�������(..����)33�3s@OII�=w�����#��B�k������#VT�z��z������O�������TRR�y�={���� 233��C���������^���?�Q�F��_����)S���_�����&www�H$5}(�D�V���R^^���Rzz�Z�@DD���=g��&���M���TRRBr��3s@������h������r��M�����ZV�XADDo��'��i���k�;w�$ccc��k���
��_�������
�|�
�III�������]�|G]�uY��-Z����������R��k���G;v$___
���%�G5Z��){{{l���qx��y/�#1ml;3�\g�bbb�v���@XX�V��
������o��"�U�9s&lmm��eV�2�X�<b>.t�&�8o��y��+�6m�����G���k�G�������<���7����=_q�A����"Q��
233C�����_���#4h�X���
�<y{������`~��-�m $$���>|8>,�'&&�m���l;APP� �|�������o�b��7h�����
��+�����+f���>}�����|GM�����|���[�^A���-��+V���;w^������A-���3"""PXX�	6l��W��*�5s@���9������������}^�>���\S��*��������/������
d�>����)0����x[�T���(Q�6���b�������L&���G��P��d�r]3T���#���S�N���[:g�l_���c�������G�Qs8b�^�a���7o�A�����
;;�:] ?~���n����2P��� �@P��MDGGxQa]�x1�6m��90w�\H�RA�+s`��������$P�\�^^^h��1o��*ONNV+h����������b.nii�V HII<�X:����G��+ **
m��e_+D�US�H$�{�.�\&�a���h��%o����ys���-[��|�k������V����?��o��6���&A�o�����8~��Z��~�����P_���l��`�!����������v�����E�z���r��{��������83�����q�����d266���,��+S������aCJOO��3222�s����?�y���kf|�z��#����#��B�k���������U��D�U������������b������e2�d2���k��	�O�>���~�:UTTh����T\\��guY�|Cm�D��W(�����w�+222�7�Wpy��������_~��ug����������k8*Q��&�����ukDGG#::?~<bcc�x�b�9���^�����3f�@BB� ��G!..��]����)))�;w�V�����7o������a���HKK���S�s���� �����������3�}�V������8���q�Fdgg����������q��{�=B���1i�$���
��w�a���(,,��o��)S���������`���033C``�R;������/�<x�n�B������g��a����J�Z�_����X�����=���'X�j��/�w��X�n 88Xi��\AP\\����c��
��������d�9rD��BC%� %�v���+V��b����/z�����P8p|��������0c�A<,,;w������o�>@rr2��A|��-�����c���_����1z�hDFFj�k��A�=��cG�|��+���W�+>l����o���ZA0�|^�a��4�W0�_���R�W����z�Bhh��J��g��Y�`ll�f��U[$j����1s�L�8���(--e����co����s��a�����0���h��M���������/.B���C!�J��eB
������o���^���{�|��m�E�Y����S�b����?�Qk(**b/�B8sg�x1W,�!�R�D��F��A�"-�3��w���3g�i&K���b/�s��a/���� ^YY�	������'����=_���g���I.��@���?��s�B"���8�����	4��{�����t�b�@���)�D�������k��l!����-|��7���P^^^��,Y���3m��xYY[X�|9{���uA\&�a���puue���@����G����222�����������"�yZZ���fE�U ���5�m����~3�W0�_aff��+��={����BM���}Euu�A����9�+W����������=Z�n
KKK��L�6��S�(5��Z(GGGXYY)1Ekkk����)XZZ*����M�D"Q����{xx���������655U��3bx��
�.�����6nll��������xg�\�U��6��s������EZ(g.����Ji���X���*]��r�H���GGG����/�[�n�E����c���E�������`���8|�0���q��ddd 55W�^��3gp��|���6l���c�0ao����Q�j�����k�.899�k��

U�L���A��_(g�-[�T����"@�f��n���������s�������[$�:u*�uW(=z46o��[�������;w�	9W����D�o��+LMM
�7�W�����waa!����r&���|P�}��P ���L�;FFFJ_X4o�����j��D����APU]]M
4���"���Rb��]���/�D"���<�����GGGSDDY[[��(??_'~��e����f��QZZ�����x{�.\�@W�^%�q����pr������r%~����������)""�����xpp0]�vM�x����?~�����s�������]�zUi[ee%�8q�RRR����._����dDw��!'''�����?}��N�:E<�-ZPll�N<??�BBB(77�,--I.�s�{�~�(&&�\\\8��Q�����������l���V\\L���������u������������mK���.
<���G�"WWWJNN������)00Pi��pQ�D�>���SAAI$�q��{���;w�JJJ�A�t��-����w�������s���t�����[���EYY��_'~��=�k�6o�L?��5i����������{�����;v�,X@���z�.���I$�����F���W888�+n�����P;����Szz�ZV�"��u�W�	����#G�Pqq1EFF��'�������C���Ok��D��VMW(D����{����5k0|�p�>}�~��\��U�O��*�7olmm��eV��;�oo ���
T��2T3	TW������M��@U�Oo�"��7P����`���pss���'���{{{�|_u����q��9�������#G^�1�+D���233C���� ���O��.�k��*�5s@�GGG�[�npssc����A����s��*7�W0�_��woN_1o�<��E�i�5�+�={f��puu}#V�U%j����
�L�	V�^�W��*�5s@���9��###�B
�y��{��
T���*rM���{��j���h�{������7P�3���]�r����U(""�5�Bt��Q\�p���X %�v�������"�$((H��E�O��*�5s@�{xx`������{���Aaa���/�W<}�� _QTT��+�B
���;�>>>�
��+Z�l��.^���������G!��:%j���i��	�L�%K�����7s����DW�`^���@�����J������|}}93���`bb��9��SRR�
������C�A��
9���O�����~������xQQ:v�###��@M����Z����S��D�@p��Mdff�����7P�����
LII��[�h��-�+ **
m��e���AYY��}��\.�����w�������A~~~M�(QzK"�(]��?���H�R��!����7s`����8_�����aee���?�v�R�O�7���.�
��&�a��ppp0�W0�_aeeU�;w���C�8��S���7��O?U�w%��%f�r%%%QLL��_����83�]�F&&&Zyaa!YXX�����M�4�&L��4����~��4~�x���$'''�L�7n�����uKg��a�������x��M�J�����3t��mj�����r�2\&���+~��	����T]]M��
###��%�������dgg��;x��q��>�j��7�����dbb�y�'O����,j��go����KR���7���SZy~~>YXXp��>}Z711���x%���~�211���WS��}����
Dc���q����q�h��14`�rrr���{��+x�X�-������
���45^\\L���'KKK�J�dkkK�'O�'O�������T?�rrr(,,��������3s@���"�L��9p��A����3s�����=z���o�6��2}����,,,x}���"++� _�pC|_VU]QII	�d2N6t�P�4i}��W��������������E���.P��P������hv�all�^�����2�L��U~��9�����l^1���*������j��S���W[A�v�Z�{������7P�3#��[F�V���}�+eee����C�>}`ff��7l��s�i��!�K+���777H�Rt���5����!������ �J�e����b���h��=n��]�g J�p���b��^������;s@���9��u�P�k��A�=��cG�|��+t���Wh��f�r._���`������P_h��`�!�����N� ��e���#����-S��"JTMJ,�B���c���lq�u�O�W��b���a�����i������,�'�|��s�b��mJ?�l�2�3T���C!�J�}2!���
�
�q�����.]��;H2T3	TC
�R)�H����=�X��@U��8���7������'����=_���g�xG2�gM7�%%%���������d���G���8���J����o���RfC~~>&N�����������'��5B||���'&&b�����E��[��-����k��zepq]3T����\&�a���puue���@����;�xQ<�a(���w�w��������K�s~��G�3T�>��\��U��+��={����BM���}Euu�A��.�9,//Gnn��c��U���_��3��������������_���2%j���B�8��)X[[�fh���
s�z�������)))�k������Bu��L&���S!�Hx3�qXZZ��� |^��y����W����������V]]��[����S�LQ����Tz�8�����k�j����k��U���<���]]�x...ptt�
)�x�"�u��[$8~�8�[$P���W%%%���l��	&�	�x]):t�}���v�\��'����]y�k�.�}��?W�\y��*J�K���9v��'''t��U��:������9��3E��-[�fh�L�Y�f����?��www�9_�`������-L�:���+��=�7o�-h�������;y����@`bb��7h����Z}���9���LE����B899)�L0�s��n���T ������:v��^?uy|���5}
�D)I� ������
PQQeee)�k������I"�P^^g��&^^^N�~�-}��wTTTD2�����h���4h� JOO'""ccc���S;���$����f��QZZg��6�����[&t^��y�;vd����R��M��������~�Y�f��9s���3�w�^����:u������+�_q^1_��<bE���W����y��y���t���B�� IDAT�����SHH������%��r�s���������'5j�?����8�bNFhh(��;���=��ZMj�������S`` �l�R/^�E��OW�^�^=Z�h����DD����i�8����Aqqq��8E�z�
����H$t��
%���:w����P�
834��w���������$��934�[�n�����2��M���{j}�\��y3���O��IN�{�n�������Z/~��1Z�`YZZ��/\�@>>>��0�����F���W888h�B8W���2	���?N���dll�y��|����\�o�����v�J����D�u�
<����������///��gm�����@�(�t�B������g�v�������9����Tv����7n�����x�������9s�VL�<Y��U>o�<�����dV��;��7����P;::b����4i��m[[[\�p-[��o�����p�8q�}�Z�n��-uYY��AM����+lmm����wo�����R�#""��$���aG�<y������g��*2bbb0{�l��������bu����I�l�~~~x���K}_>��'N���������TcHLL��%JTm���:t�����_�~zepq]3T����<::��u���{������D�3T�>��\��U��+�����A�h�"���u�
.�K��*wuu�3+TUYY�~��	� %��I,�B9;;#::2��-�^�Z������c�}��	���8///��r��;W�@�c��3Tydd�ZH�;�����3�z�*|}}�����X�r%�7o�/��W_)-���cg����?U��{w�Att�����\��/88���?��;p��	\�r?���Z�
�t�$`��a�r�
o�����y�PZZ�G������+W��`aa�Y�fa��1���o;��T])����u������v������}�������[_�!��Rejj����xQD

�;s@���9��u�P�8p :u������@PXX�s����B�5s@�s�
����C���C}����^��\��U��e�:[ ��{��QuVb���M�6����dX�d	,,,x3|}}!�Hxy`` �<99����i������o8��{��=���LLLx3TyJJ�Z�������+�c������J��r9�y����S�]������b..�H�
7o�<�Xg�
���	���K9��2�X�8QQQh��-��U�����\.����D�������0c�����\�+���|��7J�>|kkk�}�]�?�.]��G�~���U���"�D�~c�(@*��f������[�n��2��_+++�|�����k�R���@h�
��
m���;v��
�8���*h���
������wh��|�6_aeeU�������F���)1���+))�bbb�~�������9p��5211�����c��k�����C����{�n��c��{z{{S������jL�w����t��
����[�nqfh��6l�J������n�W�������������YXX���b����p���y��xnn.u���:w����t��]����+611asAe��������������'dbbB~�!�}���TYYI�����x��:u�DFFF�y�fz��	�����#�������h��}�a�����($$D�g�r9-]��5jD���N
��(Q�I��(''�����������83����*��d��W�\����83�^nm���G�������UI&���������F�C�o0�Wh����t��]^���k��,,,x}���"++��R)g���S�(77W����
���7E���'t��IZ�hQM�(Q����(�n�������fG���
�P�^^^j���T�1�Di������###�m��/�9s@��;wNm����K�W����c����C���uV\v���sDFF���
����7���=W����?U>|�p�k����7P�<xyyyJ�%�q��9t��A��^�y����u��xQo����W������X�r%�|�� "2D��������x/[ue�����7g�
����4�$22M�4A�~��|�r|���x�������q�(Q�M���X�b���|}}��P��d�r]3T��5k��Gt���=���� 33��/G��maff�~��C��5k�+�v�o�����
!\��U��+�V��?��w�+��P��d�r�7z#�\���{���5}(�D��P����>}:��������2�+V��G}�+V�_�~�3gk�U����!��8�������HLLT���"�:���~���u���c��X�|9{sZRR�/��B+:t(�R)�O&����g�<y2���
6�M�6X�~={���7m�;;;������~qq1��ooo�������{���
�5��G���AD�>}:�/_�n���`���	&��_U[���[����R(�Jabb��</;;}�����S���?�-���]�~FFF���XYY)������d�������S^,�~�:>����9S�WUU!<<�
��9s0~�x�����T,!!!���j����HNN���;v,��Y�f�#;�^w��	�;wN�=�r9�>���q���y]+0���BAA'�������{w����}��kE����H$���|}}1{�l������^��=
OOO,\���M����s��`��a������7F����8A������1b���[�=�~�){m�����0s�L������W �{�.233y?�RSS������D����c����8q"�M�ooo6���>�����aC9rD��Sbb���E�U X�j�F���Wl��A����;�s�N^�`cc��s������g���v&�P���r��o�F���1c��Y�F�-@������4��Or��v���	����A��=\]]!�Hx��(Q5!�@P���������7n�Pb�������acc������������I��t�������HIIAee��������=���"L�4	������u��
R�)e
PPP��>��5�����znjj�������������)�P��k������_~Q2G�7�������'6l�����#t�����J\�@`ii�U�V)��\.Gzz:��osss�]m\Q>>>��oBBB4>>��~
�H�o�����/��UUU���D��m9����q��Y8;;�U�V�!��/_��x����~��3�(��eee�7��5��������$�"����*M�����������m�����>S�����j�@��7]�����cZ�j�w�yG-�������ppp@�����7�q�L�����e�����`�Byii)6n��f��a��Ql�@(?u������|�o����-��b3{�l���O��IFr��z����W5�x�b�{��J��|��#F�@@@� �U 033�����F�q��'O�`�����C��f
(��_�U+W��G������3���;�}Euu5��������M����:qm�A
�}���/i�^��S��'1��J.��D"���RJOOg�����)::�bbb�i��TPP@<���j5�����T*e�y��%����l��z��M�����I�9s&=z��}]�z������^��y\.\���xrrr���t���c��WUU	�iii��eUUUt���q�������7)??��U�:t���x*,,dyee%�����1c8�&&&dee���t�B�"___��222�����k*++����t��m���+����L&c�������#t��]z���������G���J=������_Qff&u���._�����d�{���dddDC�������.]�(��g��u����V���SPPp���
		���j��	�w��^�z���������6�N�8A������o����)##�rrrh��u��_��}����)**���m���������s��f��;vP������D��}
�������
%$$�������u���;JH"�Prr�N���[t��%j����_�n���~k�������D�/_�F�Quu5��sG'�����y���k����+�����o������x���RRRh��)����j}OwwwZ�d�R�y�F�8_{��I�4i�����E�o��+\]]9}Epp0��y��w��g����������r._���C���j���w�+����������<rww���(��m\�o����BCC�����e��������9s&���Rnn.��}�8@������R��+J��j�0!J��
6`��Q8y�$���q��Y�����l;��s����77n����9z�����G����C�F�������Z��������?q��Adff������l���{��v����������.\[[[��v���Q�F���������RSS��R���a��=x�8}������������0h� |��'��q#�����TUUa����0a���QQQ��;w������z{����������#G�T� ���+>��s�d2<{��]�w��!v��P����v���$�����������GFF������[�d2����������xFF���+t��!!!���?`oo���Ud9��
�C����y��'� %�v�����uChh(BBB���������l�@XX�N �_�v�m���`�	v��-�GEE�m111l;����K�.�[�nJ+�^uApp��*M�v��K�l�ZA�����7h�<P�l[�����|�N��s����e|��W���e�
�m���cl;��sM�A��puu����O�<��]S��:}	x�Bh������D�$�@P������h���a��
9r$�.]��90z�h�LF.T[
XUU���8�^���� "����J���a��1X�z5�w���)����1s@�GEE��v����7��O>��dz�>��Sl��	�6mb�Y]]�#Fp.�j��!���[�e���>���(�;��d.�'N���S���uS+\�z}����)S4�j����;��������CBB�<mR�
����5�~���lq����r�
o���TII��~��!�@ JT����)��YYY���xzz��/���9����9��u�P�C����C��S'�|_u� ==]����g�|�*��Bm�AW_��9��k�
�|���O9}WH����y}���b��)3|||qM�A��h��E�.p�?8~�x���~�M�
R����X ��j��
��^RR�������7s`��9077����ZM:r��7o�C�)m��)&O��F�a�����L&_��*OIIQ+XXX��<&&&����'x�����aC<x���������G���s���GHH��_�?��]=aoo��w�*���H3���G���Q�~}���G����FFF���H$j��7o���{����D"��
���zI_����p��e4o�������o�����X��m���k�@�:%D����H$J�&��k�R)o��nmm�T<`$����/��|�k������V����]�v)����)�&M�����g�6�8%%)))HHH����g��1c��}���W ��]|_��&��7��+�
D��;���HHH@��-qM�A�������.���`���j�����))�U�3j����)..��_�N��������9p��
���Q��\\\835v�X
��k�*��MKK#SSS���?=x��3S���;dggGw����2���E/yrr2go�������Q�3�YYY���L&&&�����#4p�@���3
2����:q�=y��:D���4|�p***b�����/���������Z� �����O�����$���'�D�v����t��1***"��@M\&���7;;����O?��m������8�DD���J��SRR�����������������w��VVVt��u���{_Q�D�z��f���
�������1g��nbbB�����QQQ��L&�����%�D��RNN�k�}�������D3g��>}�P�N���������s�����1c�h��_�qi�
������sfh��|���W(J*���}}�"�����8y�$�����|�6_������z�-����c������J���4t�PZ�~��'?x� 5m����T�(����(mj��5���q��%v�a||����L�	����8q��db��a����


����s��*?u���
��C���;����8����eee����
_�5�����SH����U>|�p���-��7���g���P:��~�����puuEHH����8qz��rf�����!��p��q8::�����@�CC�\.��V�����@���)SSS,Y�eee�}�6f���w��"�'s@���9��7l����:t`��o���}\z��BCC���?b��E����?����G��P�.��\+���t���+t�$�|�2��_���H
�P�\�����j+�����;���\��Un��pqq��+n����#G���D�.>��4h���O��
����f��	�,J���X ��������������d|��G�������J���>z����TRU;v���������?�Xc��6>t�PH�Rv���C]�s��).��z�*�,Y"��=f������dee!88�.]��W����5�Xu��T*�����y�\���^�F999a�����e/^OOOXYY���1c����T�x��9@�<bm����-��3�������^����"$$$�^�������7�����[�x��6����;w�����(Q�S�}�����/f���^�zqf
,\�Pc��5s@���9�����0s�L������W �{�.233y?�RSS�����r[rss���#^������A��@�j�*��A����ao������L������\������|_&�"�����G��=����CM���W(r�L�3fh������7a�aDD�
�o777���S�"g���5|��D)K,�B9::�q�����V�Vxq1����acc��I���_+}���s-Z�`?��6m�O>����HIIQz���c���To�~��XXX�fL�4I#4h����mL�>��o��v���?����3��?��?��u���b��?�y��KKK�Z�J�gu�W�h�f����G�����=fff=z4���!���F����pvvF�V�xC
/_����i2
��~��3���?���������m>��3��]m\,�U;enn�;v�U�Vx��w�������M\&�a���h��%<<<834���Rl����5����O�:www�9_���o���e�x�kf����~�I�7��?�e�4a���������|���qS�\333��A��h��o�����y}��!U)��LE��G����Q)g�)0��w��
U^]]���$����fh����7�@����bl��	�g�f*�D�&���7Tr��$	���Rzz:�	�d���P��M����3� &&Fi����;������_OS�N%�DB����g���;���R�=�O�>��W_Q��
��g�������>�s�999Qzz:g�@||�F������W�.����3������,X@|�m���n��������"ggg��.����z���+�^�z��<bU^ZZ��O��������wo��u+��y�


h���j���y�BxNN���PII	5i��w.w�^�����������
F'N� ����7����������f��;vP������D��}
�������
%$$�e
����H$�����[����K��A�_�>g�g2._�L�5���j��M<55���VQk����+Wr^+���n�J~~~dee��d2�;����i�������L�����;wR^^����/���,,,8���'i��I��Q#�����F���W���r����J:s��d2���o���(� IDAT��������g�_�~]�������/�@�s����266V;gm�CW_������������<rww'�\��SUVVF/^d�j&�!��M���9}����u�V9rdM�(Q�����(
rpp@`` 6l��Q�F����Z3T�b��Y��*�<@@@�M�'''��N�
��[�����x��������{�N��|������e��k�.�5J��A�����\v�x���`jj�{n�N����3�c���c������}���s��AM���#G�T� ����������J�<�V���L&C��=�����g

�����$���`G�����?����=��Q�D�������[7���"$$zepq]3T�������K��������}S6o���W���������������������\+���t�P���B_M�8Q����#5f�fp����e|��W��C__��o_�����4|��1g�beh\\g&�.�������ZAPYY���D�;w��N�%�eH,�B��� ::eee��aF���K��f�=�3��Qbb"���S�N�
edd`����:u*Z�j�t�x��,mg2���4f����(���.]�<�Xq����3QZZ
�\����#  ��OG��������^^^j�c��Q�x��Q��A�b�:���"����Z�������sq�e�,@||<����v�����p���u^1S`��\�r����M���@ �������LX���&SSS�����!!!�����_~�1s@g2�����,��r<x�?��3��]�S�N!11�]�^YY��'O���f��!C�`������{���@0s�L�m}�����yyyHLL�����Z8^���j�
B}����>��#G*=V�?~<o&���s8x�`^�����5XRUL����k�������-Z�����������R�>}�tM�(Q��Pm��Att4�7��/���%o���9s`nn�����b�����bm��>���///+UTT�f�e������������+�������b�!|�'F����#++����
�W��%�Z�������sqUEGG�E�X�r�R�CU���CBB��}��+n�����X��m���������O�����������s�b����;�D�I$�Up��k�R)o��nmm
�����}����X�f
����rooo���K�?�U|}}�����D���Tv��g�����R��K|@�o�+v���>��������G�����qc��)��^d�o�����+�
D��;^���RBB��]���w���������-[�i��}�6_aeeU�������������h�����X�������a��&1�������������diiIyyy��7n� 5�9�fff4u�T:v�M�2E�{;::��)S����4d���4�L�;w������s�3s@�+#����q�����eff��q�h���t��]�988����i��]t��=��>�����N�Jfff���Saa�R3�W�w�����W��U{��:���+���������O>����������m��QJJ
������{)33�:u��t,���J}��q^���]�~�***X���,�nk������E����j�*������o��������M�(Q��f���
�������1g���m�6���/�:���z�I&�qf����D"��)''��_�V999Q||<����3$��������m�n�H$��;�����_�1qI�o�+233�}�k������������4>
�����L�@nn.���rfh���J���C__�(33�>������i��Qaa!������kW����h��i��kWJMMe�<y�JJJ���^�o��+����-Jee%�?�:v�H�����Rz��	eggSii)�����%K����3g�������(J�����[#<<�.]bG���k���$���� ��x�k���X�v-rrr�4����G�z����t�P��N�R[A0t�P����5K���r9�\��uI��n����{�QDL����U>|�p���-��7P�+.��;w.BCC�={�p�S�4i���]m������4����������W���w�aQ����EA��"E	�h�!�k4Q���%*%���0��x��Dl`���!DAA�HW�H)��������'
9��.?��
{�=��=k�u���2�|�23�����>����;����a��s������o�.��\�"�M/^MA�������Ryy9%&&���}�3D|���b����L�v�"{{{:~�8UWW3,,,��m�F������ �s'O��W�@]�{�n4h}����9�v4�o_jj*
4�=zDYYYL{A��DDg���[�nI�o��g�A���]��._q��a��b������c��i��	b�w��!5s�n&��8{����+Vp�������r�58�TTT����Z�hA���dRVV�i������i��U��{w�u�;�.]�D�������MMM�����O��Y�������{��W_}�U��%��A���!����4n�8Z�t)������v��I��M#'''9r$���/���"�����}����!ggg���$���7n���WK���f���y3����\]]��������/���3���c�R�v����������%K�����m�F=z� www*(( "�...��_���S(..&ggg�s���^�xAqqq�c��>���W�j�C��s�D�^���={����c��mKZZZbm����q����?�(1O���x��a�_������N���K3f� www�����'�����%������X�0a��_��5k��q����'������p����Sxx8UUU�>�YYY�����������|S�����)..����@��Ws����=��.]Jvvv4z�h��^ee%]�r�&M�D4�|�8q�L^{[xxx8ikk��}0`SX����g�����%��^����|||h��)��/�����i�������
���������sr���)))�����g�(%%�������m[��3����g�2m��M�E��������������Y�b��m�B���prssc]W]�
)��i����L1���000`���
�0�Ec��"�}E�����7nJ���N&L +++�|����UUU���/�f"j�
�R}�,_����X��ss]�Y�F�����)�@�ellL���b�D"����]�vdkkK/_���x�b���!{{{JNNf��{�f][UU��=�455��_~a�"�����#G�$---���@@��w����������Y"�U�UUU���ElgQvv6M�8�\\\Xw�B!��=��������3������w�����������S�gffR���IIII��-hjjJ|%
)11��u�F������+����_�{[�n���q~�MMM�c����Q��%��f��-f2D���{�����LLL$��($$��t�B]�t�)��� kkk����7h����Y<00�-Z$����������+9s7�8_ ���iJ]]�<<<����,--��?��eee���G���4t�P�}��T����	�B����1�._�L���t��211�a���������$
D?$�������h��I�T��W�^%�6W�`��m�����Ad�����~��3���O���t��a������'���$GGG�s����������H�f��3g���d���
jjjR}�,_���N...L�dm�����{�8���z������|����+�����dhh(�3!*�8�� ��W<x�9v���B@qq1�/		�K�.�2Y�Ao��`O.�;wN"����������P(D���QYY���D�?���x���>}���;�������-�}�6^�x333��� 99������`���2������!��w��y�z�
_~�%��������F������2yzz:Z�h!q�����_���}�"11L�}mnee���X�{����+++������7ob���x������?���H<���b��g��j�Jb}���8�<��}����������cxII	N�>����9R�������� �c�����s�PPP�A�!,,L*�t�����q�����!44�O�f}\###��?~~~HNNFJJ
<mmm�LcccDFF������dff&�^����JXXX�������"$$����9����

���1+3f```� >m�4x{{C__�A���������m���W����PTTD�����{�
UUUhkk#66V*���d����K�n���'&M��������000��y������TUU���'���@������/_2}����2yBB�D�;�6n�'''�������wc�������<���lmm��O?��
�w�<�+V�M�6������������z���Oc���PQQi����T� �W��������o���*q���
������8p���E������+"##Y}EAA��G����W��?jjj��jjj<x0����9l��
s�v��4� �W4wihh�=�����sNO����_ h�j���l��#F   ���(,,���	777���'O���_
___��u�^|��Q8u�,,,������0!88X��k����

EQQ�\��={�`���������������"\�|Yn^;��������g-Z�����������?Gqq�?s�Z�n�M�6!))	���8u�v����k�2|��Ux��5�������;v`���8{�,����n�:ddd������X�j���������������b��]puu���g!�b�
�{yya��������s��x��JJJ(,,���k����@OOO9r����/��}+���s���b�511��
��?0��B!��uccc,[��|��XP�������WWW������C�y�&�����o���7o�����������Gakk+�a��t���;���_��������������3F����g���{�q��x�_B�iii������+�������?|}}�h�"��sG*�������s%>������������c������w�^hii���c�0a.^���/������Ryhh(Y��)�
6�w����~jy{{K�
�|����aoo/������CBB�X�/(**b���h��k0odd��o��;�����*V_�t�R��Eee%�����0`s���{#$$���d�/[�L��E��O�<A�=��'O�D~~>�����Y����4-X�������������7055����KN}���8djjJ�=���
��?M�2���Y��90u�TZ�~�\�-s`��i������A�dr�L����K���=z$R��wo���3f����g��I ��z�f����XZZ*��z�f�����W����W"�����4n�8�;w���@Y���Y�U��\]]i���4j�(������bm�������lmm9{E����A�Qhh(}�255e���9l��:u* +++Z�v-	�Bz��3�i��q�~�z���|����%�����qjUUUt��-����e��qfH���?g�I������_�l�;w�$Z���Y3&O�L�V���$�q�����5����9��1����k��,� ��Vhh(���S�OKK�����Z�j������=K���'___��._QTT��+���9��w4�W��c����'��RQQ!___Z�h�[�`��7�6n�(�7�����M�����TPP��o��m����Rbb"%%%I������_��Rx�_ h����+�SXXH�W�&MMMZ�`k���%KH]]].��90w�\RSS��$���2&M�D***��uy||�D�@CC��7p��Q������������Z�n��I ��{��,,,HII��7P���$j��g&������K���W��S'���`�
��w���tuu)88X��k�S�NI��4UUUQhh(���Q���Y{E���B�dDDD���s�/4}J�t�;w.���W3�>|�@�}���df^���������������#��m[2dk��4^;�����f��IB���={FO�>�x|�PH+V�����K6l���9�u�V���"kkk�|���t��Q������l� �}�f���NC����'��HUU�)hjj����Y��w�
�A�-8}GC}Em��w��_����}��4e����P(���(�wH�
�|���V�/���JL���?�q����^����4aUVV"""/^�@�N� X3^�zccc�8[�@rr2LLL���[��+S������rq�mc���x��%ko`vv6�w�.�E�������7�={��I��E�������go ��UTT����3�����\VV��������z�b�
�����9BBB�Y�D���,�:u��b<''���O���-[�s�����"��cGDGG������b�n�������b3����p��%�j�
NNN�q%%%L�8����c��x�[D����� ))	aaa������
k��4���k�}�M�6�7o.\�������x�-Z���={��`555��111���Euu�T^ZZ��������L%�7��"��3����K�.!<<������������S'����puu�����F����R����:v���;����������C������i��!''/^��x��=���|��|�,_��eK��5��<���0i�$L�<��������������:�|�	^\�����u��_���:���cFSAA]�z�i+HHH��O�>�n��M�����$%%���e�3fPxx8R@@�6�����8��/^�(��`��q����O�RQQ���1��222$����6���-6�X/..����3������QCiiir����j������&L��A�v�Z222���/3�����Q^^���3��d�k��QRR}������@yyy���;��q#�����111���M���N�������l��~�:3�H4��.�8��i��������������;�B!���������������'''�����'��_?��^�p�n�������W����L���#�@@qqqdggG'N��2#���K�������6���������@��o'ooo�����D�v���ob<88��L�B'O�����Shh(�V���f�!��?
:����K��\;���9G�7xUU���i�M��� --M�o��k?���K9�!R`` u�����;����C�|����Y}��'$v�\���w��+rrr$�222����v��A%s�!���vnn�����d�
SS�&����������x5w��&(CCC������h��(S`��i�����9 �����������C���Y|�����];�zEc�3�XZ����3ery�K�\�l����9l��-iii����W���B!SX�`�&����G..k�,^]]�	�������

���.���Sxx8�����,z��q�yFF���p~������)..����\\\�n������(���PBB��Z/^�����=��.]Jvvv4z�h���I�&���g&��I������~����"A]�2�L�B���g��4���@����9�
��������!���g����`M�(e��������������Y��v{������zJSRR���G�����;����
V_1l�00`s\4�P�� ��+jk��]��M�-�����AE������p��i��h��hc��y�������$�@�ellL���4k�,���c���'GGGj������fH���/^L:::���x^^��=�45593d��#G���sLT  �^���*g���Q�dry�K�\�l���455i���b?+��b.^]]MO�<!333����D��,��y�D�9			�.]�P�.]��/�`X�ADDY[[3������ IDAT��q���=[l�v}x`` -Z�H��'/�����+WRVVV�xs/�[����VYYI@�5''��N��9���W����NdllL���v�������

i�����������������S��]IQQ�:t�@&L�����555�Ao"���;IOO�&M���9 �_�z�,,,��\�m�����+�����c�����~��>y������H����g��Eg��a��Q�������Y���sVZZJ?���k M�w����hN���+��pss�����L244��D��w��
"S�.]�������K�����c����S(�:u��������@���?U|A�P(D���QYY���Df��(S�������3���X3����o���033CNNk��4~��
�z�
_~�%���X3d���t��L��Wlee���X�����T�\�y��8W��<��RPP@TT�<bY���8!77�.]Bii)���+�9 ���G,���� 55!!!}}}�E���GPP���Y��1c 6c�>|��i�����),����������
��U?��&L�������GBB�����������S����0j����Z^�����PTTD��#�9
UUUhkk�f�j����~��=���������
999�v�����!C� &&�y|ddd�����?��w���UQ�@DD:t���i<!!A���7n����7]W�w������z�������p�B���7��>}3g���'/����T� �W1�RQQ��;0a���]555���������"22��WH�����|�,_!Rpp0?~����c���������<��������?0w�\��Zuu�T��_������X���!###
�������S)00���uy}3���d�����']]]�z}}}i������o�@]�����\Z�@�L��!C�4(s���'s�.oHo`]�����:�u�=z��������4EGG��	�w���b�
��������u���:w�L���������Z^�����

2������8�7s@������m���~��wf�Ayy9EDD����N�|�
�l��Z�l)�S!55���9C�'O&//�e����_'+++����8��S^�xQ�,����7�III����|{��C���!������i�$v�m��~������W�]��5���w��j������|�SSSi��a���,v�����w4�W����;x��LjA�G�75u��������7�9�;w����QQQ����/_cccTTT`��}������=z$�<K�.���>�����o�!>>��u��;w0j�(�|��	X�h��o���2l��	�������^��������|�
&M��w������o�>TWWc��E������&JKK�z�j����g��8{��/))��e�PQQ���{���k���?��������h�����������f�����L^TT��3gBKK�����s'<==1}�t��^���?�����p��5l��	:::�����#Gp��X[[����p�B��}��066��s�����q�����������h���T����v��������kF�
�P�/^���	:t�����WWW>>�������k��}����?~��o�t5j0u����^�x����
���1e�TWW���{��o

QRR�@�M�6���UUU���?p��Q1%%%���������,�����������_~����J\�t	�O����1�������5k��{��������q��U������7RyBB����g��~��7��������}b?��-[�`���>N�x��=��Y�B$'''(**2�����7o�0�C����3���q��8Pl}���������r���h���\����F�W(**���
w��e����#�������m���?��3�����������?J}������7������N���_�k�� "����������]k���~�:��;���7�u������'x��k��L8Naa!�^��455i����K�,!uuu�8[����sIMM�3��6g��4i���pf�����S4444�8;;�����u�������1������K� HHH�:�X��b�f��=����3�X���>��� 333�6���y����t��:z�(s�����AU�x5e���Qjj*s�����9Bm���!C��fH�NNN�&�$,'RII	������Y[[�fl������d��3g���G����Ww��d�Y��h��%��iiit��	����.]����v:t�bbbh��b���j���|����-Zp�y|��������+������G����������h������w�����g4aUVV"""/^�@�N� X3^�zccc�8[�@rr2LLL���[��+S������rq��tQ��>��E�������7�={��9����G,��z������\VV&6�X��b.|�7��9P{1�g�,��cGDGG�����L�7'5;���b���4h����c��������{�7o���?�*y���������ARR����������\��
|�A���,�o���5�W�^�WUU��������uk�����������Z*/--EFF���j���dq����1o�<���0����?��#|}}����������X�`TTTp��9,[����o��5s>y}Eii�T_Q[;v�����1c���o���?~<�m������8++�������


���7�W�l���1x�����/4AUWW��������w/:w���g�b��A�����[�PXX�?��nnn�����?/���@XX���777�5
/^D��=er777DGG����/_��={0}�t\�t	]�t������V�>}��];�������(..���g�g�,Z�AAA���S��k��]��W��M�6��i���d������b��]puuEpp0����n�:ddd�������!!!X�b���$x��}%�����8r��������k�"??����rqooo���"99�6mB~~>�������s���������?���
�@���t:t7o������ &&nnnx��-c�����~�l,
�����7W����������}�v\�v
C�a���2\\\�x�bl���3����I(���x��=p���<y�s�|||���{���b�����?�d�g``;;;���3EQ.YZZ2�t������S�b��}�x�".^�������c����������1m�4���o���[��*����H
3l,����Z4���<�AB@��=������l��9��=����������������c��a���nsss��l����H��mll8}�<�b���������A�������y3�w�]]]��9������Gyy9�?���t���Kl-�^�b^�m����c�����(_������������O�i��,��?�H�����K���������HQ����H(':;;3�����eee2�(xp���L aNN}$;v,�k���^�����+vqqaEAj���L0�,.�<bi���ai����9l��-iii�m��5�X
�L@��X�K��������N'N$;;;���!CCCf��[���)<<\lntmeee�����322(&&F,��><99�������{�����i���b�Z+W�d����K9�^������h����t�R������G3��+++�`B&��.���`�WXXHS�N��-[���6kx����666$�����K4e����_�@�/^QEEL������9W�A||<%%%I�����3JIIi0�������1������������899I�
�|��m��k���/���m�6�}��6l�X��h��4�A$�W����@�n����:v�-\��LLL��(P���������3f0^U$�P�(_��9�����/4A�����9S�,//��/_N����PBBB�xNN���R��mi��%I��xVV������69::RFFF���a�HKK�9&*�}����O����a�����yWWW�m��Id
ddd����erUUU��{7k��W_}%?p��UJJ
��������[ ����H
����233#:r�H�xuu5=z��LMM�S�Nt���z���J�}�6����_|Ag�������+W�P�������LLLV�@Es�����4�������;�x�b�_Y���+�b�
z��]����?m���)l���{�`�����
���R�~�������N ###������`1^RRB���d``@C���7oJ��o�2�w��MC���c�R���%z�g��Ak���!C�PTT��z\\\(;;[��;v� ===���f2�D*((�����������U ��{7���s,6m�D^^^TXX� ���H�N������E�������L&g+hhhH�
�|���&m����N����r��l�.��;;;�}G]������>����9&*�8���M�o���Iu�v��q��]]]�1c������)���K�|c|_ �����o1h�
�044d]���|�M�}�6��G���">>���r����#))	}���@ ���/���%%%2ypp0RSS���_#33�_�fz3��������PP�|�����{���#))	IIIL�Am>b�<�o��a�{��������������#%%���XPP�����<x���4f��'N�@yy9��/�kKAA���L�(!;;�����Q�&7
����@`` Z�h��"<<o������� 99AAAPRRB��}���#dee��������k���@MM
����[Q���+���������1G����~�����w�^���5���3...h��}�xsU�-��ovv6����WS������F�����eWVV���g�{�.:t�===���H��	��^���{��d��8q.���*��?�]�v���7n��6m"����L���GTT�t����[#..�i](//GDD'/++C\\����"�^�+W�����u�V���q����nnn�;w.�������1e�(++7����_�o��+���������o������Wb�b��}�6m=z��o���L�?��o_^���+*++��U+�k��;d������_�������������b��yb���������������III�	B��Q��/^�O|��	JAANNN3f���p��Udgg�?���9+++9r����gq��u��������;x{{�O�>8v�BCC������/��mllp��Q��������������������O�x#������?����x�b=zpwwGtt4�������ttt�����|�������X�z�L����d�~��^^^���������555X�v-��� p��!=z������������8;;#==���8x� .\������C(--��gdd���:t�w�F~~>�o�.�gff�������?~l����k�\�������@bb"<<<0o�<�+��#�P(6��K���8w�,,,>��x�j��B!����������#..���x�����������J>|.Ddd�OIIa�7~�x�[��	}�����������BUU������=z�������]�rzzz������5�_����@dee���{8|�0'�y�&�^��Zt�_������Y������a������/q��1������[��b���055e]Wdd$���#��`�vvv����
N�!���^����#G�������8}�4��a���b�����X6Onn.����+��a�555����������9�j�jA�����k�����G���q��	��q����������,YCCCTTT���<����?.��1����������
������'066Fdd$���;�|����?>��m���r�������011���wacc#�:���Lp������������c������@YY6n����4t������3���C�n�p��%�^�3g�����L^RR�e�����=z�@@@�o��i���U�V2yqq1.\����&-�7\�'&&���,�1�788;w�D��-ajj�.���
����14n��e2���"��	RSS�f���M�6h��-?~WWW>B�/_����������HLL��m�0h� <|����g)����'O��=�S4j�(888`����{)
��k��n�:;v_�5�������}RRR0}�t4����\K���^RQQ���g1q�DTWW����8p����Q^^���J899�O�>������7���#������S'����=���'����x�b�?���SSS���P������Bvv6:t�pww����ann���J�;wAAA���Eff&����r�JV����~�O�>���oHKK�������~F
0[�l���c|����{())I�
��(++c<���
���ajj*��())���-q_ADpss���wNNN�n6�!��
�puu��\WTT�M�6R�3c��������	`���(..FXXX�}��[�p��y<��/�O��/_����x��
������������%K����������o6���H�����tu����1���H���4�|���������\�-s`��Y���N?���L��)0a�RUU��+W�����IOO�����/ihh���ko��#HEE��gdd�W_}E������xZZ���S�6m8{�qQo���g&���>ihh�e���RBB=��:v�H������p===���c������uuu�K�.������\�{��t��E�EDD���s�v�?U�=������~��-[��a�����L;w�����S���	u���	����9HMMMl&}YYyxxP��mi������xm}���3��MUUU4p�@���
|+((��7���M�8�5�@�mll��������p����2��OD�}Cs��/_�a��1�Y�~=)((p����
Y���!�@ �C/<u�T���k�����j6�����];�6m9::��_M����k244����
0��>}J���A���t����|�x������UVV�������W033CQQk�@rr2�w�.g����D��=���+�se
������rqQ�_mijj����������������L���
8qqq��\\��'
1t�P��@..��k��F���I��U+������>}m�����Y3��������/k���drMMMXXX��^�vM.��K<~�999�[��������W#<<��������s�N<z�����{�.TTT>�Ry��[D�l����B||<>|�N�:AGG�5s��������$�GRSS�����{�u�a�V�0~�x�od���%2�����_@AA�5�@�+++����%�7�������Q����@���-cccN��P_QVV���d<z�qqqpww�
���������_?���3�kaa!�my^^g����BQQ����O���b�Y��o�F`` �����~�	s��AQQ������J��� 88�{����"����[�na����w���)�/4AUWWC ����������9�?����sf�8qB.��9p��)XZZ��\������������K\s��=add�� ��f
�9sm����������={Vjo ���w��y��={������\�p�����93dqOOOxxxpf�������9{��[�lARR������L�������&�������X^SS�����7g�n�;w�Dll,���c��9�������q��
�c���{��x�KD��'O�������e2�=
{{{��.WWW<~�X�q*++���Cl��~~~�����[�p��1���1�svvf���[��2���0}�t�L???�?aaar�kWUU�����yee���v&'� IDAT��������Y�"//�Q�B��+���X}Enn�D���I�8}GC}���+���@uuu���s���C�"77W�����gggxxx4�Whiiq����N�<�U�VI��E�a��Q>|8233��E�<y:::b�������q���O�l^���� h�222��A�P\\sss888�����x��!��9 ��������022��G�X3�q$&&�K�.

e���������������+���������SSS�����fdd�����7P ����>|@�n�dr???���=z�eL�<�'Of2��k%%%����f
���H�����g
�]��[�F��Y3����o��-PQQ���ko ����jjj(,,Kc��A������X:�5	_d� ����w�������Y����(,,d*�����A���?U���>|8:v��|��}�v��___�������5�@��!n��������CYYk��A�=PUU��W�"""[�neM�?u��\�]]]ddd�fp�>`��
���/pg<}�������Z�l)����Hhii��/�h���>���YCe�;w��k�������
$�A�j�*��s��7�����

j����76�W`��=�"++UUU����1�@(�����w��W�?���PSS���-Z�����������������/]��7of��t��]�1�l�2<x�����������T^���'ni�%����IGG�f��IO�>cyyy�|�rj��=-X��5s@���![[[j��--Y��5s@���"���&GGG��Y|��a����������'�������9{�.��;�X���c�G<i�$�MMMrvv�YY��e���jz�����R�N�X3����+&"����+W�P�������LLLV;� **����Ciii���;wh������� ~��Z�b�{��A����6l���W���	l����?����l�B�������$^��%uuu:p����%�������&:t(k&�4^TTD{��%}}}���o�����|��1���3�����c����#kkk��i<((�,,,��\�w�&www����M����K��\^���H�N������E�������L&g� �����d�
MM�F�
o����{��u�2	����[�~=�]���l���y�
�f�A�p�B�\���r233#��S'��7DDaaa�n���s��x�K|�A�P(���!�B!^�x���b��)����=z����5s@�~�:�����O��i<88������������9 �����~;P�y�#F�����Y{���dry�K�\�l���JAA�����\��eqQ�@`` Z�h���fpqY��e���j�~�!!!PSS���1�V����
���044d�#F���#G���� >q�D������/�3g\\\��������O�CCC���b��Y "|���G���1c����c������Btt��^./^r�����hkk�s��������{�.:t�===�L.���DEE1;�455���SH���B������e
DEE�K�.h��5k�/++C\\�\�/�W����+Y3q`���������F�������55�qoooL�2�u��<���R}�,_1x��F�
o������?_QYY)��_������+�Ba�|EsQ�^�+q|���HLLd�����<y�n���mk�����MP


prr��1c��W�";;[,S���#<x0g��4��w����}������mllp��Q���qfH���O��^UUU�y�>>>��k�����#���e��G���&���������@�y��x���C�a�����u�<��e��/_�����������y����f����
CTT��9�-Z`����{�.���[��� <<�o������^./^rK("//���X�|9���X3>��rf��YYYx��!>eee>|�f���{�p��)�x�L///X[[sf���7o�����E��5���_�o��+�=�(_!���m��a�vvv����
N��X_����(_!�����j4��5�����={?������}����|yy98��#G~����%���&��]�����{���'p��
���#>>�5s@4s����2��#$2�<ycccDFF�f���'O��x��%LLLp��]����|������f�������EE�O:�X�y����7�W\�w����d���!88;w��{^���A���5k�����#���������m��a��Ax��!������_� ����g�Z�
�w�fz��������Ebb"�v������.�y5��������8q"�p��hkk����5s���G&o��k�������YYY��AAA���Eff�T����~�O�>��A�O��$2��%%%�����������o��())���-q_ADpss���w|� ���Bj��h��%����+D<,,������[8�|�� ��g��������Azz:�o��@�>}�����h��F��#F��_���: ;;s��E�n�8�	x��,��-
��P��]�C�@@������I���g�X�x1ihh���2f��E�����O?��l�&L UUUZ�r�\<>>�������������?f^1���� ���������e�+q===���c�
�������G,�w���.^�����233cn�� ����g�Z�J�����	���J�700�BCC?��x�j����(55��]VVF��m[<x0k��<\GG�F���9�k�.����Y36n�HZZZ2���
y{{S�>}��A�O[�h��,��}����i��a�}��_O


������c����"�_����,2D����Y�f���)����6m�$������dU>�,--IQQ�lll����3��/I�{������p��}�z�
fff(**b�HNNF�����l�������'rsser�L�~��!==].�6"NSS���+�g�4.����W\���|H�G,k^������o�����.\����G,�w���?FNN��������������$����[�>b^���������B||<>|�N�:AGG�5s@ndd�����(����k�@\\�������)))���l����n_QXX�(_QPP �W����1��h��h��M�|��7�W�Mj����N�>���_���gSKtuuq��m�<y����w�}���`�9sm����+��KR|��	����7o�������q��q>�3s���rq���S�N���R&���������\<>>^��{��Y�y���#����#��k����W��IPw>.H�G,k^��{zz�����7P�g�,�e�$%%a������DJJ
k!�h"*++9_���555���)xsUqq��u]�v
0f���UWW#44�z��������""�<yo��Ell,�)p��Q���sf������?>g��<|�����~~~2����&W�vUU�A������R�7�����d�����F�
o�����b����b=�0i�$N��X_q���F�
o�������]7W)((`��I�����;v`��1h����^/^�3�����0h� ���011a2Di����������;�>}
###<z��5s@wqqAbb"�t����P��Y\��Inn.��W�\���������G��-,,��G,����q����G<y�dL�<�� h��������#�<bY���W��e�#��kjj�]�vAMM
���bi���������[7TUU���ZZZ�o�>|@EE444�+**PYY	uu����rTWWCMM�^\����?�,�3�A�������aoo��W�b���011ABB*�����,��dy�j�RWW������cG�[�����e
���BGG�����\\�)p���k������\\�)p�����"##�5s����6l@pp0^�|	�;�����PTTD�n������������������0�������54Q�s��v�
}}}�|��A�V���;w8}�,_ajj�����
��qc�}E@@���#�+���PUU���3�B!���9}�y}!!!����{�����n�x����[x�!ccc�����3g���O�X^^-_����oO,`���srr������mKK�,a�����������������5s@6liii1�|}}i���D$��by�sqy�K�\�l��'M�$�A���I���b?���UTT��+W�s��dbbB&&&stt$]]]���/�M�6���J=z�����3��J��ukRWW��={�����Q���ISS�z��]onjjJJJJ���M}���C���555i��}����C�������{���/��(44��B


�:t�@iii�y��x�'uuu:p����%�������&:t(k��4^TTD{��%}}}���oY3������c������5k��4D�m����w���;	��i��M����9�]wtt�S�NQqqq���E�����b}�\�-�@CCC�o��+455�+D�1�b����-�$���/sl����v�Z������+,,,�U/^�$IU���%
aff<y�FFF���Faa!�������W���BEEbbb����w�aM�o�Y�B#� KT@���:(��:PZ;�U��pTZ���@]�Z-��E�A@e2�U�"�� H�|�?xs^"'���W�����$���:A�x�|��67��U����_x��!F����Jdgg�{��000@UU+?u����1f����[066F�n�PQQ������v�����Cyy9�����<��}���tuue��)Sp��-���`������AYY<�H��?��C\�v
���pqq���&�={�?��b�X!�����c�R��%%%���>���6����������������"$$]�t���;._�777�xss3


p�����c���r�
F�	;;;V�������aaa066����^��a���g���\,������������)���C�_:fff�������@����������~�:���ccc�������?>,,,������F����?��fff���������+���S{�l���~���%z�����c��Y����������"����������A.��P]]-�I0t�P>|�z����n0P������XZZ�W�^HMM���������[[[������B���IIIHJJB������������{S������"!!��_G�~�```������<���D"ddd(���l�2F�~�z�x@@�J|��}*�1c�0�6_1~�x�|����+�]���w���
m�����wt��hnnV�W���Z'�u������PKV;v���u�`cc���466���1118|�0F���~�	���������&�\�B���C�4i�/_�������k��000���gq��QF~����1^^^())Att4�������S�N�����|��������Jvv6n��	�H��'Ob��yX�x1���
�@9r��^^^�u������gOhjj"44�N���e���ky|���HIIAtt4z��
B����
6�����_�t	���pqqASSv�����b�������P(���3���RRR������:����.]����1{�l���"!!�����UUU���_q��ul����OG\\RRR��o_F������R�������/���>����������+/,,Dpp0JJJ���������p��5���BGG���puu������[[[�8l]]6n��A�����������5�����{�2������X�~=������X���999���?X�����]+++\�xeee�������'O���	����a���!

�6}�:::000���	�����r���ju������
���5;�;�����B������b������'V�\	SSS��������wGJJ
#OLL����!����	�z�*���1e�����s���?���{{{-^DFF���'r}��X�x1rrr��R~��9�}EJJ
��;��W��=O�<�V����P[[���,Z���[o��+���U�R�k�.�}��C����kk���USK���Rg��rpp��#G0`�?~B�\.>��Q����_S�����">>������g������9s������K*T���#77�&Mb���O������#00YYY���2331c�V>l�0�������Z2�m���y����O>���2���+++�������:�Y�<���-����l�2xxx�k������X�|9JJJ`oo���(l��S�L���6+����?����*�����KZ������a���T�@ �P(���;!�`kk�K�.a���x���eeeX�|9+������9�_�N��I�X�z5���yCCLLLp��=l��#F��D"��������X��9JJJ�z�j:������/q��}-z��������C����[�na����H$�������b�
8����v����


hii�����B�l�2���MMMHLLDHHttt���mmmV�b�
*'!::G����jkkabb�%K�����u+>����<1�;�������s���6���


DEEa��M�v�x<.\�N�0���_���#,,�&M�f�����5�����B���WVV�g��������=�b1���/��������?g�O�>��ENN����� �7i���m2*++������i_QWW�e��)�+^�x�������hhh@@@�d��������w�����+D",--��R������HLL��S��j��z�[
j������1,++#�-"\.���=�����\[ZZJ���kbhh������O�>%�|�	�p8d�������P���'�h�"�xnn.�5!!!���ooo���3��?~���=����������n����k����d�����t��������/_��������G���rCCC�333r�����E������1��g��k����|>�����?��S�766�+W�������^�z�������r������	�Xjj*���7�8((����{2����#aaa���''')�kkkIhh(155%�f����2�������������#G��WUU???bllL��K��!C����Ig��U����!���&B��B����������+��y3���"���'�W����UK-�e``@=zD=���Ui6H�����O�2��������r���?###V�������0���2�M�� ���$������+"""���+u��������;T�fff*�
)W�W�3�R���>#�K$���K�����A�P__�7nP}�������FQQ���y�&jkk����;w��?�;�����JV~��m���h������H$����Q\\����366FAArrr����%� ,,b�c��i����p��Qhhh`��q���Ann.U����={�@OO|�222p��j��������?�����L����$*E�U��������2>|<���>����o�	!(**R��9)))����}�aaa�����
Bjj*������{��!22R!������4�������NlEE��b1rss
899!==O�<��Tp��
$$$����������������z\�~�������M�����)))��������������_�x����3�G����������k///477c��������	�{������|�j���$	��.���
t\����������E�������+W�=u6yyy�������7������L%_!�$��+Z���^��P�W�x<�|����+��9j�����:��
T`` F���w�����p]� IDATqq��U����!7s���!���B���+V���Vn&���?�6s������r3	Zs���/�d������rw�-[����w��Ef���d�
|�kii���-Y��q7������:��h�"���W3	>|'''*�`��mhhh@RR�o��o���q7��a�����L<  ���rw�l�����+�)p��
���a��%Z2RSSQ]]MeH3�����{�A(�f���b���r3	�����{�7n���������nox���������b)�������',X@=�������n������2�f"����033��[UK�v���:::���75;455�5�����B��������X�f
�|>#�p8�p�jjj�p�B�3�b1$	mE!����E����/����4�������B�.�`��98}��\���+tttT�R���������
��}[&�������w���S%_�}�v��9Si_!�QQQJ����hu�Zju��o����1d�444���������
�)�������f0�={� --
<999��L<  7o��@ @FFm��r�
����oDBCC��G�������������iw���+++����?���5#������@��'?{�,��_mm-���e2	<<<���Ae�x<b��}mv����aee%w7������[�f
���iw�q����������riw�qi��4�������x�����K�.���tuue2�{����e^�2�xBB���444��
����P�������vo����r�����r��N�A�v�Z�����HL�6
���.d�=q��|>�����R-��/��q�����@��X�zu�f�<��l`��L������g��L|��������c�e����K�.���?m�����abb��}��&�����XXYY�����C6.
���kkkV>r��6�}�233��6_aaa���D�}���^�Zi_�-[������Css3RSS�dH$�^�Z��:�WBp��=�}�������� PK���k_jP�U666����|���$33S���������t�����3�6s��?}����3��x<2o�<��&^TTD>��#bbbB/^L�9��G�I�����BBB���!�e7p��	�������O���&L \.W�n���#Y�������(�������>m�4�.�K|||d^���L��������x���L����$%%[[[beeE���Htt4���'qpp��
d�uuu$<<�X[[;;;��W/��/���������, �e/��������2�6s�������~��XXX���G��
���[�R]�t{�L����Sgl��Q����6����l�2�����ukj���8	��f�l`����d��uD ��S��f0�3g�GGG����_�����*���/��B8@jjj���V�"aaa���V)�d�r��yRWW���2�\.�o`����*�
)W�W����y��L��R����ooo���B:��pttTg��VI�A�J"��w�����Bvv6*++�_�@~~>�
�XL�9����;���B�1�����L<""��=���JJJh3��H$�=B(�
������c��������*L�4	����������|���rw�����v����1}�t��A---dff���;t��v����'�������'N���c����
����055����iw�qi��P(�@ @����d���P|��2������8XYY�O�>��L�����r�
z��kkk��a6.�'��x�{�L��g�R�KKKMMM|��2�$%%A$�G�q�j��nBp��U����� �+2��4S ;;������m��<.�����f���������Nr���~�	s����Q�o���1���������4iR��UE����o`�c��U�WH�*�"##��Whii���`��+���U��_t��}�8q�����>��`�Zo��o�v���u�����111hll����L��O?����f�����C�0i�$,_�555r3��#G�`�����BII���&>u�Tdff�d��y"�H��b///�������+�G��/]�$7s�u����B!�������@���!%%E�>b&��_?���Y���xaa!�)���������@KAll,ttt���WWW���q���:l����*������w���[s###���333q���N�A0h� L�6
�����U����3���O�9s&���???,Y����d��Zo�|}}aee�_~�����
t���R����SSS�L��+W���Tn�OLL����!����	@~��It���x���\���+/^����}���;wNi_����s�����g���'Od2jkk���E�;�z�-�|����J�B�w�����8t���>�`���pww��0y�d���`���������Zju��o�p��0���P(�����i3���ajj���|V>n��6�)))��������$h��O��&S ++=z�@ff&m���|��apww���	

��m���p^k_�"}�L\��j_����UUU������K��@�P��;w*�G������#��X���8����HNN��_~I}�c�������2n������C"��[�n���n�9�g�hhh@KK�6��5'�(�e���X�B�.���Zddd`����6�h�6r���(,,���<<<��9r��NCC�W����mG��Zj),}}}���a��I����{w�f���Uh60���J�����pP������O��r���C���A�o�����dTVVBWW��7��������-S�W�x���}_������$&&h� ���Guu5�����Q�W�D"XZZ*�+�<''Gi_����S�N��3���q��9XYYQ'*	!��g����@U��z�z�;
j�����\�v�BHYYY�h�r�d�����_�5144T��e|��'�����s��r�L��'�h�"�xnn.�5!!!����k�������L����s���}�L\�>by\�>b6���$�)���Jz��M=

"���������HXX��x����6s 44��������re�����t��;�2�Sg����U���G����Z�f��+:���)Sh3~��gbdd��?��c�����P\^��It����v��}EDDquu�����!ZZZr}������L%_!���
##�}AVV���/��s���'O������+��Rg���D�t����1h� ����fa���
q��������w�Aee%+��)0z�h+��bq��jll�����#f���?y}��9��k������#f��������q'''�L����6;�2����������
���h3`gg[[[V�l�yk�l������"��?|���;w.�|FFV�X�H��w��Z��D"AII	�����
t\�������h3rss����� //���0�p����W�����+�={��+Z���^��P�W�x<�|����+�t���/��`����<yr��G���j��OK�A�*00#G����wq��A���`��U�����9���?����B!m���+P[[+7�@���?O�9������R���9�����e2���������t��R_����B}�L|�������}�t�>����S�m�6444 ))I�>b&�P�<��G����+�) 
\�d	�����TTWWS������{
������:t��L)�p��R]����]�={�Dddd�� �c��a����p�n�����
���G����	��[��[��RL~~~���A�����������@�����
L���Ln���5k���9����PSS����A �!�H���C��dyG�����/����4�������B�.�`��98}��\���+tttT�R���������
��}[&�������w���S%_�}�v��9Si_!�QQQJ�����}�Zj��Rg�������!C�����?666T�@bb"LLL���G�9��������4�x<����f0�����y���l���+HOO��	

Edd$�=�p_����B}����}�L������t}�����2x<

�o�>����8Q�������K3��^�����G��d\�t�J������,�����o�y��`�			Jw�Kyhh�R]����>|8V�\�i3233����o���|�	��+W"((H�:������;�F�R���p87n

�����W�k6����&.��������={F�9����]�����s�����Tt��������N������abb��}��&�����XXYY�����C6.
���kkkV>r��6�}�233��6_aaa���D�}���^�Zi_�-[������Css3RSS�dH$�^�Z��:�WBp��=�}��������� ���Czz:��������Zm��w�b���
111!�~�)����a�������#��w's����`�O�>%s��!<���7�6s����>���������f���#G###�������AQ��X�>by\�>b&.o����x��i2\.�M�|g�+&�%S <<�X[[;;;��W/��/���������, �e/����r�����]�555*u����v����������<�d��k}||�v�����&�C����6�xyy9Y�nd�����L���3����z<�|��G������gooO���#��w�}������}��Q�F)�mll��������������=��s8���.����|����J�B�U�����UI3	H=���C���)N�;�������Sg�\����5���5���;�H$��.]�DCC�����������V-�d�� x%�H��wohii!;;����/S ??C����_�`����Caa!F����j��&�g�����
%%%��l\$�!lO_��}����}�L\��]�����Bff��}�l\��b�>b6.�
����w�����0@&�@��'�U�j�W��\���2��������pssS�Z{{{*1]-��tBp��U����� �+2��4S ;;������m��<.�����f�J777����n�Byy9������s455Q���7o�Duu5***P^^����v�7n���eee����xSS�>}��������K�����������&��trssc�
l�b���*�
)W�Wddd��
---�SL���}Ess�J����������9s&�m�


?~����v��������R+�j���H�A�j����a�������8u��{�=x{{CKK����������s�XyXX�M���K�B,���������N�>�3g�0���p��=^^^����P(����t��c��!22�����HOO�� ���?�}�-Z���b�;w\.���

���%K������H���ACC���������7���{F.�+����`mm
�D�;v 66�6m�w�}�����466b��-���GPP������T�GGG�_�~TA`` ������x��������oGFF0k�,$''����������

��{������d\�t	�����W�^(..�������bl��'N���W���kkkV���C���o������z���&������r�������+._����XXX����Te���1d�$&&����077��;w�w�^Vnhh�����������������7����rsss�]�������Caa!LMM�������B.?}�4>���N�AEK�*::��sp���?�ZQK�7Y������������q���v�:nff��l`�W�^������o_�\�fffTf����\���cccq��	466���p��-TWWc������x��)>��#���o�����0y�d,Z�|>O�<��Y��k�.�������1<==ahh���RV>o�<���x��%f���@WW���X�`#���BPP�������o��������b���2��������e2��;���
����W,Z�J�
)?}�������[k�+f�����B����j������>}���+���PQQ���h�������g��������|��G����_��#F@[[���Cbb"�y����u�]��V��o�p��0g��Add$ttt�o�����@�X��G�"::]�vEII	+�8q">��s�x<*� >>�?���;#���O��������,HNN���1���0s�LV>p�@L�2��&44�7o����y�����|�����~�:�w����\^__��u=z�@vv6~��GL�<zzz����������
kkk���a���?~<���Y��/������W�^�z�*�n����{dx~~>�����@�P�?��EEE�����7������Gh�fc��5����|>��a�y�B�����������?{����(--��5k0d�H$`���x��9+��GK3RRR0g����;v`���8q��D������UUU�����������fdff"88���������#�����%K������&$''#44


�H$�r��|��eppp@SS.]��#G����


�������\������7w���S�L�~������2���q�~�)�����}�j������q���?��{��i�l�����
�&������������-!
q��)hhh@$1���J�x<deeQ�z���q��!:���2d���kXZZB,�����r�=Z%_�������Zi_������g��Wl�����LAee%���}�?�+����v�Z�}E]]~���6�B$!  ���Z2.^�B��x���J�����@i_!����J����$�>}��fxzzb�������bXXX������T������g��>|���M���W�,6��(r��5B!%%%d�������|������2��9s�.�����/,,$}�144$�|�
+�����?~<�p8���S!���KuMHH�r�d���mv

��#����yyy������+W��
d���7������'7nl���sss	��'��u#[�n%�J��\�L����s�IKK#|>�����]�v�����Y!��{wbaaA���+��b1�t�+��x����8p@��|��DFF*��������)���Jz��M=

"c���y��/���G���)qvv&2\$��{�SSS2x�`V�����������������l�������\�t�������:��������l������Bd3����������		���TK�v����<z��z,�T�
R��l`��'O&III2����x{{###V>}�tL@q???��[oQ<##C���}����U������W�"����\�����$������+"""���+u������f���
>�����rU|���Q�� X�~�����P�L�2���!!!�������:��
��CUUU�������1z�h455!==Zv���=���2�3F!~��u*�����8s�D"���H��f<{�'O�Dcc#>��<{�L!����6�������G�~�:������=zZZZ�<yr^\\���������M���w����X�/**�������#++����n$�V�YZZ���>Crr2233��������y���������;���q��M�w ??_!ngg��c�"99999Zv����o?~�������3��.666����������>c��i�Vk���S\��{tt4�����h��MKKCbb"\\\������]�F�&�x�����v�
��={*�������&&&����:t(���Xy�d IDATg� pqq���/�.]
4g�������;�����?��F�����w�������H$T��tv�w6�qEg744DZZu����qqq�w�F���uttp��]�7HU[[���GCGGiii(++��W�����+���_��x��J���i_Q\\���(**b�����(�w��+lllT�R���������|Hu���Nk�������_��r_j����o�1l�0��u�N���!C�|�rt�����hll���>�B!"""����e��A[[���BhiiAOOg�����g���///466"&&���Bt��]�t��' 
1s�L,^�UUU���a�:::TU*`��a���������q��ADGGc��y������S����`����t�~��Gxzz"??.\�@ ���#����������D�]�,����!
acc�D����s��EZZ��?O�n�����������A =2x��]l���f�Bjj*bcc����� ��q��Kw�RSSq��ej�o��](((���#��y3>����Z[[��������PZZ
___V�����W�������@vv6d2�_����
*s`��������
������x��{����{�.BBB����u��a��!�r�
#��������q��M8p\.�W����3._����<ySSS������#������+akk�����?~|�� ���~�����W������j������]�t��-[

���U��RX~~~���B��=����p�5���u��
L������(//������p��q���>>>033c�FFF���Fuu5.\�z�*
�\�K�.�����������������R�W���BSSSi_Ce)�+� �� ����q��	����Whkkc��}J���\Y_!���
���w��d���@__��wH3���7o������R~��e�}�P(��<@ff&
����^������?�u���C��[���������VGK�A����...�fw�������������iw�xHH._�<|��v7�����iiiT_-�n ���Azz:�����H;v���������	rrrhw����������s|>�����077g������O�<����L&���<<<�SSS���+--������@:N�w����eee011��
������mCee%8�n �����]� �PSS���oS������������D�����,�H$����>4�����`�III8p��b1i���xhh(���Q__O�7|��1�|�������;mAk��bdggS����A��y���L�p8�2e
455�����������f�~�


TWW�f��b��6mBXX�����s�2��?mmm�����}���G���

Ebbb�|���{�a������
yyyr}��011���7��R�r�J�}EZZ���������C"����kZ2$	��Y#�w�+�'��NNN��o_��  �`��
�������>�������		���'q��=�5
.\���AG��Zj����b���
111!�|�I�����b2w�\�������iw�xaa!�9s&���;�;w.�n ���6m��x������
d���'FFF�s!!!����������SSS�l�2�������U�V��>���M�6�����_!.o�����p�\>m�4�.�K�/_.����f���Nz��I���hw��X,&			���������2��/_����kkk��wo��@&���r��	beeE���I�^�(D��������d��B,--���Ci3�xUU��k��� ����{�l�������������
3qWW�N�A��Z�Vq8�u��lv��6^VVFV�ZEqww��`��O�&����c???�`��qII	���"fff���(..V�W��W6�M���1�o`����*�
)W�Wl����*i������|||���7��|!��W8::�+���_�N��9C��������K���O�w��RVV��w��Z�Rg���H$pqq�������t����nnn�H$���L���3(++��q�P[[K���O�<���L�8eee���l���ZZZm��t7P,c���x��1���X,������jjj��3f 33�v7�k��
qy����T]���A---dee���

������iw�q�����G��GL�8�v7P���������nnn�����4S@(��������M���*�6L&����iii���C��}����&�����W���������f�4hz��A�7��E"��ug�����p�Bl���
KMM��	p����3��R^�$%%�����y\�������o���a�`llL�9 �WUU!--�M��4�G�9p��}�9������R�WH3	��g��i��x�����}���:u�J�B�U�R.��W@GG��{f��+���U��
<077��������K��9s����u�]�����o�v���5k����^fw������455��2qwww���hhh����g��	OOOTVV��`�S�NEzz�LAvv6���������X�����'�������7����?�q7��o�a����r3�����dDGG�_�~TA`` \\\p������>��q7�5���o������������Kf�o��MT��n ��u���u033��K�d2bccall�u��a��2��L---�Y���9���\.V�\��}���f�=z���+`mm-woX�|�i3=z�Y�f����B||<����CqKKKL�:066��{�j�����/�i�&jv�k6�q333�fo�)�����������qqq8}�4���	�%� ###F���X�t)�d�>}Ze_1y�d�|��3��+���0a�����pTTT��
l�b��(((P�WHydd����������h�+f������dTWW#--��w���G%_agg���
�}������J��c��u���?�;v 88QQQ�:u* ##�v���a�:} �Z�>�3�@988���#0`�L_��g��#f�'Nd�#f��~�i��@���W���1e�����Pl��|>���+�G���������;���C�������� 
����?�#f����
�����=c�#f�G&S %%s���N����w���'��������UUU���!�M�@pp0jkk���C�I�����+�e��/[�L�.s�	���7w��e��a��yT���5kh��H$����p��	hj�����K__g���������g��v�:�����l`�/^���8u�444 �yee%x<������
�%����C:t(����d�����=z�J����
_��������g�n����};�������J���1���W���c���J����:���Om|�H$B@@�d\�x�Z����c�|EQQ���B������III8}�t�� �c��a��y����={����x�"���p���	��,u�b�Z�rpp ��]#���+�G�*oo���n7����U���KuMHH�r����b:��re2�����;w�#f��������qggg�L���T��wo�qPP3f���_�xA�=JLMM���3m����{���)<x0+W��\oO�����O�~��N�A0{�l��
 YYY������O���G�c�H��l�rEg�<y2m����7122b���O'���d�����#o���_�h�+�O������:j����:b����m2*++	!���3�������J]���C���}�*������+�\_add��3222���>Y�h�r�
���%�/ns������_~��oP-�����
��C��+�G���#�o����������^{_�"}�L\��'���5733k�����j_��}���"}�l|��A2�b����hyy�L�@vv6������L�������D��������+�e��+�enff�/^��3�LjllT�ZMMMjN����.�D���������@��
L����6s���{1b+������w)� Umm-F�
�6��}������"==����W��Tl�������*����"F_�Z���r}������F%_!�����~�>44�����;0j�(����V[YY�����{��]Rg��
��a�p��-���.]�(�G���B!k1
����L}��r����d���a��a
����(�GL�555�#��������2	���'''*�@zd����
�3��[�*�G,�o�����������d
dgg#!!A&���������������
������x���u��a��!r3	�<..N�.�����'Ju����"""����������!C�2\�r%-Z==��pgj�����������={R�����k6��u��)4����������1r###DGG���.��APXXH���9��W"**J%_MMM�}ELL�����+� �� ����q��	����Whkkc��}J���\Y_!���
���w��d���@__��w��+6o�����+�+�����J�
�P��3.^���<M�����G�����i��Z�>�3�@��������}�!!!�}�L|��=m�����_�111HOO�����|��c��)�W����#���B}�L<99�v�������T���)����#f�D��b�>bExNNv���H�����}���m��������H$����Lf�D"AFF��������&����R��t�X�.���&>?��s�� ���?p��A�9s�����477c���8w���o��R�M����)S���I��v�&�6�������phhh����6s@����i���p�����;x� �9p��yhkk������+�=����}Ehh(��+����
6�d|��W������|���	n��������+W*�+��������WH��]��%�@"�`��5r}���Bz"AY_����}��u��%K� ((H�9///��v���X�x����u�^�Z����!&&&�H_�"}�L�����|�������z.$$�xxxB�+V��XW���������#�6m�L��%��/�ymg�+&�%S�����������^�zQ,((�|��wqq��, �e/8$$DnW9W�����J�.sWW�N�A���D\]]	��%�W�&���$??�<~��dee�}��ggg���M���:�v�RKaq8�u��lv��6^VVFV�ZEqww��`��O�&����c???�`��qII	���"fff���(..V�W��W6�M���1�o`����*�
)W�Wl����*i������|||���7��|!��W8::v�///'���%K�\���-����Zo��o�$	\\\��+�G���#f�t}�l}�t��ZZZm�w{���#����G,������#~UZZZ���R������W��G����B����pvv�~nRUUUQ|��a2�


HKKC\\�LW���L\�.s)W��\$A$��Ywiii��������������������8p ���������!C:�v�RKaB���$3;�;�qEf�f
��}��
���1m��<^UU����6�/��i�����1r��6����Je_!�$P�W�9s������'Nd�
l�b���*�
)W�WH�TR_a``�6���wt��hnnV�Wtv��?��'�|����������q�����{���;��RK��o�v���u�����qqq(++C�n�	�P�	&`��%������QSS]]]�xTT>��#������(��b����������e�_~�%.\���z�B����C�������{k�3233QTT���$,\����Gee%��=]]]hhh`��}_�`�>}���p�\H$���iii������~�������������������oGVV��_��������s�N�����b1���p��-l��
s��ANN������*� 00��GLL,,, ��e�<|�[�l���~��7o"22��[ZZ����DYY���������l���@ 0�=z������+����i�&�7HLL���+/((����MMM�_��������� ������c��QHOOGJJ
x<


�w�^p8�Y��Fjj*���`bb���\joX

���9V�\	ggg$%%!77FFF�����C�X���|||`gg�+W� ??���HII��c�`oo/�GFF��>��`hh�o����wGyy9*++�����={b���8u�utU-�:�|}}��l����999��
t���D����q��)0��/G�=����'O�@__��GGG�����������A������#**
���9r$�.]
ccc_��g���+�B!>��C�|������+
1a����������
l�b���())Q�WH���'��8~�x_��g�����2HLL��666*�
���+�+�<((Hi_�?����733����E��}�v���#++�����{7~��G�>}�����m�:�v�RKF��7P8r�����#<<����D?~<f��>��X���p�={�������S����?���	�;mmmTTT���������:u*�\.�;��]�����f�b�NNN�2e
�
Hhh(���acc�y��a��I������/����#11���x��I�c�$''����=��?��q��AWW�����c��-HOO�������j�*�3ZZZ����7nDvv6,--q��]���c��Q �

�b�
*�@ ���8v�rrr��,7l�����*++�����sss���PQQ�5k�����!%%%��m���oF~��}p�\��b����3,�ka��3����)vVP�X�Q�`��5F��$c������F%M�QEi����"��� �" �e?�f��af����������r�g�{��	KKKP���|;v��=���� ##C7����j�*z���c����___������
999���?QXX(**��z[[[����3g����,K`��0���C��mmmEjj*<==QVViii�����[�l��A����.�oooTUU���
fff��qc�����pvv��
a������JJJ}=��QPP����akkK�nnn=�����r��Q������X�v-8������/���<O�oll���6RSS�����Ap��yXXX���'N���+������f�����z�����}����������.��e�zt_�o�>�={V�APQQ999��
�������z��������/]�+��y���ho���@YYY�}Gff�;�W<x�ZZZo}_��


o}_���
�~� ������������<����-[�@J�,�&|`�������Q)))E�����q#���J-_�����xmaa!�b�
JEEE"���c���O-\��RQQ���]+�w<K��(*77��9s&���Lm��I"���CJGG�~���;���Bm���z�����?~�������������lj�������c�����G����������D����]�������455)EEE���������4������l*11�����455��~�M�k[[[%�������
x�G���K�MMM)www���@H�G�A]�p�v���{�~��wj��i__[[KyyyQ�����#����������OJ]]�3f�X$�������Sjjj���M�}ii)�g�JMM��1cu��-�~�����A@ |�(**
��TUU�NsCG/�� ���;�����������O������/�N�<IYZZ���������Siii_���b����|_����������BWW�K������(��
������k��)S������b2�"�;���BSS���N IDAT���+���BUU�_7:���D���P�O��\\\����.-�C�l1�quu��%K ++�k������6l]`�p8PPP@II	�\������L&��������\�=MMM`�X"=����������������BX[[���



b���2.^�(�����{������
8X,
q��Y���b��I())���?������1}�t@SS222b}^^\]]���0k�,<y�:::8p ������O����0w�\������r��^FF666��#G�`�����������-=zCCC���
���8q��X/''������zzzhiiAVV��Q�WTT���c���sp8�L�������CYYY����O���K�[�]��o��@�.����'C[[


HII���/4440r�H������ZZZ�����E`` ttt`ff���R�������Att4���```CCCTTT�����PSSCUU����A���/p8�n��g�`kk�����������H������jjj������=f����3g�����#88�Gs�0?p�@��Q^UUMMM044���
������$������w����Q]]����H5.����4L�2���hmm���������+�g���}������[�W�X,4�G��o�������;v���T�}����x��9�;���yyy8z�(�����$%%	l1���CUU���ii�w��`2��<y�[�W�}~~�[�W������?��[:"--
}}}�3&L�����G |�� �Bii)�_����`���b�����Fxx8q��m�<_mmm6�������������T���#:::t(��y���P�����HOOGJJ
��9���8���������

���������G1�;w� %%'O�DRR�ccc	�'N --
�G����������L$&&������������kkk"77���ILL�]\\�����S��K}||���#$$$����������#�e|���7oPZZ����c�����>BCC���G���/�zggg��7�����������yWWW���c���"��}�0s�L��{			���FQQN�<	����Y��<y2������4����8|��w�ddd������������g!##����?���ARR���������l���]�va��1HKK��\.rrr������:���O?a���HNN��={eee$''���+033�?�$&&"//�[��U��=��? �����%K�}�v\�r7o����~��7HIIa���d9$�_q��HIIAWW��;tuu{47�;w��hn�
�W�^AAAqqq�v�,--�m�6�����GEE�@��?G���!66���`��GHH&N���[�BMM
������,������g��o����<����z~S���111X�p!=�[�n���Y��7.^�.�'''l����������ojj�����������HMM��
��W_��F9990�����nnn�s��m��u�������kkk���'��������W�F^^n��A7~��7��_�������r�Jdgg#00���x��1��[�����tuuH7:�G���_}������c��o}_��iiio}_{{�~�����W())AEEjjj���
�=L����b����y�&����h	AH��DYY�������7�E��GFQ����[[[���BW����{?~l6����e���E��`���::T022���e�����������@a���{��=J��+lo�(���WWW��f����7���PTT������ ??@{� &&EEE���h������{8w�JJJ %%%�9 �����������(J��aq���UUUhnn�o���K��	&`�����A��s�������PUU���4jkk���IwP�����2JJJX�x1��c���=�����
�<�)������z444m��������
��A���#���_ts 00<���]����

E[[***�6���� HII���Lhs���["���7�b�P\\,�9+��?�_~�E�A��_���Dhs 11l6/^���k���AYY���b��]��4���55�n���}��4"##�`0�����A����={�`���x��!������+��3g�����%K����c��i8x� ^�~
KKK�~��~�),,,�;v`���}=d�o�������A�1"�A�p��>�����^�A�`0(�L&���������+�.P�������@������>}���������6D���r���������L�"t��8�w�^JWW��5k��}�������u�����8p ���J���w����TDD���G�8q�FH �JJJ����{�;��
�|qq1�c�JGG��?����(��j���������k���/_R�|�
���C988tiR��������+Vm����95`���/���?��3JKK���y���@goee��A���N}��wB���M�455���;w
m�7Nb/�90|�pJCC��&AG�~S`��Q��v��A������p8���z�&�)��p(]]�n��y�GEDDP�����A��6D������k���5t�P������a��u�������X�b���};����&j��9TKKKo�@���A�@�UUUl�����}=��BAA���>W^^���`XZZ������077���9������H�;���HLL��a�0l�0��������HJJ���5���D<fff�Y�����w1y�d��� !!���4h���p��-��������?���'�o�>899	�222�9s&���`ooO/&>t(�BBB���ann����;/�� ����#,,�=��3 //���Dp8p8���������:>������2\�~��?����!%%������AOOeee����1w�\����K�����|MM
���Q__���hhh@]]����|��X������#!!***PQQAQQ.\���w\��g��%(**����9s������BxzzBFF���b�������[[[�������t����I"��r1m�4HKK#//'O�����������<���Oq��qhii��bu�=�=���������8s����1n�8$&&������b=�)����!C���O>ARR����c�J����???�1��
Cbb"F�KKK�x<����?�������W�^���v��I��ba���������}
y@@ �,�W����C�z(����|���g��������b�����S�Na��U������w�Fss3��;�s��������b=_���QYY	///xzzb���(,,�����a��ux��%.]�����c��������
w�+**��j�3�����������`��yx��zad�����eee�����;z:7��
�|ff&�prr��'O�����=����SRR���iii��s^^233���D7q��]�O����$�)�x�bp�\���lll-�_�p!�����7o���[�q��!88�n��NNN�3gp��u�������&AG_[[���y���q�._�>|8��?O7f��ooo�����pww������3ts`��I8u��X���������cts���
...b�������o
�\�aaa����
�;;;c�����w/>Lo���*2d��������[���rrrtS���000���G����M�6AVVV��78555�����?��������*��x�����@PQQ�8%%���=z4������.�?N>H��d�����������z(����l��1�^�xxx�����z�j����p�B,\�k����LL�G��`��U����� pss���/����������B(((@QQ�Ks���3(..���$��utt��,��~��-ou�y[[���gg�~� ��y3���O�^{��	|��'�2e�{���(((���������77��
�|yy�Ds�(���"�9p��e��������������Fjj*222�7��?���wi#  ���������m����7@Q����6:{'''��@XXdddP^^.�9��/[�L�9	yyy�~�Zh�`��}8{��@����rrr8u�bcc������"��Q���cHLL���z�MQ���CHKK���v��Q��_~AFF?vvv��7o������X�
���(++4�����Lhkkw�x���X���%�9p�����@SSS�ohh��8v��={�M�OMM����m8p�v��?��{7����M�6u�����X�x�G{OH��5�@�ttt`nn����������{��a��9�	���011���9bcc���S�~��Y033����Caff���h�|�R"?h� ���G�	DFF���R�WVV����O������f�^�����#G���RRR��&&&=��yI�Q�������.�3�L�5�>�@���������DCedd��mmm���G����l6��O��h_�6i�$0�PI<�Q��������	AAA�������m�������QYY���@���`���]��- ''��s����W�z�*F���S�BAAAbooo�g�����VVV�<y2}$�$���<��+W0}�tL�<�^�!///�/_��o����>��3����dggw�l6��/Gjj*n����s��?���j/Z�H"�O?�c����FSSvvvHNN�������tuu1u�T$&&"99Y�ojj���/TWW���7��h��#���HOO'��@�������hhh@jj*���`ee$&&�n~s 66'N��Q�$�O�<z�pjj*�L��!C�H������7���������� !!A����?1z�h|���b_F�	��@[[����;z:7���
����&QPPts 77�f���l6�����A���;;;��l$$$�����n�z�J����������y��`0$����@7���`ooO�e����*��RRRppp��7o����7�l�2�x�\.uuuy~S@KK+V����V%�'O�����j�*�)���
ts@�?~�8��u���Ma���w��&��#���H� ��>�7$�,@RRn��
ts��������'&&�+[������=3g�������s�l��������G1w�\dggc��Y�={6������c����3�x�� �?����}=� �����������Cy/�����������������c��������C��O��9�5k�@SS��G�~(**���W��7�h�r������Rhjj"//g����������q���,����g����`��]3f���Dz.��Vg�w����zz����	�^����g��������w/�������]-��p��]�����o��������x��d8pRRR�����]]��
����;%�Dy������WPPP@\\���m���Dz�J���
:��r�3�������r��l����M��[�BMM
������,������7�|yyyDGG��<L&~~~ts�?�[�n���Y�g0�����������������pHII	���&����{�����b����p������PYY���0�����`���]�wss�����Cqq1���������6�<yR���������z�j������0`Z[[��o������������+W";;�����������n�:@dd$������@����M�_�K�.����
}}}�����������,@ff&�������7o�����{�b��yb}ZZ������x����1s�L��{�[{{{z�LCMM
�G����'^�zGGG�9sL&aaaX�d	""" %%���T��?jjj}=li|����iCLL8��� ++l���n��w���CII	X�����,������,���L�0;w���
�=$9k�,<{�@�rW)))�����(0���{�����������������;�o�����;/�� ���~~~���GCC����(��A\�x�^a����G������������x�����$���Ghh(���PQQ!�9 �AJJ
eeeB��n��o��	����b�����X��q���/
�/��%%%B����`��x���H�]s --
�������w����9p��=���u�$�������)	�����
���6���{�����1`��Y��z~S�������0�o
=z�~x.�9 �������`��B���������3��A@ �g���+(((���
���x�����#�$011������/�9 �:����������


������Eyyy�^���ccc��;v��Suuu�����Q�M��>B�?w�tn��K27�������������*�9 �[��f�ioee%%%DEE��buiL�4	222����������8�����7oBOOOhs@����Ahh(LMM�6:{)����aaa077�())APP�Xomm-�9PPP�7nH�;7rrr�m�������������ti��w��EXXX��a�cS���������9�������i�������omt�?f���K��B |h��W(//Gpp0,--1e�$&&
4	��c�b��1B��|����.t��8�?����H��aQ����W���B^^���(--Eaa!RRRP]]�;w�`���}=<��P�������sCw^��A��7=z�3f`��B�����2$&&vi��������x��9f��
EE�.M����~�s���������8_SS{{{466
m�����ppp@yy���@g/,R�d�	m������Q���9���'''���������]�m�����o
hii��bu�=�=���W_}%�$��066���S��a�������!C�h�"��Q���;�����#`gg'�9�������+W����+�a��{t���PSS��i�0l�0��9�_�������i||�A
"""��p�{�nX[[���;HKK��������
�����@w���������?��!C�t�oX�755���##�n�
w�o��;;�~� ���J0�L��9eee�����d�����g��������={�����G=��yuuu��Q>>>�n
l��:::�6����������	4���0f����7�|�.M���P��=�7o���l��Q���7nEQ�6D�+V`���hhh�prr�����3g�@����+hhh��9�v�ZTTT���_���9�j�*�z�J��z������+D6	�����KS������X�v-��Ayy9�\.������n8�KS`���"��}��;Gw�����������g�L�6����0��,Z���6
�m��a����������l����7o���l6��G���H�� 
�� �� 
�c8s����0t�P���!77�O������(�����
>��s�������C___�711������"##��������������y38Z[[���ooo�|����������
�>��2��p�\���b�������rl��_QPP@HH�N�J��N���� �H47��RRR���������������8\�t	���`0"=������:;;���033EQ�>}:������f��u������EQ���O�d�hjj��������s����-[UUU�x<\�z��]Css3������{{{�~���PRR�����n�v IDAT���}u��U�����
�]�v����
���
������!!!`�X������1s�L��l455���O�Fxx8P]]��[�b��i`�X����#22jjj(//��]�`cciii466���"���G����{����W�������X�
~�p�����bCC�:MMM���a��==z4������CBB�X������k�.XXX��(������HKK����X/''�~�#F�EQ(,,�C����������O4��
��{���������������'�����)S��o���������C%�@��^ASS�~ �/������������JII��������m�x��^iiiA__			(..�����������444���*L�8Q�WTT����O���6�
��
���"%%E������
���s�(����	&�+edd0l�0((( 66V�g0>|x�z111`0�0a����7���!###���������DEE��fK��?��X,�;uuu�������D^II�����x��
"""���O7:z������b��I(**���7ajj
+++�� ��>}:�={���0�9VVV��~I��Y����C���`��q�����rrrb��������� L�<��7�rss�xyyy���!==����<y2��?���>}�D>11�'O����wJMM
&L@ZZ�D~��I1b����0z�h������;"=�����/<x��%�<y�<�	&���G�=D�[���+����{�����r�3f�������;`555���F\\f���	&��qqqx����}�HKK���~
�<�Cyy9BBB���C��7���A!a����W��?
�������.v�����{iT�����F������
���s�(������X���JKK�f��E��zUUU��w�K����PUUELL�,x��5���QZZJ���h�I���K��������-�����W3�x�.\EQ���/������(����@��~OOO��l�^�UUUB��H�������1c� 33<�N����	TUU���*�7nrss������
}}�ykkk�~�<����&������I�&��������o����b�
���1c� 99�����>|XYYa��uHJJBtt4�}���	777����#hnnFzz:���`cc#�OHH��MMMHNN����L�����=��(����$��OCCC������UD z&���g����


pww���:���[0�L������K�.��7op�����c��Mhnn����H��Yxzzb���(,,���~������������������>CNN�_��\��^���K�D����������
�w�^���
�����7�o��^������BQQ��;z:7�6l�hn���������/b��Y�w����`mm
GGG�����>��'��uuu�g�dee!  >>>�6m������d�dee���`cc���H$&&b���X�`RRR(����b���

BZZ`gg����H/++KKK\�r���X�jf������������r��;v��*�����]�}&L���:\]]�o5��?���p��������c8q�Z[[���������{���
������hnn���<�;����/�@WWW�?v�N�:���FP777���c���PQQ���[�����/.�?FKK���������'wym\\\���H�8!
�� �� 
�c������)rrr�b������[��M�������=�������(��]�?`0B�
���;e��
_�t�[?a�����_�#��]���077���
������|^�|��S��s�CGAA�|�	}d���
�L�


�������o����������%�����{�.]�����������&���)222P[[����1c��!<Q���111x���={��A���OOO�9���
���ti#00�����xB��|@@��� �9,����uuuB�aaa���#t��A����h|��g������������
����b���x<������(
����F��g0!\Q���^^^X�b�?~={wwwP�/��111������,rss�-;���8r������?���	��!+B� ''������������������011��K�0p�@|���]��<_���/����f����EyMMM`���B�
��rrr�z=�iV�XA/����t�s�?P__O/c�'�k�����gee��z��

���<���I�7n��������ti�5
W�^E||<lmm�6�yooop�\��;Whs���+"���'����E�	m\�tI��[���cdd��?�����8x�`�e����k����[�nEmm-������N�����___<~��&M��M��}����@�^�����������6l�����zDGG#::��M���.���affKKKz��(���d��9jjj������1F�A��333agg6����Xp82��7,������X,���`��i�.��(
�_�&1%B�BII	��������#::��m�\]]���/_���E��������������������Aee%�.]���ZDGGCSSzzzts@�ojj�������DEEAMM
ZZZts@�������+QTT���(,\�jjjts�������E���1v�Xl�������8}�t��2�`0p��e������VVV�����j����v��_���H>���+���a��ts����M��6:��it�=it����}}��	---�������+�����c���gHMM���$x��@g���@g/�9��WWW��U%z��1c0f���
2C����!B��b���������q��!(**vi
�]������C� ///�wn
���'<(�,sa��8p ����r��0������
��_��8q�{
�@x*++�������%����HJJEQM��>�������8���H��M�E��]��[�n���I�9���7��PCBB��� �$�{q[D����p=z������:��������{7���/p�$��!�{�@�5455����>|8������
�.�ccc$&&"//O"�6g�w�o{�yUUU�_�b�
��7O���������w��` &&�Ks���222�sS���QQQ`����M���:DFFBCCC"��9���DDD@___h��	G�|����3g�\.���Z!c�����\\\��PA �5��@����p��m��0.����P��1����������7���0{�lL�0A����;��=����555�z=�'<���puu���������}=,� !���ppp���*bbbPPP��&Aii)������Y�M���z,[�L&S"_ZZ
tS��(|��hnnFTT�X�?!��`��X�z5��������B�����?�D���0i�$��hii���38p�@��@�b@ z~w��pww���:�$pss�Qs��?{��[�e����Y��^�Bddd__����xl���K�PZZ?�������G�#�����={�mtn����Ys������Qs��������n�"����H��}:::"_'//KKK���`���4:A4��@���������~�
,���M��k����...�����W�\��������`0B�����>B��.]��G���q����(
�
���)TTT������8p������$��0���000�� 55---]�MMM��������������`�>00aaa�����G���KJ �&�)��


�����r�G z999>iiix��)lll����011AJJ
^�x!�9 ������(++��9 �kjj"99���B��|�s�����X�n������<{�����r�
������>|������k_�@ ��M�7�L& ##��I0j�(���!>>���B��|}}=������%�9 �WTT 66���B��=y@I��immEQ����b���yD����@ �
eee���
f������&Att4���1m�4L�8Qhs@����@rr2f��	KKK��q>33vvv<x����(_UU�����&  3f�@PP����+((`���#����:7^�|�E�AMM�K�������X�t)X,����8������������q^ZZ+W���9��������$z�����P^^^����(V!>���+���a��ts����M��6:��it�=it����}}�����d������"_7~�x,Z���?��^��g��!55Uhs�s��m��}O�����@g_]]�W�@�����������w�}�1c�����111�|�2���?�����<  ���h�_��O���C����(�9p��9:t���b������'<�%���������!---�I������W���`ll,�k�����|���@�@������3(���___$%%��(�M������E"��)p��5��uMMMB��}����7����M����^��BO����������7nh��������F��`��)}9T�d��@�444����<x0������
kkk�����>8���'����p8�����Eqq�D�cS���***���Cee%���DzEE�^���4�|�	RSS%zmzz:�
&����@zY0�@�{bbbVVV�������`��Msss455!**
rrr��M�Q�F������PSS��wl�;%%%�u�tuu1~��.����@���4irrr���������L&'NDRR~����&�����@ �
����r����ZDGG#$$,��y�����M���p���a��E�>}�X�;w��������K�b������,z����������#F����(���/y]�~=���C�
�.�����.�e�~
�����&�^�ZZZ���@nn.���>>>����}xx8�$(((���7������_��fK�_�z�}+���X,6l���&�����>}�3g�@]]�7oFmm-BCC�xq[��mmm�?���x��1������Z$$$`��q}=<A(d��@��l6<<<P[[���&xzz����6m����3g������*TTT���C��������///����^^^(//GQQ�]�KKK�Z�
555������?;;;<y�aaa����������k\�xQ������������S�N��m��`0�����������-[p��9��555�������!�n000�O?����l��������:u*������;;;,X�����x�"|||0q�DDFF"##.������???�����?~<n���G�������HHH@@@�����5j._����|�Y��'OFdd$�]�^EE�///��c����U�@�
�^�C |H��W022����?�###��_����)����j�*xyy���c`�X:t(6l��A�I����������L&���t3���U"���0�LX[[���	������\�x�[�����W��pqq�����������_B?/#C�I!>������---�����CFFvvvX�x1�������???p�\HKKc����?>���akkb��K�iii8::���***�;w.��SRDy___���AJJ
k�����-aoo��Y�������/)��c.\�����CWW���+_����e�L�:?��C��@�
��#����,8N�>
===��������Mxxx�����-���x]]]���!==C�����@3@������t�������~0 --
CCC���d�������������~���������������FG z������v&&&hkk����1q�DXXX�ddd`ff������a��������\c2����*���a��9������g2�6l�X_RR����c�������.,#F��������!K��INN���/������c����-011APP<<<p��Il���GK B�^���AAA�����A||<LMM1i�$���"<<����7o����A�����n��!!!HMM���������p8�=�n��<���ddd}}}�����Q��s������7c��-o��iii��x�����PSS���@ii)���PSS���hii���EEE���F}}=��Y���R���C]]�n�����GAA������]]]�9 �+**����������K�BSS�nt�$RH��9{�,�����Y�v-��]�U�VAAA��GI �<  �B^^���O7<==�=mt�o���{����{����l6�����/���'9���������$x��@g���@g/�9�������������7O�k������kk�^� ���@ �



��5k����G����������'�9����_�5���AQ~��z�mII	�N�
mmm���������������e����������B^^^h�����O�'M��N_�l��h$�]������!++��9��T����@ll,X,�D�sS�����u��L���@g��9���������m������$zJSS����	����@ �
����


p8��}O�>���E�����6���PXX(������~���1��0FFF�����011���RSSQRR"�9�f�������*��]�}'���������4�M��^Xs 11,K"/�9���%%%�|��@II	�\.455�z������������������K�`ii��"$�<  �Bii)�\.��w�����`��y���EJJ
�����8,Z���O�����#=�]AAS�L���K1~�x��� ++�k`` rrr����#F **J�'K^	��BSSV�^
---DDD 77��M���
���������@ss3���K��l���W��n
�X,l��E!,,L�/++�9������7������]|�<��!�`�8::���[��&??033���l/��@
�b@ z6�-��������$8s�L��>>>X�blll�?111�t����PRR���:���a��Q�4i-ZDW����`jjJ��z���������B��O?	mtn\�x���������=jt����"��`���"�@�P�3g���1k�,L�<3g�����L&��y���o����������y@@ z###����`�X022h�Z�
^^^8v�X,���@g�x�b��/..��Y�p��}���BQQL&������GBBN�8ccca��a��������	pqq����x�b�^CC�O�+�@ t��������___>|222]�<~~~�r������/]����(HKKm�������������k�����{��=����`2�8~�8����xsssxzzBGG�FG t�b@ zYYYp8��s���hhkkCGGw��Aqq���@G?k�,����/_��k����(,,��g����K�����������=�����JKKCWW


HOOG]]����(�d2{�R�H�
������oCJJ�K���HKK���|��Q���
iiiPQQ��9 ���� 55��I��w��	�YYY���oHOO��?��9s�`���X�f
N�:���t�=���I t��  �BII	���`gg����x���b��I���Exx8���1o�<hii!66���| IDAT�
�������_���3g���m����3�Lhkkc������Fjj*&L��=����222������>������(_YY���!�@ HBMM
������prrBMM
"""���z{U}}=��Y���R���C]]�n�����GAA������]]]�9 �+**����������K�BSS�nt�$RH�OXXX������A Hy@@ z���<��?�nxzz
4	$it�EEE�������c�&L�������O����k=jt�$RH >rss'�9��I�6��������^\s��'�-�@ �?���+(((4��Ywww=z���B����8r��{�����e�#� b�
��]!j�%���VT4��c��7�$��(�HEy��5�y��(�����R�����:0����Za~g���8s�������%CP���+(({{�*�B��]����=���m����+W��A�*���ZZZ/�l	�?���G�����W��s��TJ���!!!��[�Jyi�����9}�4���*������={�p��Q�����IR��S �7��B

%11�w�.�>�b�@ ���������XXXp��n����9 ���|�2w��-����J�������S�]���������~QQ			�^�???:w�,e���J�@��
����_rrr*�_t�E�@ �.
�.]B�P�q�8	��U9.^�H��u���r\�p�*���������He.�^|||x��w�:u*6l���C,_��!C�0`�i	Q��UB4A�p��}~��7�������s��A���qrr������7;;�C�����3v�X
T&?u�������������/M�6�A�JM���G��M���_	P�\5j���'Or��URSS��{7QQQL�2�w�}����W��������I���/&M���X��}k��@P����9s&���>|X�Ru����������C�q��m��T�-[�PTT���s����R���@LL6l�a����?5558Pi~��}���X�nr��������}���5z>���u��8q"VVV,X�����������_0p�@.\����=�=��R%��@P#��������$����
S�NECCooo|||���"++��������1a�
����rSSSH�:��fnn��+W�F��+W���@�P���G������
R�r�����	���{�������3���{899������;+����j���
����]�@ ����CLL�v����{{{.^���k�:t(�&&&___������'�N�"&&'''������-=��|��t����������+���\�|��y�N���k��������{w��;G@@�R���W�gX ������]������mrrrpttd���l����+�G4A�`aaA�����q#u������i��aii�B����<==�W�vvv���annNqq��GGG3t�P�������������_��?~���zzz��������5kh��!���c���F!����s��rsCC��y���c�����+66���o�{�n
7n���
�WLLL���]�vI>��C�2t�P044����]�v�r�J���qrrb��A�d2I�ZY�����3g�������~�����#�6��kW����/'N�@&����F�>}h��!|�J��e�j��
/���/(�9 ��8v�������X,�)xe
�@P#hjj���Oxx8���>KKK������ZZZ�����Y3�7o���9��9������)�F���������~�������G__�.]������1cPSSSY��{�HJJ�S�N��


QSS#""������E�r9��9`ll\a��h�W���7K���y)X�|d�@�jR�^=��g���)�?&""�n����U+�wXCC333�������O�>�j�Jr��S�Jyzz:����V�Z���#�M�4�4ONN����4�V�ZINMMM,--���}��
������V�]��u6l7o��u��5P�@P9��7Z�@���������1b��������iS������9|�0����=~��w�4iB����������hkkK_L������+w��AGG����������9|�0���xzz����J5���s��i���o233)((�[�n�����~����0a
���'O��Q#:v�Hjj*����YYY�uj_�����������0`���)���~��7lmmQ(��w�����V �J�(w��������l���IOO���#��U+�������Jaa!3f����;�������o��R^�~}������79x� :::�����M�*����<x0aaa�����c�bbbBTT���K�\H
�:���U�������	^OD�@ �����=Zr�8J�9J��������]��Y��9s&�������\�v�.p��Q���������#�0U###H�$�@zz:III=z��}�V�9P:���?~<`���XXX0}��r�����_����}�v�����$����[�8u��J�@i'�?q��W�\ASS����?t�����d��9CHH-[�����JN���'W�(�$S�W


222�4����3��=����h�A&��q����v�Z������K����/���`gg'M9�g�"|���������k��t������s��=���;���9{�,����-�X2������W���K�=�8|}}Y�j2�L������e_5j���7����=�+VH�PVD�t�@�����S~��d2Y�<�]��5J�S $$===�����X

Y�h���Z[[cmm-�liiIff&�7Vr���p��i���quu-�������c����tW���-d��a�8q--�r�����)..�A�5X�@P1��!jmmm%��L&C__���0�����9�����k�HII�y��J�������\��5j�����������S�����z��Fzz�J����:aaa���T����}�prrb�������xxxP\\\�s��!^=
	

�����s����'O�(���< 44uu�2y����<yr��W�����;��qdddp��U�����9����_�������d�[��U��?�E�����,]��S�N���r�������������~���7�v���A j���4~��7>|��'8z�(...�9����s��H���g�2v�X
����N\\���3f�t�R
E��;t�P�u�&���������g�q��	��}N�>���W$�@LLS�L�c���<y���u�bPCCC�l�B��-qrr���n��G��L �J�fff9rD��+q<z�H�����}�6���3g2�L)/...�MII���+=z���@N�>Mzz���n����M����a��yhhhp��A��� 9�������x��)���/��.RX�����'�;w����c��t��;;;�{�=����E`` ��5��R%�'�@ �tuu��������HNoo�2���N�c��1s�L���qwwg���P�����3)))�j�
@ZJHKK�.]���];V�X�B���yPPP���j��?�w��,Y�33�2�������s��Q�(�$�����s`��9���I��w�^��_��������;��?�a��)�cu��-�IP�s����!��hii�s�N&L����[	

%%%�w���%K022��2�2��@ �,,,h��57n�n������q������I�z����+�$x~X��X�jd�������888�����TP~~>�������6l����6mb��54l�P�s`�����o��|�L�/������qrrb����]�@ xA,,,011�>�v���O?����V'AAA�v�b���hkk�t�<yR�����������>�����������&O�>%''���l233���o�}�6�}��7f���t��]�I�����'��d*�J��e�j�t
��>�@z/��A ����X��,x9hjj���Oxx8���>\�I���������4k�L�����'��6o�LZZ���>QQQ����={�������cee���Y�f
���J��X��)S�`bb���>jjjDDD��}{�����7m�k������;_~�%-Z���r�P2
��9���c"""���['������DDD��O�N���:t����
Gn���fIJJ�q���j���� 99��7o2h� ����yy������y���o���C\	8x� C��m�������� e���c�����=�����!!!l��QiM����3j�(���h��)k����
�,RSS9|�0#F�`�����(9	>Lpp0�G���>P�$x�"�����={�c��q��m������/nnnhii���+9�<�
b���l���7n�P(�x�"�?��w��y����0a����J�@EyVVVM��CKK�,YR����d��@vv6���*������,���U�$x~�����:uj��x6�`��%�g%���wILL &&�M�6add��y��u�����^����;v0x�`����$�^%��[^����7nnn(
�����7

�����n����{��G����'��O����5?��3��������u+���|���\�t	MMM���O���c����\q��s�N\\\^�~���=z�����Wr�r�v888H�
<�E��x�b���i��	���c��q��/����s���zzz<x�@I�����s�t�:K
����[�8u��J�@i'Ay�����F�������J���SXX��MFF����k��<x���$&O�\�s�����"��\�p����E1"U��!o9O�>���?g��%|��g���r��u�/_N���9�<VVVhhh(
1|�y��!�W���o�����K�.1k�,rssi��!�i����\���X�x1��O�������,����de�~~~�]�mmm�t�R�9������:::���)��>|8��5���?'55��S�*�����`����?����ap��q�������k���}�*9|}}Y�j2�L�����my�W��O�J����x6��$5jT����!!!������$	^lmm;v,��~������V�X��������{������������Z�9�����c����W�$~�gK x��`����+�v��A;v����h��\�~{{{�/_.=��];��y3����;wmm�7����s����pss����Q�F��� ]�������Bzz:����6���>}���w�e����J��L���>aaaXXX���R�9�����k�����y��e��:t�������J�(YZZ2a�i�B�>}x����7n���s@]]���0lmmU:	��K/�%�Eaa!��������s����'O�(���< 44�~����U+i�<[��>�Y�f|��X[[#��$KAAYYY���s��Q���C�F������������W<x�J�@JJ
7n����?V�?/�^E������;?��n[2�F xU
�����d����2swwG&�1i�$�����H�������Szl��0@����m����\S��t.\�P��qi
���LRSS9r�C�!''�C�q��A�L��\.��������233��w/g��a��i���(�hjjJ��[�.������?��������S�2��:u�������R�n]�u�Frr2~~~DGG3w�\���8|�0������r���E),,d���$%%�o�>tuui��-�o�f������J���_���i��111l��


�,YBLL��_�}��J"�O?�+++V�\���?J�������-k�����Yz<//������/	g��=���cjjJDD?������=�?���]�v1i�$������U$;;�y��1w�\������;�7��]%$''����C4�r����|�r�����)..���?������M�r��%����������h��}
TV=����^�z��]�J��>|��}��UK�����������c�z�b��I������������p��;v,(����L�2��8--��{�r��a@��m�s�QQQ�n��&M��t�R��������Krr2111\�x���3|�p222����0���&/���S�N%>>???������.\�����>���l��oooz����S�HNN���{{{rrrh�����6l��
�����������B�@OO�����/,,d��E���0a�z����k����a���t��
�2e
�;w�M�6x{{��K�J#�j��?����K?W��MY&Y�� o9�[����[<x���{�RPP�����6������z]���a���DEEq��)���/�����y��m������c���\�p��'�^�/��'bll��*�655�Zj����K�.l��MMMz������7F�P0f�����A�8880~�x5jTn^�T�B� 99��~����������3f&&&�����c�puuU9J�G�DGG�n�:d2�f��add���+�������@ xU077���P=�������144���Ir���1~�x|}}Y�r��W���:::e.����		������K:v�H�.]*�'##�����!55�	&��O������[�l������3e��u�F�
��������/^\
gM xycee���;
4P��B� 55�M�6�puA���[���_�5������Q�A0n�8���qss��*_>?��3�������t+l���/���={��h���~8c�6m8q�D��5�^CCMMM���o,--������jjj�E��7h��9����������u���H�y�LMM111�9
���ILLd����^���m�*��jkk���S�������q����^������T�?/<���n�����]]]]233����k��4i�D�N������iii��u�F���I���<�V�����Rr��j���k�J��$&&2u�T���y�������>�������>			���amm����tAU�N��o��G������g�V��TG������#Z�l���_._�\���&L(3��u�����~�������w�����[��U���N��p���/�RCrr2AAAL�8SSS��9C���%'��}�		a����d2N�>�����$�,��gW�^����:u�p��I�r9}������R��gO:�/����q�����f��A~~>G����Hr���W�gddT�y�%;;���o�m�6rss�7o���8p===�I�i�&���Y�`���������G�e���,X�###���GXX��7o�d���8::����4����[�J/�/&,,���@&N����%���xzz��I\\\8�<J��5k�����P��3h��2����6mZ5W#��A ��5.Y��"J������0c���.����A�J-�%T�$�7$$$���&9%'Ae�����'O2`�F���G����SSSIII�R��GU�9P:��Q��7�@ xQ���	

R�(�$x�9���/���,Z�HZ����#\�|�L�����K�.�k�.���quue����g��G���:t���ooo�v��������a��it���-Z�t�8	J���@��R���%�I�7o�A��r��]���h���[3�m<��	###%�@�������W�9������k���S�$x>8p��s���???��Y���~'����s������Wcdd��I�|^]��@ xQ
���h��Q���m��|��q�s��%�u�V���/5@�HMCC�^�z��W/-Z��q�X�l�~�-���L�<�=z(96o���S�077g��	e�^^^=zKKK�N�3g�T��^2���������P����������> IDATg���5��YB\�f!��o(���C������u��v�
����������Nxxx
U�rx��y����q���Wz�%q��Qrrr��Be�����h��!���\�~�����555n���������vq��u������v���q��
<x��I�|^2��M&//��[�2{�l,X��-[HHH���A)


���$??��s@WW������9P�$�����������������5-,,8~�8���>����-�HMM%22uuu�����$"##���T��)�����b���;lll������?������ggg��������2�2�o(FFFhhh`ll����V���888��}{��������\�z___�������k�0^����sss�����


����:u*u��������������>G���AAA9r��S�"��U:��;��������4W�c��YhhhT)o����s ..��s������I�|X�����9s&��m�s��\�t���H���HOOg��U��I�@P��p�B����8�m����O��y�@LL�6m�n��RC`��Q��7:t�P��6h�www�]�&
�666V����������K�N`` ���J�+++������?T:	^wq�������g������B�����d���r��UBBB���/J�u��F4�P�r9}������dddBpp0���<x�����tQicc���:;v�c���Y���7o��U�Z>��y�����kkk�/_��K�8s�L��������{{{�8\]]quu%==��3g���]�2</%���;�����$���{!�@���������q��+Z��M���]~~>u���}��|��������'����+���VVVL�:U�s���`���x{{��GN�:%9	��Oggg��i�prr�u��*_���{t��������h��1]�t���k�����h���J'A���W�������/_��y�T
/_����;,`����P�@�� xCi��������GGGHOO'$$�3g�H�����g���w�^���[k��"�m�lffF�v�3fc������g��������]�t����z!��?����.]��u�V455������`��1���E�
T:*������k6l@KKK�s������u��!��T:�������J��������y[[[v��U;E	�2���chh(�����c����q�?___V�\�\.����~��Q�~}ig���o���l�2�-[�����y`oo���{���������(�s��M����S�ZZZ�������KN�-[�p��	���U:�����������������!UFqq��O�G�����f��%�ncgg���'��-�\��UA4�P

�?������#F0b������.�]\\���Uy���m��xzz*=V�_(i�����{������������^


455�������D.�+9	J����q�����tT�kkkK�n�y�������O�����J�@E���������'�v�+Oaa!��������sg����,..���$��iSm��'J�s 33���h�v�Z�I���GZZ�n��Q�FJN�9y�$ZZZDEEq��Y�����g{����366f��eDFF*�0���/Y�b��7��%N���������V�(��N"b�J�
�!!!��q�`mm
<�>5k�,��������7��s��r��Ohhh���666������H��kW�	�#LLLprr���	���TBCC����k���\]��&������ncll���#9r$��8K�^\�z}}}�����;���LPP'N����3g���qc�I�o�>BBB�<y22�L�s��|��=\�zwww�����9PY��3���W��(�����s(^}RRR6l�/_�]���7�U�V��

�����������k(Y��9�����y�HLL,�$��i���,X����h%'A	����.��v���	�g��4�����}�6�f��>_{��Ahh������T�r9���xzz��I\\\8��J�@��u�>x���Kx)�����M�:u��u�V\]]�����t����$$$����������k���EKK�L��<7n�$�j� �A.���{�����\.g��Q�5��_;!!777�9(9	^�9P:�'����G}Te�@����G5~N_���,���?~|m�"����1���X>��S�r9W�\a��5���A����3g��7[�l�����	

R�(�$(q������/���|��'R��/�`��E0t�P�v����M�4a����g��;w���������^�?�\.g������0m�4:w�L�-T:J�%yI�6�z�*_|�E��}����_�������z�j���[����t��f�"77��
A�6m���%((���3}���Z����@PP�t��".^�(�p-a��L�833��*Q (� 5�����s`������������+����g�������t<�8��S����5k������9P:/����a����t<���}�y���A Tw�����+��q�\.=���3r�H�r9�-���Q���h��Q���m��|��q����t����[���Y�~=��a�y�f��� ..��c��y]&L� �0HHH����|���I�%&&�e�����0aB����G����R�����3�v�*�u����}�LV����R\\\C�Uaaa��;��>�777���5j			��?\\\HOO'""��={�f�����3C�����n�������k������J��;wN���@P��@ ������h��!���\�~KKK��55�
����N���"�_�N��m���v���q��
lmmU:	��������n��\�~���f	5Mdd$��OWj�k����/3d���o�����u}�o�����s@WW�����d(t�� ##������U+i�@�f��H����������d����������,"##���P�HJJ����4o�\e^�S4h���3���;�;w�t��>����^������Szl��0@es�m��$''�Ty�$��o�������a����}ONN&22�~��q��%���r��)���W�%�A j����s���9��#G�:u*r�\�s���sL�>�JsUN���0f�����F��&M�(9����;w.yyy*���%�h_e���Kaa!��u�c��Js�+B�P���'�lll��C���L����n��R#�4:::9r��#GbiiY�u�p�B����8�m����O��y�@LL�6m�n��,Y����<==�<yr�K��������ciiIrr2����e��J�����������,]����pqwwWrXYY�������IP������q���*5j��S�4m��K�.�Y��{��*�����}��5P��Kpp0���W���;T>.V���A jccc����w�
���;w2x�`�����;w���_%11���G}����)(( 00��|��l�����RRR���?������\*��n�J\\�n������9�?����l���+�K��|�)((��_����J�IMMe��i�����|��w�V�@�:��C|||�6m���(
���:::2y��jz��ys>�����������i�{����$%%1n�8�{�=�������6m�G��8q���&M�D��=���e��m|���4@�%�����#,,���X�u���}�(**����^�zI#�_�������������q#vvv�����aCf��I����7n,�T���
��7�>O+c���\M�ccc���K������S���_��W�y��I�$%%��������p��[�����!`���/<��������V�=&�lD�@ ����888������&�f�������P(�%�n�J��
����pvv����J��1c����L�����#100����J������2r�H�
������������_n^�_X�B~~>�Z��rs 00�3f��������9_}�U���^U���i��56l`��-<|��[�n)m�����-[�����aff�L&CGG�I�&�}�v<<<077���Ur���0y�d�m����+i��)&L�O�>hiiacc#�_|���[ZZ���A�f��<y26l`���h�777�w�^�E����y��wi��;v����u��q��q��i���;�:u�^�z��B7nT���0�
������w��-�.����?����;zzz*�lo���/���={��h�����������+35�����)��j� 5���:O�<!**
+++���$'���������M��-������V5������[�i��L&]�W5���$..mmm�����������S���uX�[SSSj�TDff&�f�b��]���;�����/:����������������q��)��������3uuu455III!!!�\�����(��{�.M�4���---����*y||<III4o��\�4�����?���4���quu����������B�6m������������M�����~�������w�.7��I��U�����.�2j
� 5Bbb"���c�����r~��w�r9���dgg�{�nBBB�;w.ZZZ�<yccc�Bzzz���;��i>z�(�������{��U)������>#77�C����O���ILL�����<##�6Oo����|���nS��HIIA]]��s��b��*�
JK�����>�������� &&��7RPP���K���%00lmm���a�����_�e��N@@ZZZ�n�����*�r�.^���;�:u*��5#""��~����"���Gddd�����E�L�>��'OJS47nLhh(�V�*�W������dee��}{��������)^�;7�	���{I�/�h�!!!���gK�555v��EVV
���S��}���T:J���~~~�����(��=Z�9������w�u<���������<x������m�6����������������\8FGG(9\]]%��������_%'ANN&L�g������m�6�m���$�,www�K�.�k����7�e��2N���3f��C�����q#�6mRr���+�YYY/��?~\�noo���������T��^TT������������Q#�"�)"T!����F055e�����r���qtt���///v��)9LLL033����N�:��/�H���������3��-[�v�Z�9PY>l�0

������SSS<<<��@E���~m������N�������i���������������[����p
E��+**b��E�8q�F��S(����Rs�_�~�d2��i��I������������a��Rs���{��hkkKN���D���[�9PY��S'������+�|�	���|��7Rs�t^s�����������0w�\lmm122b����]��k����Kjhh���������,]����V]?~�:(���]�V�{���WWW>��s���k�Z�@PS��@ ����S�9������7���P�x��1���deeU��r
��������vdgg���U:	����y�d=~��9s������C���9~�8^^^hkk�vy�+���.��������s�JU]8������gs��u�
FPPP�����S���x���J�@ZZ���r
��w���o���_���S ))���x


������w��!>>���"�yu���r9}��%**���4�������i��1��O?��1k��!,,L�w���#?��FFF��y���W��M�@P9�A j�����o�>�����w/�f��yL�:��'Or���9p��9,X��1c*��=����$�@xx8�-��?�R~��9�9��%K������C����5z>�-/^�C��_��B���c�������j�4���C.�cggGJJ
���+��q���e.����?>G����S���U{�
��o���-ZHXX�N���") 22@r
hii�|�r5jT�<..@r
������������;*����$�@�������P(������_:�e��U+<[����"�������/3g������2o�<�}�]�a�j�*�o����{_����������%&&&J���;w2x�`�IPXXX�s���Eyyaa�;J�/�(������Oq����c��e�Z����b�����i����>�/_.�	�*�6mJ�v�h�����~_���			!88�3g�p��8<����z�����������`ll\��Z[[3~�x����N//�r����:	J������:	J���-[�T�$��)]������4FFF�1�#F��!!!�9s���`<���pqqym<��"�������Uc�{��}�w�^���[k�!^.�A jsss���FSS���3~�xLLLP(��{[�n�a���s����J��1c����L&9044�R������'����s@OO}}}\]]���/7/���*���K���������//��XY�f�h�*�6m����Z����iiiK
��/���m��u���^333d2:::L�4������������$���AGG���'�m�6V�\I��M%�������,��a+V��E��s�A��s`������������i�Fr��W��]��q�F�|��y�~+���'''��Rjj*������K5���M�@P9�A juuu�<yBTTVVVhii�q���M��-U:*�srr�u�m��Q��,���$..mmm�������}��="""���c����;����s��j��+�	��p		����������N��u������K�)))$$$ ��U:	�{�.M�4Q��,���'))�����tT�������B�6mT:J�����\.������)M�@P9�A j���D������3���������r���f������0w�\���8y�$���2DrT�������0�n���G144����s��<66��>����\:���>�{�����yz_sss|||���y��=x��?����-!�
��rF���Q�j�u333��s�t�Rbcc	DGG[[[bbbX�~=���g��e�������[�����r�.^���;�:u*��5����-Z�`����<y�M�F���%�@��&W���mh�o+�A j���f��-9�������@�����?q��G�]e�@�<77�6Oo����'��������i.|�	��Mtt4���*����;���*t�������K��kW�s��|��t��kkk���'AI���U��X �G������2l�0����w3z��Z�J PF�b jSSS���\.���GGG���b����S���333������������(/q
aaa��1ch��%k��������
���+++\]]155���CjT�W�4�:��uN�6��\�Q x�P(����Rs�_�~�d2��i��I������������a��Rs���{��hkkKN���D���[�9PY��S'������+�|�	���|��7Rs�t��� �&99Y�������R5�jD�@ �u��)��������ddd�t
<~����h���*�U9>|��[�����R^�9���Mll,>T�$x>.�utt0`�����i�^B5���x��)qqq<y�D�s --M�U9�����������R^�)���D||<*������;w�OQQ��\xPo
���5���@�"���h�������o����w/�f��y�t�;w���a�JsUN���p-Z�B��Rnff�����g��%<z�H����|���}�+������g����X��%�D� IDATT#��B�7�|C\\\����)**�rUN---�/_NDDD�r%����������*���Y�f)9Z�n�'�|����U:	JAmcoo��������'O�����?�@�P���@�����B���
�@P#���(9v������%'Aaaa��

�
����v��_�9P:��gOm��J��� 00����������,^��%U%^6����?^�s�������\�@lll�N���<����m�N���<�@��-U:	^�)]�7��777"##_�y999��7l��e�%�+��@P#4i��!C��e�|||1bnnn������>}��q�F�����Q�7n���,7n����_���~�
gggF�-9��[[[��������q�ptt����f��1q��
sCC��>��RPP������~J����7����O�A�|���$''3y�d �3g�����o���G�1m�4����C�U�322����PSSc�����mmm:u���9s*�������/��d��=���;K�����?erq�U����[7BCC���/�1c���<}����.\���~��+W�|�2�����C PB4A����FLL(
%'�B����{����������4��*yqq1)))���������2������D���GSSS�����FQQQ���@�z�����"���_RE��:(q����SPP@||<��������A�����:���������F^^ZZZ�3����[����$//i
���:yyy��7o�$''���<d2u���9�<yR&]>so���c���L�<��S�r��y���W�FFFt�����;3t�P���k�%��@P#��{���D/^���1���233�������,Y�����s��q���qtt��������o���k|��W�L&c��!$%%U)OHH����&++�������K�~�HHH`��-���dH]]�k����[�4DW�P����44R �z�4����X�n
��+Vp��
v������;w&**
d2+W���?�����
��}{"""��[XX0}�tN�>������3h������\�����������~6o���Y������?�d��er!)��t�����w���?r���/_.����N�:�@uA�
�@P#��s�E�1f�����={���DMM��G������#(((@MM�]�v���Jnnn�����;v,}��?`��$%%���Z�|���|�����H����xbcc	g�����O�<��s[UJ�����������&!^Mn�����.\ 33777z��E�=��u+[�n%22�.PXX��)S������.^^^l��IrT%�9s&����n������a��u����{%�@E����i��
VVVxxx���I�.]����Q�Fe�����>��J455Y�t)��_���
777�R�s���k�8�����@ �,,,pvv����B���C)**b��u���2a�F����
�GGG
�������
�I�&1t�Pd22����GSXX���'����;�����w�aM]��,*C;Q��XGkU��Zw�[���*��8p�8�u�*m�*(R'"*�"{�0r~��-d�=�������s����{�y��#�����;b��i8v�`nn�������B!����3�;�=>;;O�>m��Q(�DEE>>>ppp�������CKK666�;w.����`����CSS��w�������ooo���s����]]]���GGG,Y��w�������0o�<��G�PWWG�=�b�
l��W�^��0�|	����>��Lq��������~��;���
��Bi%�u"55���R;


���uuu�^Z�@~~>222���������Cff&

�v4����X�@WWW\�z���AA���[pT
�����BAA8�D�@mm-�������#�S ++������U��w
ddd //���R;��x�@ZZ^�~���*��t��]@EE+W����/1�|L�4	���m=,
E.���B��
������_EEE8u�._��M�6a����v�~��W`:����e���9S��|�2��W�)///|��
���H`:233����a�����2��0����&&&�z
����
�u������#���q��}�u��l����!>>�N������(�_�|	L�������}}}9rD�����s�w��		�����%<����.��rq���~��W�n��P(r�3(J�`ff&�9p��)L�<��$�����9���"������`��r�2��|{GCCS�Nm����1�FC�P�vvv�8q"rss%:v���"((���777��B�X������N�o�s���Vj'AVVV[�b
E)�[|�3��R�=t�Bi�v���c����L80e�t�����`��!8v�����	000@�.]��I�&�o��

e��{zzB__���
y���0_�G�===p8L�6M����H@�`��
�By[���@GG�������={�p���?f����������w3_��������t��������f�����BKK��������m�6&����S��+$�p����aff�>����A���� �P(�FAA^�|	.�+�� //���������Y^  77��������9 �ggg#;;���Y�]���O�<A~~>��`����9�
��AU���;a�@zz:����v��� %%���R;����d���K���QZZ
>�/�s@����
��^�3(J�����K�.a��u�~�
;	�?�[�na����6m���Y��������������)�s@������-[0x�`���|AAA����@ �������add���3�><<<��sg4/^dv@�P(��7o���s�ooo���Kt���O�������v�*�s@�777���tuu�v�������������R(���� �P(�Bff&��]�t�$�`�X2;��x������9s��h�y<^��������I�&�����N}}=n���[�n���>Bxx8���Zq�
�)$&&�������$h�)��wo����E��W�^ppp��9��vXYYI���B),�B������B��
����2e


A���'�����;b���0a���A����QWW�����S�NL�@c~��Y���������0i�$���!((���L��,?b�����c���6m�;������3���wi�`��!(--E��1p�@����K�.���GUU���������<�QQQpuuEtt4lmm��O�P(2PQQ�����---�� 88��,���;455�Nx{{�g��L��,���



�S`����������9 �������L�����q��U0��$h��_�����B�P�[h@@�PZi����HMM������������A]]]���)���������(��;�������h'AC����}��>��s������_}�������$b����������c������)��TUU���@j�@mm-�������#�S ++������U��w
ddd //���R;��x�@ZZ^�~���*��t��B��=h�Bi���E:N�:���/c��MX�t������(l��3g����u
������_|��B^�s 33���6l��N���]���j�*888 ..s��Q�
���AAA�s�������?��H)Js�������D�@`` �l6��u
���G!/�)`ee��{�B___j�������7BBB�f��vt���U�%�B��/AgP(�V���L�s@��������Vf�����L_SS#�s��f���tH�����t��{�=bfS(C��}���c����]I
������������+�9��� 77AAA�v�����$��:���dv}c����R;	�����S(�{�A@�PZ333L�<������1k�,L�>�:u���!���K|���8t�.]����gc���000����\��W_���>��}�p��-��;������>�1 ���������y�0j�(������`��Y2���Ap��9l���I���^�za��i����[pd
�%���+ttt`kk�E����;w�Dqq1,X���3~���PSS���-Z�?�������W��x<������#�,Y�>}�@KK���X�f�\����������`��e���'455����
6Hx:��B�P�4 �P(��@ @jj*RSS�b�P^^���>����dff��'��]���xHNNFNN�������;�III���Gmm-jkk�;�,���2�@ x����<��n��6��?o�Q(��������Bii)QRR���,-b�X(..����QQQ���*���0k����=��Cyy9�����������P�OHH@MM
JKK���UUU�Hx
�B��=h@@�PZ���\�t	^^^X�l���=zPXX�#G����[�������q��U�������� >>�v����q��E\�p�����������/>��S�={��K������`������z>�Bii),,,��:=z�`�Y�P(����@BB���������899������w�k�.t��AAA077Ghh(?~x���B���������BBB�����{����?��}�����������@�������-[�HxZRHy_ � ??eeem=
��vP(�V!++��m��	@?~o�����
"""0o�<�3���;}�4���PUU%����?�7oF��8y�$��������_�d	����r��?����T��� 11�~�m�����U�gS044���/��{�f�Nzz:���[hT
��y��BCC
��������}��e:�>}���h���c��pqq���3����k
{'''t�����@���q��Y��.���,,,���
???���������������m}�)�f��`��9�����	P\\UUU,\�\.���G��� �P(����5&N���;BOO#F����Sq��Q�9s������c���CCC�3#G�����p@�����������;c���L��0���
mmmc��i���'�p@�722j�S,��={���k�~���08;;���(��@CC�v�b��@SS������!�,X777t�����X�t)TUU����|���������kkk�Z�
UUU��m�����PWW������������73������k�SL�4___dgg�����m���{������~��}��zx��ah@@�PZ���:�����Z���#33���R;�������'�K�HKKCnn.*++���iii���GEE��N���]� ?~<v������&������/c��a-82
���������eee����HMMe��N������T!/�)������RK�������(//GQQ��N����V=�����o����-Z�<gdd�_~��.���4 �P(�B~~�H�@XX._���;wb��5R;����{�n��?_���)�����~�	S�NU��w��� 00�F���I�����l
���7n>��3���*}����1n�8�]����@�P�***��?z��%�9���uuu�K�066��C�`mm��������#G��sg���^�s��������N��*�}`���HOO���%�����`�Bimh�Bi,,,p��9�s@��@�I���ev��l������`��r���y���cm}���D�~���wo,_�.��' p��u���+����/_��#�P(�boo�Q�F�_�~�
;	����={�4�9��W/��B�X������N�o�s���Jj'� �P(��
(J�`bbOOO���BUU�������ec�����:::L��pY�<?q�D�����K�s@[[���
y�����0�ZZZ�����i��Qohh�z'� ""��m������WWWt��zzz���BII	^�|����iWvpp��+W��
��cll,�9��~���NNNL'���8�.]���@��������PWWg:��]�v���d:�����___����[�n���C��UUU�s���[�?|���O1�B������B��
����HMME���Q^^.�I���������L888H���y<���������|RR���abb"�s@�:�XYY���G�3g.^���O�����2��:u*���/�oF�P�'l��+H�����())����$(..����QQQ���*�����g����P^^.�s@�OHH@MM
JKK�v�{
�=���+���������B��(���B��
�t�����l�2���"�G���[�������gK���8���x���'N��9 �ggg����~����Y�����z>����!.\��;w�`��)Rg@t��_}������'O�p�ByG(((�_����*���$�I�k�.t��AAA077��9 ����a��}000��9 ����������qO��(��@��W���0(��� �P(�BVV�m��t�����N�N2;��x������%K�N2;�}uuu����������?233�����%!�����H
���������Jt���W���a�������Y���	��w��9��vXXXH���������@rr2����3f03_�EUU***-<:
�����B��
���"�#F�@}}=�o���;b����uuu������Y~��%������o8���q/�9PSS���@���J�$h��������l6������l��P(�f����]�v���E�s`���`��e�$:|||���
www���^Z���m���������q#6o��O?�Tj'Addd[�b
��R�v�Z\�pA�����111�cggg�����1R(M�
�U�����^[[���tdff���Vj�@zz:rrr���#�K�HKKCnn.

���iii2;	�w���B���������eee����HMMe��N������T!/�)������RK�������(//GQQ��N����V=��4jkk����{�����^�c���/��=���?-X�>>>os������
�U���������s�N�Y�Fj�@TTv���������:��O?a���
y�����b��QR;	����V=�M!;;�-j�aP(�����
����^�zIt���A]]���:���q��!X[[+��;���q��t��Yj�������?������.��@�R(m	������B�@ee%/^����#++�������J{�� �P(������;�t�9s���c:	�|���6�-���|��l6[���9 �;v��O�B<x����@�P�2���5j���'�9����_�~��gO���z���I ��u888��$��:����v�J{@OO7n��{�o���3����1c������H�4	P(�V������������*���'�I0f����{���#�s@��8q"����Lg�x��<���p��p8����vho���#66���J�H���������o�����[!�Bi	�������t���{������D'���K���I���w��ooo8Pj�����L�����[�b���R;���E�����S(��������|>�6m������q��Axzz��()���Bi�������>�%%%"_R���������t899���B�s@�����������CCCTUU�t(��={�t
�w������B�ppbbb���}�6BCC��������%�F�PZ��#,EEEHHH@II	���@�$x��
�>}���
TTT��b�t(��<y����� IDAT�j���BUUU�s ??_����C]]������.�9���+�)����0}�t<{���71������;���(����",-y_�����:��b!::m7�����O1v�X���O�����,//��y.--
/_����?���MMM,X�		ATT�f�q��	t��3g���W����� $$$ ((���8�<:t��I�&!##C!������dgg#<<���Drr2���#�������V6��%K��K�.JWRR�/^ ""_�5���O�@�P�)�����8������

ELLBCC�����>�qqq��������]�k��!$$jjjpss�����=z���;p��i���c��UpttDLL�l�"�4�&M����{�n�[�666�y�&6l� ��[�R(����Zl����oG]]

���'���(��A;�������j�a�U�w/���>���Z�a��������0��YYY������c���!!!(((����_��+V`�������'���+�x<�����X�b����j���'���������u�0h� TVV�;��/_"%%���X�|y��������L!���7�����9r$"""0b���Bi)�?��� DEE��ba��epuu���������8DEE���K�.E�=���???��������K�,A���accooo���b��8s�����������
��u�����s�N�����������M[�b
E��O�b���x��`���8t�LMM�xd��
�By����RUU�<WQQA��;Glll���9w���x�/++#?��3���&��/_�L���_\\L���G��������|>�����d��������1�DDD���������-~�Z���|2b��f���{����w��By����������[�����W�^�cooo���J8�4i�s����!�"H^^Y�z5�<x@jkk���+�p�B��[72c��|]]������3����7o���W�gdd�	&SSS�t�R���$�����������Hqq�[>�m������<^�nY�fM������@����z
Q__Ov��E444���KBCC�zXJ���C)J�P]]
MMM�qUU�>}���\������:t`|yy9���k��������"3SJJJ���3�y����
��k[���3������2}}}}��������E��~��(--m�Q(��AII	*++QRR����g�X�����/����5�,���x��x<��y��WQQa|FFQSS���_���^)������$���#77�	������;�|����k���1x�`���c��9
����#��)���Bi���(((@hh(.]���� ����t��U��s ::!!!X�|�\��y�>}D:<�Y�f)�/]�L�@^^>�/�����2}QQQ+�����pp��)��������'q��a�������prrz#�P(-���*�?�>}� 44QQQ��$���b|HH���L���Axx8�w���OHH�S����O����	����z��o���?�����{��_�{(�������7bbb������@DFF���B�����������()��
�U���������s��a��UL'����9�b�dz�'�s��b���:��C���)������(g���W_}�����W����3-=<
��B8::b���puu��h�I������w7�9���$��@���r�2;	����sss��<��O1�������������{w�~�Z���|>|||��)��A
��*���`��	���������e�G����;vd��w��:t��'L���g����b�
6
���*������X�|9<<<���


�rc�S�N�}J[��KC���p��Yz�Bi�t�����022��E����a��epss�������r�J���a��������t�R8;;CUU&&&
y///l���~�)�,Y�������������L�q�Fl���������amm
p8l��
�7o����m}�)�2���5�&Auu5���Of	
��^�A;����FVVV[����sg�;wp��5�����G��Y�n>��3������)�����aaa���x�9s���c����=,`~�>������l|���"���y�@>����Z$%%����M�)))�y�&�nW_QQ������Il'�7W�^Emm-
}}���B��pRa�@\\x<*++%:	������Z���J���?~(**��9��WUU�����v�{
�������7����X:�GD�4�Cbcc������T������
���"�����������w�����V�gdd���;��������BE|ZZ������GGG��7y���7L8��6=??�&Mb�KNNFTT���`oo/�Eq��-|��G�r���<���3��y�����5X,��>22c�����9���������S�N!//��QQQ�����	��[7�c����Q�F)�kkk���c<y�#F�@��]�����x��^�|�������D)_YY����7o�d����#

aoo���Z������VVV�m��|������
���w�����j�z�
���077��oW���x���!GbJ~c>..N������?����@�P$??�����

ELLBCC�����>�qqq��������]�k��!$$jjjpssc:��=z`��8}�4����j�*8::2����A�0i�$<x�w���u�`cc�t�{�V�J[#~
�,������N��Bi!�pJ#p�\r��K���+�y�f���#�;555$::�L�0��������+�o��AF�EHaa�R������2t�Pr��!RRR����111a9r��=Z����jr��2p�@r��IRQQ!�/\�@�����D��S��x<r�����D"""�-���'O�$���$**��#���C�=�xccc�{�n���Lbbb$�/++#�V���wO�	RXXH�������\���C	���G����'�|�����'������d����'��Og|ff&��};5jy�����)))d��M��/�$��=S�����/^���W��3g���$�}||<Y�d	Y�p!IMMU�<��osH��/�������=��w/���/���|>���#�6m"S�La�p�������+�r�J���_�}�����G+����IMM
���", 3g�$$C�e�2�����Hmm-��� 3f� s��%�&`�:l�����6�t��6����\�~���s���
��r�����rIll,���		����@Z@���.5x_B������
���"!�,��@����s��r����!�gH@
�}��������555�����W�^�����Z��z��,\��t���	�y���@  YYYd������	��d��	����	����
h@�������wo��i��P(-������
,Y����8r��H;�������������
����������b������?q��	���������������q��i�={V)����l���o���d�������C�n�:���H�#F���
�}�v�������
{a������r�JDFF��e��?~<�n��Y�f!::Z�oj��[<5DCC'N��e���������"^WWW!���_c��%�6T���6
0y�d�~���X�j=z$����0m�4������x6�-�,���=��������k����������E���%f������c��-r���/���[[[��3]�t��������������
|}}���&��}�)J{A��^RR"�9����/^0^Z���/��������x�@bb"jjj���k���|jj*���P__���\������������3��:#G�l�`(�De��-[�zQ��_���l6���077��s����;;;f����
LMM��pp������\.�Yw-l���N�8���J����666��ka����<�%�w�����V�Zx��1���p��}�������)�SUU����v�
����
�����};LMMaee�\�(�mll`jj�
6�������)xR�s�\���`���pqq�$��~�
nnn������3g����lmm�����7�w��"�r���
TTT�s�N�����nigkk+����������pvv���)�����������G#''.\��%K���q��e|��'066f����������p��i899�K�.�������%���q��y�����pttdv`��000���%!��������,,,���#��}|�A����G6l��N�PZ�;v`������k��������������@  22FFF���`:	����u�V���_�p8���+�)`bb��[����7o������`dd������������[������hp�\��G�044d:��[����'L/SC_]]�Q�F����u�V�[��I���$&&"&&�f�DFF��a����������������^���8u��O������?����B��P�
�!?��<<<`ggLH�h �����
d����BY��f#&&F$ �����e�
�C;;;�Bq��r�
�\�t	A���
dyEBY^�@�~�����Arr2bcc�Ax�0$��������?W(��o��)3��>}�J;�1 �����5k���������������'�b��l�28�������������������K�.E�~���W/<y�D����DAA���`mm�%K����...�{�.n��%��y����pss������G����������2d
h@����|�]��z�Baa!rrr������c���m��P(���K(R�p8d��
�;��G��=�$��
��g�����&������!uM��s@�wvv&�����G�!c��e:���G$�o������.��={�����^�9`gg�d��Ibnn.���>�\�w��NNN����N��� 2`��&���<���K>��3���S����|���������������d��	��v|JJ
��a�;wn���/��+��+$��s@�_�p!��u�T/�����
����K��?����#�����i�&bcc#��@X<hee�h��<�`�baa�h��<?c���p������� x��;�z<����;���[�����s[�)�4 h�����Y�f�-[����lWSSC�������������S�����o������W�E�������Wd���$44Tj1�<���CCC�9a@@��_�srr���g���999d��!�fee��������kR�333�7o�$��x<���Nz��!��}}}&q|ee%IHH }��%�o�V�RQQA���2h� ��///'7n� #F� <P�������Rr�����Almm',)�������8��KJJ��S���i�$B"y���������s����D�}aa!	$K�.%)))JyZRH�P����d�����G�OOO��kW2j�()�����:t(���;v,�s����������L�0�<~�X�GGG��={�$VVVd�����7n����������^BK
�!,��
���/���l���������O���wq�����)�MLL0w�\\�zG���7o����055���q��q�<y%%%Jy###f��8���+���;������s�����k����M�p��%TWW��n�����6m��E�p��5���1�C��p8
���'�����`aa///���y^�r�D��������|�rL�>])/�����������o�)6T�������#G���E�$�
ey6���;���NNN"��B����+V�����E������A�`gg�u������
{`��a���6o��/^(�


������#99YaO�P(����\�����?@[[���pssCpp0n����
6������3�r���g��p��]�|���q��9a��]x��	 **
k������.@CC^^^Lildd$V�X!�iI!�=@A�N���?� 99Y���/_"22�)��P�����w�^��=�v��?t����cccp�\�;w999���;ttt��u�G�EYY��������733�������@.�+��O���
���D:�={�)S�0�s8������:::���e:	���\.6l���)lllDBy���
\.��-�����5�)������������
KKK�C[[[��]���3~~~��y3���{��6�
[[[t��Uj�������H'������q��O�������fc��]"��xMMM�X,\�v
��-�oAnn.��MMM������!!!pvv���	s���6�\.���q��q���FFF
��;���"99/^���:w���������-?~����3�X���?���}��
���DGG��?���GXX����z�j����{�Fzz:._����,������+W�D�^���O<}����;rrrp��At��M�_�z5����{��rss��={b���2���+��r1p�@���_���������;w��O>���KE|BBF��tP(mAEE�����k�����I?VVV8}�4-)��/�z
E.�KbccI}}=���#��M#k��!���"�W__O���O��O�n��$C>��3�{�nRPP�����#QQQd��A$88Xb/����g����	�{G�!���#����_�~�����;vL���� NNN���3���)�kkk��+W���
�r�
��R��EbjjJn��A�i�?��c����x��/�[[[%q|UU�B���Yj����@�www'�������E��G�D\LL�r��c�!�u�>>>d��!����M�n�JF�M�����iiid���d��I}����$�t�R2{�l���K��}\bp��)r��%���C���k"�zH
E��������)S������z��u��1����"����,^��t�����5K!������7d����S�Nd���$))I)���k2a�b``@V�\I222$���]b@is233��1c��:}��m��P(-�A���w/���n���K�.�r��v����Ef�X,���4:S@�wttdf�X,t�������|���e��L��|EE~��g�/^D��]Ef
��l���7:���f��)�����nt��"^|�@��
}hh(�.���������SSS�3�w��ymm�&o�hkkBH�3�����@��999�x���.��?gf��;4�I������n��Li�w���L����P�6:�@�����������HII���1�|l��G�������iS(��Ett4n�����*������666�OHH@xx8�����������|������_~AAA�����o_�����q��I����c�������o�1118q��|>tuu1h� �Y^1118s���GgP�===|���`�X�z���g��R�P��C��_���,�		N�>�P ��
d����BY�������H@����;w�H
������+pqq������T�@�o���,P�����,�������������`B������rCY����J���W�^2CY!��0|���* �p8puu���'�/_6��. ##���Bi�DGG����8q����q��U���
>��m���cG�������/_��A�n�p��]l�����Eaa!�]�&�w������������������"22\.W�wvvF�N��5k�`��a�����G�p��M���C����c��Q4 ��9���M IDAT
�p���`BH[�"���%���0j�(�9�@�G����={���y�D�m+�7n��!C�`���"��@ �?����[��������_~��S�B__�������������O?����L����Gq��%,]�k����E���_�t&������[��4i�H�A}}="##�r�Jl���G�����'�IPWW���,[����O��W�^����/����C��t��17nf��	011���
{{{������y�f=z9^�///���g����])_TT���p�8q{������R>??aaa������/�|>�O����D@@@������___&(�-�y��58�������NNN"���W8|��L�w�^���c��-�y������_�/((���/r�IArr2���PQQ�������k�.�?�3�-��}�@?:(�
�~�)������)q!.PSS�@�:4���|B��������j899���#���'��_���!��UUUQ__�555��lB��5��������fC]],�I^EEjjj�������555���czn>��#�Eouuu�������H��2����C�PSSk���������rfy���<ZZZpss���? 44'N���_]]
---��G������o���������'�����Q���ptt�x��SQQ�������������u���+>���N/
�=B�v���9�N���;w�</���m�6L�2�'OV����?��i���;|���J�;w�`��������~(��!�<��7������]A�;w�n���+p��q�/�������K�p8>22K�,�_�%���wO���/X�`�>}�$��U��3Gd�;v,���h@�l�����G�///��3g�G�)����p��I�?^�����K��c�p���_�^" ���A���q�����o��z�
�Bjj*�������o����$���===l��]�'''#  �Q?p�@�\���RSSaccC�;�������R�_�^�B�����/���3_8��9998�<���1w�\��@ @ff&N�>
sss��^E��k�p��<{��n�:DGGc��	������	.��H�������������I���+4h>��������e��~�
���������R��~��=�������{7((H���@ @\\�������K}}y�������H!�"�������O?���G�B[[[i��]l��}��e>{7l����4��3w��������*��|DGG#44���J���*�����p�:��/++�_��[�n1���~���G���%�k�dee���G��������y���������q+��BQ��Yp@i\.���9��]��dff����zRQQA/^�h��<_^^Nf���h1�,_WWG�������-&�����G

���9B������22l�0r��Q���eee�����>}Zj1aii�\���H._�,�xPQ/�������sss?f���B===��BjjjHVV���'7o�l������7�}���������X������X��@  �����?�$}��%�����
��a����������1c��'O�(�y<������)S��g���UUU$((���3�$%%)���������K[�BQ]]]����n�;���IUU��cY�d	IMMU����_�W�^�cooo2�|��+++������u��+s]��_?��B���C�u����a��5��B��s]q��e"Nmm-9y�$qqqa�[�nY�f
��]wyW�+Htt����W��9C:v�H(���sgr����6�"�A���w/�������"[�X,������g����9�����+�9"�s@�N
���[���|ii)����z�j�v$&&b���`�������i�s@CC�v
(�---�P���9Sj�@�`mm�9s�0���S"����O���?%��TTT����.]�H�P����@KK�6m��P����B ���G�s@�g�XPUU���^�|���|��w���p��	�����,hx���^�z�'NHt(�


�����~�M�s@�WSSC������C�������aEEn��-q�LY����p����v��c�.]
KKK��C���-�;��K�.�u�����>��Y�'�gdd ""����o��W�0n�8�����������B����x���,���u+���__�F��]Wp8�[����Boee����e�����Y��"55����3g 22�6���!��uEpp0<==E��^9v����+���b������o�n�:�Z�
��=���[L�6
055E~~>rssWWW������@����	E.�KbbbD�8�����wu�CB�os8z�h����-o��!1�����5{�C[[�fmq�����-��@  ���G�����ns�>nqH��1� ''�xzz6�u���P�;����Vy�����74���7(����IBB�;w.Y�x1IKKS�_�~]b�������������Nb��7o�^7���
�o�u��+W�^W\�x�|������3/��h�u�4��u�4��u��2� 66������#G���D�����#g��%��u#�����(����.�Kbcc%>���a�^>�ziA�~�Z���5C��?�X" ���o����7��Z���{�/�111���2����!���!C�4�uz�����PZa@@���yo����^��1���%5 ppph4xB�����X�������
i�����8��������666�D@��O��w��@���%%%�����?�-��Bi:4 h�BD?���a��+�a-���)���t���M>�[+$����D@����f'�UUU���.++k�L��^�K���w�������_���xH����o�����h�Aaa!122"eeeM~���Rbjj����P�.:::L@@H��7���5y�@C��Li~��5������_~)3x�o>���Cj@ �m���
i���v�����Csg(v����������>jR8 �������H�D��%4 h������?���a-�M��n��]N ���_" 4h�{�a.�?��C�!���?i^|&������B�LaH����e����U�����f�I����b�]�Fy����$����sm�I�+��@�O�6�L�<YdV���P�L�w�������������q��5z��n>4w�"��i������K���:��m#�n�Q(-��k�XXXH4��D����&'�B���q���-�;V����
���
ljH����h@@���/�������yyy�ZN�����������X��ey?�����v����:$hJ�@CG�B����"�	�������}
	~��G��`��U2�;�����3�w����i�����_7�un��A6n��#�PZz���p8d����?�===Ixxx�|LL:t(�z�j�|�����QQ������&�3C,��F�)v�-����N�%zM�F��b��&QQD%F��4B4�AQ��H�,x-�������s���p�^k�����: ���}�������on��a��$'''�u� `���p��c�3�rL��������F����<�9�=<<���ve
)T��a�8�O�������r��&�����k��:����y��Q��}
�?����������3���>��/**���'��������O_}�� ��e��)�TWWS���i��������c���4c�� �`R�����>������u<c�9������z�j
`_S�9dL�?��~����bu��S�D��'N��+���=]t�*^[]!�������R�Nw���0�!���O����+W�P|||\�	uI�!�r9}���F�W,�G�+���Cvvv�k�A����k�G���6�X/�7�*�X� ����<g`�y�D��pmm-<x�"##I&��3���{��Ig��\�.�\o�,sSRx��m������������� �����%]�|�h��/^����)!!�&N���h��?t�oc0�=zD_}��Q�
��EW��uS�4���={��/FW(W�2|ZZ�i��}M1�@��``����	&V?�����/^\W$AB�����3g�-y��FRRbccq��i��+�#��W��������������(,,������+�6�X�m�:���?��
��#�������p��%Kp��At��I�<bc�+f�v7nkkk�����p�����������|kkk<x���=Z�n
ggg�z[[[6�<44���:���2OMMEdd$���`��{�.>�!C����u��a���utU$�^$$$`��I���f���������w0|��-q��1��� 88666Z����HOO��1cYYY(//��8�����w�^�����8{�,�w��L�5k����h�"��A��������S�����������C���y����k���������g��*uS�+V�@��}9�bl��������C���;���pss��+� A$�PH��I1(,,��C�R\\g3����S�~��������r����\����9s��Pi�O�:E�:u�o���������R����[��	
�U�V�"���L��d����s����9B...�}�v���
������
���Z�����H���>y�����T�*�B��555�j�*
��?p��dQ9��������[����:u������4g�������\����r�����_�~t��y����b�����C�
���PA����:���O$H0V(�2{��{�"������U������X�z��V�P�axx��n�/�B.�)��^������+�9"�+��2�`t�X]!���+�x]u�)T<|�����cz��9s8�$$���s�x��sX�a�����7�a�w�]�t�A ����w��a��	��+��A�h�?��	��h��;��
��	��kk�����
��� �&@}0	���T��$x�B� 4ho-��n>�5	�����  z�o�����_~�i��G�h�����n����N�� FE�����\��Z����V�u�P������0W��g0�XG��Mc��`x�/�B�P���I��	����(�$0�!��b��I��W/���/�7����K������C_�	Z�����EX��P^^.�R��u�����h��M<�`���jMS���6����BA��MU�c�� �B����$����S���	�����y�f��
��=���O��i�����������+� A3$��!��x�\
E���a������N����w�W��2TU�^���\	 d���V
0&����R2���]�7n��9s�����s(����E��I�hER�um'P��J111���)�T)`�7��*7�O&��
U��n>��P���4	���UD�>}���A����E����=zP�N�(((�Z�h��>|����	�����^^^�c���b�����r�sss��9����5�g���_��\��@���7P_�@S������BA�N�T�TWW�j'0��a�LVo
���-L
���e�H��g��"
�G�����b��I`�7�������b��9Sp�:�ah]!�B100�d�Wi%K�.%{{{�	 �prr�U�V��%HP	I�!<<<���?���?O�z����������R��]i���z��N��v��	F�h���������b�!3����s�������|ff&yzzj����'�9r������8@��5����  zuXo���������	m�����\����V�\I���z�����d������A0d��������o������������o������0a}���|qq�Z�s����  "��u�dH0)XZZ������M{�&����4r�H���o��SSS)  �}�sXXXH�
���$��bu����E����\�u��A �%�H{]���VW���BW4n�X��BU����u�))�3��������Y�f��Y3����Prr2=z����)A�ZH*�!��i��4i�$����c��/����2���C��7�|C�n������-Y�D�������-�\� `E+W��~~hh(m��A���������[��,������ GDdee���
kkkZ�z���{������`��6<s7[�������Q�������z��������8�033�:u�D'O�\�{�n�����g������Q��})??_/�����!C���K�t��W�>}���7on��� Ak0C
�u�`���@�G��+W���
)T4L�:���
!��c��ju�&]%JW0�]�jX����)""�}.�b��;a���T
	���9s���(A[$%%a��q8s����kkk�{����y�f\�~����������dX�z5������@�����`��Ex��9��E����Jl���'O�������f��3f���l^1���P������r���#�������������L��������h�������v��a���,��O?!00����%K�`��]x��78y���qc����k�7k���������k�������3f�@xx8'�X���%%%���G||< ;;0`,--���s,^������������U�ggg�x\�~�7oFhh(u��������}��!44���Z�������DPP�35j��k�"..���"A�VHHH��q������m���yox]{WWWdee!++!!!������~�:���1f�@VV���1`��zOOO����^����<t��2�0k�,�]�s��U�4����`�����+���Go]1z�h�n���+
����Q�F>"B��=��(�E���X�b�����,	$�
0�C!�&��>D	�B)B�M�7PS���[����"�Hl�������a�+����C"�� (--�O>�D��(D� ���sh,CM�r&�PAxxx��8�����r�!���9���)JW9rDPW
)T�  �Kw���0��*�?��)AB}�d!cM=�H�2��oo��4��R�!�Hl�aXX�K��E������`��y��{�=����eD�c��A@dCM^L�all,AAAZE��I����2���&����R�p����� �$���3z����H��	�� 0B(D�E$������0W����
c�"q�j�*��|!�@�U4	�DFGG��(�$x��7�� ����v�����V�Z���H��������EX��P^^.:�0..NT�all,�����M�x���C��84��aaajc��I d4m�T��0��b+mmm�� (++#�LF���C������|	TB2�2��c�n���)�A��{�zu�+CU����	���B�������o��VT��1�{{{�AP]]M
6�/�����������?�&M��G� Ak�h���e���#���EE^�z��J111��fH�6��z�AhH�r�w}2	TU������� �B�����
�;w�h�4T�h��!u����=j�C�$�����E;v���.��?��(G?77W�����Y�xA���u:���
dx}{�5	4���I��. dt��Ie;Auu��vc(��dFo��{Wo1��� �T`nnNQQQF���}f(����z��AAAA�k�)���x�A� ())���/&���3g����b+�� ��3�I�&F�$��ARyF����9�y��������u�}}}9���1�����G����k�W,�G��  2��b�W_��,YB={�4���B�}�6}��7*��5�b�����Ee�w�������j@666���������,,,$�@�I����>��L�o� IDAT���wh�4�W�^��#G�7�|����J�s�����B4h%%%	��+��?/JW�����+��/�D��
U���B_��q��*���D��+LaHauu5�h���m�FYYY:=v��M�-���@rrrR�)A�! �<#�\.�#F���be���-�\� `�)�X�<bU��y��xUy�D�<be�����V�^-�������I!!!$�����fffR�N�������5e�k��))���$�\���Z������E^�	���Bc�;$$$�������+:�BC

S�N�7�B� ����Z��IWDEE��/FWl��U���};EDD���R�u�"LQW��APYYI]�t�/^�����M����$H�F3g��YW���III7n��9S/������Jl���'O�������f��)�X�<bU��y�����_0o�����ODxx8`��%��k�x�
����1�X���())A~~>�����������`ii����c������+g���-�Uggg�xCe����"22AAA0V��� ++}������iSl�������+� ��!!!������7�w�m�V���u�\]]������,������V+����HOO��1cYYY(//��8�===�o��z�+�����{w�d2��Y��v�Z��;W�n��+������`x�u������uk��(,,DNNF�8|�0�={�d���;a��b�����/���	5558p����g4h����������[o���I� �v($�������4j�(�4i]�|�^�|�y�����?����TTT�3���O}���Y�fQii�����g�G��`��y����P�A�^�x�������#-_�����x��'�u���f��;�x�w���������[��o_^�Ajj*�������y��={F�w���OOO����s�'O���-[($$D#�����kjjh��u��}{�������\9������b�
���+eff����s�.\H����8q�^�x�_QQA�f����:u���|II	M�2��
F�����7�
�;w�Pbb���������j$H�{�s����
���{�.|QQM�0�bcc�����/_
V�������+d2���BM��u��'N�������BhH�P�
�;�����w��B����*���U�����j�5kV\�	u� 0B(�*����r�+�BA��m
r��]&A���g�rX���=�^_@�W��/4����>��W6	t5��$0�@���E(D��1{��k(�������/����yA�V�T���$pvvV�b`h��u�
!�`��*u�1�|k����A�/���(66��N������B{��1�eI��B2���_�����"��a���R)��2�����a������:�B������'�*^�@� x���x�M}LE^��@�&A���� ������TC_�	+,,,�����������BT��k[)���4i�_��g:T�	`�7������7�@� 077W�;�����
E;;�zk|��wl����~J����o\�CB�A`�HLLDLL��egg�V�Za����r�
�r9�����A��"CBB�}�v�|ii)�r9,--Y��������an�����w�d2���Y����[�����G�i�����y�f|��^� (//������aC�d2N����+���1�|A������KKK�d24k�Lk���m���g�}�d24i�Dk���m����Q�{����g�DDD�3-Z��?��������\.G\\�r9|}}��
6����������M�\.���7�7n�X#/��`aa��s�������,��iS�����#))	���pssCyy9�m���'x5�`����������y�����x��%V�Z�\WWW�o������x��RRR���6m�\.���3�[XX   eee���_4����h��%�[YY!((/^����!��U����x����zAee%����^e	�0{�lt�����z�
B��{�:>;;YYY������gy#''G-��!������
c���jAmm-�L�������B&�����]�����\�xQ���r�
;�@]q��-��+��[�n��qfL�:��7�Y7���x�����1r�H�f899a����C�������������g�����X�f
��}��A�/4h���T�|�vvvHMM�����/K���`h�B����w"{�<cm�>}����3��G_�8�w�������:~��i�
������~RR�`��"���#���k������xEG_�q��m���4�*;����+;��������r��PA���Y^h=S	���x�JU<s�����<^�n�:~��a���������r��W��y�7n,�/AB}���9u��Up��voP�k�7��+��o�����Oz��w)((�}M1�@�R@(��?��+>��CQ��O�>:�
����EW���
!��t���Sc��C�
�
Eeh���������UE���	
� 0Bxzz�����������
D)))�������|������/T[[�3��Y���;8p@o>44���csrr(22����z��)�w��.\<LO�8A!!!���������V��v'''�w��2�����Z.�����U�������M�6����e����JII�n����3&A�>}(##�g2��kjj.X���
F>�������3g���c�����%�����'��)S���G�%�����(�7���	5m����mK;v�����+M�8��=���K�`
����/�������M|QQ�?�f��M�?����a���c���O����i��e�EW\�xQ������YWT�4��?��C��P���+T�������"���0�P���
� 0B��r=z4M�8�
��>��3�2e
]�vM/~���4c�*))�����i�������������c�+���)11Q�7��(22�V�^�2�XHiii�������]\\8��A`mmM��������O~~~�k�.����
		����~����?���oO���?~�8��������b�������7���~�Mp������w��������6����i�������z�j:t(�����������oZ�t)��w�>|��QSSC/^���7�'�|B:tP��.A���Rh�{�E���9��J1P4|����FW]�vU�4����hQ��������4�s}����>W4(�E����	i�"))	c��AAA��;��^�����W�^��j����a�����������*{5������agAaa!����{�Wy���O����W���-?r�H�y�m����o�������%K����c		���@�F� ����g��z�x???��iS�����fff���@BB�7P���eee���C||<�W3***0`�XZZ���|�rvf��z<x�����������W�7�
����K�.	�
��SSSi�3�����;w��D�����iS��j�
}��Axx8F��7�|-[�4��#A�VHHH��q���������:�
�k�`����r��:����HOOgg�dee���111�����������x���83RRR�t�R��A����i��������������������������Q���A@D���'�e�!FW(�����=���[/gH�`�0�C!�&��>D	�B)�z���Lm��:�o������T��"q(�<x�|||���D��B��q����� (++�	&���S�NQ�.]�pJ�`�P�9d���111�#�x]"/\�@/_�� ���=z� �L&�b`���'N�������B(���/���gt�X]�{�n�FfddH$�A`�P�94�("!^� h��m��"R�w��YpH�1D��8l��=�K�����>���^�$qh&�)u���_t��QC_�	ZA�  �5c��86l������X�|�2>|�g�j�J��CS5	���U��$x�B� 0`�J�a7������A A�� �!���777��"��<y���TN���]�`ccc�QDB�m���w�}��������H�G�����8�����%K8�eee������c�����III

�;�0%%�W2,6�L��������������Q�����q��Ut�����"A�F��;c�����
�W{������\�pAT����q���#srr���KKK�8q��b��aC�|�Rc�ann.���D�
e^W]��k�+6n����h����q(�����������M�6!44TPw�����r�S�Lq8m�4��+v���!C�H-$�A`�HLLDLL����u�o��U��Z�/--���V������	��wrr����9Ayy9N�>]os��z��=����������u9��xmku������������<�`�������P4	V�Z��P�o��Io������z���l�����AYY��;���~���"A�F��=�;w�����:�����l�&�:���C���EUU����AP[[�)S��&�:��o>�[���u4����t��/����1����b�
A�!VW�����5Ko]�f������A A� F�����7��|���������fy��Z�����7o"  ���,�xX��W�X�G�!  fff,�|���?~��g�r����#!!���G�
���0o��BBB8���a��		A�F�X^����W<��r99��;v��)d������]��:�������k�x�J4j��g��������`�����CJJ
���Ys���������/�������+}u���;���'''�W��x���1O�>Eqq1���D}Njj*\]]��c�:�2	^p��
s�]�!^��A�h������M!�U�V��k���1~�x�����c���J��}�����������Do]��|�EW$''��q��q�OY7h�����B��K]��eK���p+++L�:UPw��B7t�B�����+WJC
%H0�� �OOO�������W�M�:^(�XW>44���c��+�7�����#V�U��	�+�:99Q~~>g�)��5S�O�>�����A0d�����L�`��Y��x�Y��������~Aii)���W�gTTT���]�x���J���KKK���/_���io������i������c��
6P`` �\9���?���?���-[�Zt���E����|�u�P������M���?��+T���
!���#dmm��A����D��+�!�$�A`����4z��z�W������\� `�)�X�<bU��y��xUy�D�<be������M^�"�?N����������bp��qz��7���~\�)��X��MaH��;w�K�.z������� ���O���$Hx�`����`��E*���R
_�u��BA��]��M�"::Z��`x1�"--M�\��};EDD��
��C��+$�@��Aj10B$%%a��1(((�y��|ee%6l��i1(,,�����������#V�k�G��9r�`���#��e��`��%8v�BBBt�#V�����W��[ZZ���yyy������������%���/�6d`cc�f�+���7T�yjj*"##���������x��1N�>���]����C��y3�O����g�E���};���	�����7^^^���<�0������U��u��������RXRR����zddd�]q��y���[����,]�T�n��+���1m�4�u�;88��+>��3����tEaa!rrr0j�(�Z�={�d���;��
e�������w-qqqX�b6o����,������������XH�`p����sX���x���^�z�~�E�����/�� 55�(���F
�$��b?�P����"_�xaw��%z?�}�]*//7��!A�NP�9d���111�#�x]"/\�@/_�� ���=z� �L&sh���'N�������B(���/���gt�X]�{�n�Ffdd��
�7n��9s����=_%H0&HF&�044�[�FVVrrr���[[[�uupp@XX������xyyi��8::"<<?��3�_�ooo^T�:���X�v-���^T�_UU��9<|�0�����c�����m�b��ex��1|}}9���;��o���gxuw�y��Z����������Sann.8�X����:`���ptt�\.G�����/_�]�v�!���MCTT�L�'''������A����i�����	>>>,��xxx`���j��s����^^^,�������5����`,��s;w��),++CLL�W�	�����qc�X�...���d����!00O�<��u����777�yf��������?���...Z�VVVh���]��={����NNN��-!��������QW<y�������
`ee��������(��1			�!c$��
kkkv��y��^{�"�}�v��u���/Z�l��666		A^^�=
OOO����/>|�p*��?�[�n�������z;;;��P�������+RRR��_?^�����Z���u����(]���)�+
y1���������t��)S�������u�w��ELLL�� ``mm�.]�`��a���_q��=H_�$�PH��� `p��57nM�<�.]��s]/_�L��V���Wyw$


h��A4}�t���7x|^^����������^���'-^�X����3g����R�3wV�XAUUU:�uU����FO�<�[�l�� �x�"=�����)$$��l��[�
�m�6j��m���jkk9|mm�F>--����h���<����Z������������?xC
�~�m���{������)::��9��TUUE��-���{k����x��[�(!!�>���x�;*eee���_����);;[-i�UUU$��U��� �>�����\��yM��A��voP������3gx|qq1}����'��5kx��
�q�����)??��]1q�D�����K�t��IW���V0��LMWU�����buEzz�(]��bt���}�� P���[�
	F����l�2���[[[c��}(,,���7�����G�V������/**�9�-[�DHH~��W�����o���s�������T��J��eK�����
���2\�|�������8�...h��5V�X!�3QE���C�F� ��8���������y������w/���y1��������\.��i�����s�5�>>>pqq��9s����s�5����������K����s�����V����<<<p��M^�������4h��9�����A�������S	��E��r<z�7nT�o����}��������[��m�6�<�����a���]����txzz���?���~��+<x���,|��G��	�6��=����{o���������������R���������S�gff���3������c�� �������������������T
0��������E����B�d2�uEii)o&�&]�n�:^�����o�l��^��P�$�K]'O��T8::"--MPw�����prr�[W0��������x����e�"����h�"��?�1��H��B2��/F����U+�5[[[�0�t�[��@��V�����l^����+�����TUU!((���,�x�k��������1�_��9s�`��x��	���8_��'O� ,,M�6ey���a��h���Z>""��7�xX[XX 44T'^�0wrrB���9����o�)d��Z��^�|X���r��5�������r�N<�%��� IDAT��U���@�f�xAyy9������___v=c���`����������+�����
l��
^^^�����:~���������+�+}U|ZZz��a�Amm-jkk��CC_�	p��m���q�]�!^��A�h���������M!>88�������1a������c����	p���d2888��o>������v������_���7u����<�`��1���a�+�M�B��UW(�u�+���PQQ�1,--1e�A�!VW(�|�UW0������b����nH�5j��k�"..���"A�_0t	�><==)>>������F�I�W���w�����~H�6m�{��	��������o���k�.���^|�N�����}M1����3MTSS#XM'O���
��������z��)��������������9�r����#���r�2e}m������e����Z����T��O���C����������2��{��Qrr2
8�����k12d�WTT��
���(11�F�I7o����u���7�&N�H�n�,	����1��N�Jw��,	V�GEE}��	�������3g���C����/..���'�������Rg>--����1���]�������K_���|��(]QPP����9��s�Z��IWddd���]t����I�����Z��CU����u�)),--�������:�	��A`����4f��0a���	f�N�2������@m��c���i�{����
F�|��`o�&�����������>}�������B0�k�����D���z�m��Q�g�
�a�A���H&�qxe��������/����B?���^|ii)�k���n��;���

(**�v������M���'???�5����l���������:�����{����yB\��_�>��233��SRRh���������M!�@���t��e:p��_����#A�k�b`�{���D������O���|������g��7�B� x��w��M��O�>�t����W�<��o�Nm��a�+�u�"LQW��Ap��Mz���D���_	�R��"))	c�����W{�W�e�z��}}}�u�V��@mx�\�����j�+++�a�N�Aaa!���w�}��O��z $$�������S�g�
'��m��A||<����/��%K������������J��r9�����z�x�L���5k��;���
off��7P���8{�,����j1�����`aa�
`�������J<z�iii�������*����U�
��SSSi�-�=B������_����BQQ�����g��� ���I1���b��<Z���������-������<dee�f���_����tN�Aqq1�Y����r&`Z����x���8-k��Arr�J��IW��)h�;�7o����>}:���y����'O���Q��j1 "����}����+�yC�
Sh1�����+W��O>�9��/��q����$H� 0B$%%����'z����0�u��2��!e^����|ee%��_�1���1t�P� ����q0�"������ � X�x1,X���g��{xx�=@h��9lO���yooo��A��g�S�h(&Tl��`B!^��1]*�6l0z����'?~<�������I�&!**J2$�k0�W�PS!^�������#���y��c���K��	M]W���������~�-"##�L���"JW0�W_}��������I�x����������=��o���W��t���]u�2���8x������������q��Y����:?�o���{�b�����q$H��.a���b���G	�������zE������`��1D��8����D	�>��^1�0==]T��/6�L�����l��������w�����
})$�m`ZTUU��8LHHq8|�pQ�������O������iq(���+�f�n]����2���E�`�a���U���"$$Dt��������1���w��:yH�`L�*�III��������G	�O�>�U���fff&E�����~@��=y)���3x3eX�("KKK�X��S	PVV�K18w�
$q�j�*x{{�q�q�F^��>��%���
�y�&����������X�z5���
})$�m�;w.>�����x�w��8�����+WDE^�v
zG�������h��N�<�� h���6m�1�������d�t���7������Tl������
��S��y���.�P.�����8q���`�������2�L������9s���C����o��!C������'�?>lll���+++���� "������uL�Q���>����������]�&��gx}}���R@��1^A�=�V�_����[�n�D�9�B������+�>}*XA�����4 ���@�J�{7��>u7����$*]1HNN�=z���5n��7nL�����gO��e��T���C�-���~2x���m��*~��q4`�j��5�:�b��R�������'����O�YW
)������O�[�l�U:T���+�?.JW�E������WTVV�\.*�-jjj�����J���*��/F��9�����Z�����g�y�����^1�>�X����F^^�������3g��y�aaa:�+�:���W��G��o�)d*D�k�G���&�X�X	����f���*������
������J���l������@�R@_QQ�W��"�{�n�������=z}��-[�AW��i�#F��O?e�5


0j�(���	������}~~~��C��A��voP�+V
���������+	����`����o���	�� ��>��V
�9s2��z��`��}�tEzz:�]�������_q��M�tErr2�u��� 3flll����A��P�u��|]�
333TTTp*,--1e�A�!VW4l�P��P�P�GW������dee���>��3�6m��7b���uxe$���
	|xzzR||�k�+�&�X/�G�+��S'rttd_S�9�6�X�<bU��y�����?�<b��CGGG�����5��b�Ww����i����g�^��!CX����WIPUUE���*��5�b��o��%*�<**�$*�����g��I4g����9sf]^�	����4s����wh�4����4y�d�={6UVV�����Q`` ��� `p��5?~<-]�������/��:�
�
��;w��
�tEFF�(]����EW�������J]�ta_S�9T�;�L[W�B���;w(11Q��|���up5$�$��!��i��1�&�XH�����
�����#V�k�G��W�7L��#V6lllh����&�X�����}{���c_[�t)�1�����i���<�ND���5��{���� �7o%''�}O�����$Hx�`���� 11�bcc����:��!��~�)o�������2�y���A������(]��bt���������s��
��C��+L� � ��Bj10B$%%a����z�j��+V�+++�a�N�Aaa!����W�m�*^�<bu|\\��`B��G��/�pZ�,Y��g����[�<be^1�0L^�"oaa���
�={����1�h��V�^��86�\y0�6��Y����Y����Fs���Sl���G�V����lXXX��BX�|9;M�cs������CM�������{���!++�7�P��u^�aqq1�Y����2�0-]q�����[��5k� 99Y�n��+U����7�[WL�>���<]QXX��'O��a��g���{�u�]��BW�B���(**B���y��$$������������g��+V�+++y)���:t��Lvww�*�������~�Z�x1,X�N�W���a�)�����I'�={� ..� PN/P6	tM/P��I/P���2��a�I�f�B�V�P]]���2�#33O�<����+--Eff&�l��)S���� A+0�W?z�[�l�;���}}}�N/�uI/`xGGG��c���K�.j�LYW���������~�-"##�N/pqq�+�����[WDDD`��I<]QXX���l��g������f�+�Q�B�����B��GW<x������?��9s� 11;w����Gq��t�����'A�_0t	�>�r9egg7�X���K�.��2�o^�2_PP�K1���0�)��f�d2����`���)�����2����B)����g���}�T����n���D�� ������?�	Z�i1`PUU%jo`x1��oz������C�x-aaa�T���
�YG�[W����Z���KD�+��9��>S�N���{��buEHH�(]Q�I>>>�������=z���	����������������!!!8u�N�>
WWW����G�"//O#���
���]�v���+pwwW��������������~�	��������?{��WA����:��w\\\��M$''���������m��X�l?~,Xi��wwwG���1{�ld2g��&���������/��Y3p�3���+�K1h�����1k�,���A&������&���.���9|}}Y�q�===�����X�|9�������&M��+����^#��?���^^^h��	���x)g��������e�k�����<<<�;
LV��g����[[[����#\]]Y����{�.�n�
{{{�����[ZZ"((�����oZ�l	ggg�|yy9������`��y�?���L� �`2�;w.bccaoo������ ���qC��A��A899�����T`�	.]���G��������I�:u�SA��aCXYY!;;...h��%�^QWdgg���S��P�u�����Jmt��XA0u�T4o�\�n0E]QTT�'Np*v��A�$JWc���z�
�����[Wl����W������a�p��1\�~��1	�� 0B,[����c��lll�#G����nnn�����AAA����4��/_�����f�������"���7����9�[�l�F(VTTh��u�V�APVV���r��wOeYaJJ
�[YY�T6��[XX��o�,p���h��!�������#<<3f�`��r����{�3���	��;��Z���WWW,]������Z��y2_��&M�h�7l�������
����\E�`�����d����[d����`oo�3������Sl��Y-�u�V888���L&Cuu5+������!oaa�\���<x���*���,���0z�`��e�������_"..�&M��1q�D���p��J�`��={6������ �k�7��

���ggg�	`ee�P���������{�.����A���|���8}�4N�:WWW�I�����O���s�tEAA|||��EEE����IW����b�L����B�A��P6t�Bm�u�+5j����A������w���������z�
�_�|���"99111�� ^���f�� �`T�#������}{������������X����a����{7�]�N^��a����y3���KKK�W<���/\��1���0g��������h������������w��M�a��g��uk�|�v�8��k�����W<��7o��m�r�M�m��R�������3 N�|X[YYq�v4������
���u��/����ppp���9� (//G^^�����gL���Zl��������cye�@_YY�]�v������,�,���{�����;'�\Q�8p@%�q�F�����
��{�b������������-[��_����	�BBB���777����� �k�7��MOOO������I �"##�0a�W����1l�0����������7����~�
���z��={����X']����3>��S������u�&]����+����/_���;w8���&O�,�;��
����
�����[W��!�Bpww���~�/�����"A� 0B,[���l���0>q�=z777�h������[�j�������ys������c�����eK������������<y2��R&M����P����prr���gs�����������5�g���W�w#T�AAA���`����-Chh�F����7`(<<s��E��aff��?��� X�p!
��=��:11���������/�3������Y�6m���3����
6m����0����}U<�%�i����s'\\\����1jjj��;w"$$�������=CFF�����E�gLu�L&�������
�h��w7P_VV���|�n������r�������S'�6�={�c��a��A�>g���2dH]�	������#p��	��������foP�3&��+WPTT���������/p��1�?�_A���Y���s�}�6<==y������ ����_Wl��M']�v�Z�A��sg���t�&]����u�U
h�+�yFW,^�������#G����L��������3z��������������Y�~=k�I�`0�	����4a�7n����-O�>�������s�y����>���N�Jz��G�������\�"����/(( ;;;����k�����4H��""�w�}Wm��&>**������i��\��jjj���0��_?��B�5k���P���i���z�eeeE7n����_�t�z��A�7o�G������P�N�����}m���4b����wi��m���c�������?���Gp�&~��4h� :p��^������>��G�
�5���w�n�C
%H�_3��X���=�������9C_5��!��|�	o��������oHa�����M�b��A�t�������������m�����S���)S8�Q��0E]d�C
o��A����9��%H0HF���$�3eee�`B��A�U��c�{��}}}�w�^��@mx�L�_~�E�7P_YY�
6pZ
1x�`v}`` ��['����j��5��[���{����O�.���7�`����
�%K����+�������\w$$$�z�x�\���6m��7P����c{��:kkk�\����
oaa�[�n���3�����9���@���93����������eo��6������amxGGG������C��au|jj���J���&������;���u��y�����{ggg�3����_��^�v
����>}�^���/��&''c��M*u�&]������+���z���I�&<]QXX��'O�*z����G�,$]u�2���P����V�2�
��O��������E}�?����� � F���$����D�=8�� ���:@H��u0�"_YY�K1�����!CLf���L��_�t	����A�x�b��7���zbx[[[�-]����z
R�}||8�D�={� ..� PL(d�2�P�;|L����|ZZ�dH�`�`ggg�j��...:&T����q��
�Ap��1t��Q�`B�����+�����W/�A��o�w0����(]��			�t������Bdggsf<}�����^QwX[[���7t���>�"##�$�E�����b����4iR]�	�!F&��U�V��\9����b��&AUURSS9������wo��2��$���E���9C
�N���;��2�����l�0�;88p����};v��� (--ELL����z��Ip��t��A2$H020��8�T�I�o�>�����M��������G�p��A�Ap��%TVV�M/0�����C��}y1�^^^M/pqqy-7
y1����������C�N IDAT��������r�������;F�bP[[�)S�`��=��m���t~,]�.\�R$$���nnn&E$�?{��WA����N���&��U��K1h�������)�bL�5k�p*���x)g�����#��_GGG�#7o��+��$P,�U����#**J2$H02��;����~f����C�L���bQ�%%%8r�����.]����M����S����5F���&5F� h��y��8@QQ� ��w/u�L&3������m������ x��)������r\�rE�GEEH���d!�-[�~���qH�QD�������uv��7n��N �;88pr�sssQVV���r�s+++Q�������;L��{�",,�g8::��+S��L���O�o��!�]���[<�`�����d�JE� --M�JE��%�YYY���}iT���f�����y�AAP�1b4���$�11j�Q�����`�pB�FA��$*"h�"�h**("��M}?XU����1�������������9�����?��BBB����mUFVVV:ER����4>N�����<����t---�3g���/��CJJ
#�`��y���O3	LLLP\\L3D"233Yu����;6��PLJJ2�
������a��QGpp�V_}���P(DUUgp0(p��<G'�)KFi�G�����T�G����k#�P�W��_�t�f\�~.�8����Z�+�aaaZ�k�W��G{���5)$
���5�#V�k�G��'�SSS���+++�Ap��m�?�����'M���V���"���U�h(���am������e���K�hq�������G�H$��C�����tnP���nnnT�-�4	�x������;TLs����	P\\OOO�D"�z��}t���	�T��������7��III�`��i�����W�
�t�"���P��SWtvv���{4���������C_]������P�P�EWl����{477#77���7n�N_|���[GEs�`�������V>�X�<bU�&y��x�<buy����-[P[[KM�d���_~�q^����Fy��������y*o�k1g�#��s'� X�l&L�@����W�.�XO>��x<ddd���9994����	���CFFz�������������ad��&�*^�,s�����)�����v���/��8�,Y����<y�1wh:7(�5�T��	PYY������������mmm!�������3g�� ����L�s�����nnn����8t��u���{��������W_���M7��NNNppp�YW�<[����B�'u��+`ee�H1���������+�
E]u��u�� x��!rss1y�d���������1cF7�z�9�,r`���/�����c�����2�����>99�;v,�5���5�#V�k�G��W�7L�<�1c�)))okkK������by/��2���M�,>>�������#G{��%�<y��^]V��f�GFF�w�f���|>��q����$~��b�����'���6����Z���E��O?��q}\\�?FW����8���cU�u�b��	z�
��GW�Y��u]OOO'BCC�����O��7��E�!�QW����������'##�����WA`�HHH�g�}����D^�"___��[���H�RL�8��^]^��y��xM��U�lQD${����VA�r�JTVVB(j�G���G���wt�+�����q��]�9s�g�@�9���Vqt�h�Y��=4���2W�u�2OMM�b9p0@�)���������~��oj
�>w���J{�����1���]��o��(Y/))�G����/3�&%%��_U���
����:�
���d:����8�����+�R)������:�U��������B��EWl����+x<<==�~�^�zu��p��}�DBB>��6���"b����)�����I�^�B���H(6�r�
)�`��X�d	��Y������2L������A ++�f�@7�"�M�1�P,c����A����4�b��45%yggg�#�b1�b1n���0����6�P��t����1j�(�A@�o��1���������X�x�^��m�A*����S�mmmx��7���u�@ �KW(n>�q(���+rrr� �}�6��������8��A���QDl�������J3����BwVe���b���&����GDD�s�"���0�;88������o�>Z���j�73����:G�I������p� ����@��p������+����#�H$:G������8r�� �r�
����F����7o�[o���9tww������d�A*�2b/\���c�������o>(V(j�+���g�)�=���_J�p��Og H�@"�P�]/\����"�D"888����{������j��={������B!���������28;;3���C*������=�/�!!!������W��gO��L&c18z�(d2���hb���	}�����;Q]]�������l��	���c]�U�...���	GGG��bF����0�Y�����������={b��X�h�����W/��0`�$&&b��������#((+W�DGG|}}�E�b��wuu���kA���)�l����������Q� �JQ__�HD58"�	�i�&�����OII�w����F�����1~�xJL��	-,,�m�6XZZ��������A --
���*y�����|����?FFF�D~�VVVDkk+� ���������z����wq��!������E)_]]��r�E����>������C~n���R9w(���������?r����h&���
p��5;vL%���(--�FFFpttDaa!�B!D"u���(,,����^�B$�L6]����DW��1�����Z��w�
e�A]q��
�Ap���DP�z���� �����+�yR'��+v����'�A����o��NNNA��d*����iGS8p0Dp�b���=z45)
����������:�*��:uJ-��%����krG���AAA���'�~,,,��+� 88���U�#PUU�r����
���HOO�555hjj�������#�������;����
���b�1nnn4s��X,Fpp0~��477�.�}����������X�]\\�������A � �H������tvv2ku���+$	6n�###�bmbbB����@����������������SZY ����eLMM�9Y9�s�N�x<xxx���{����#���'e"�^�������	`nnOOO�d2���W%���kkk��������7���R��}��Egg'~��w�����<�[X[[���l�|^^���8�����������j�������q����C������z�*���aooO3�|>|}})@��9�����O�e���������P\\�I@��.���D/]q��y��������\H�R�����uFS]����H1����b
�9	��+�yu�A[]��G����GGG�����}u�D"����F�B�i�&��A��HLL4�
��O�b���8|�0233�y�f$''+���i~���������J�������+V���		�~&�����s������#��/�����l\�|~~~����x{{{:����KKK���K(,,���5lll(N�l0  @)��5\�r�f\�~,������+++�z�<���0Z���b]__�~����#""h���A~1ojj��h��/����x���i��������4X�P���kccc�����		��](���1.�/������x���C���;aaa�@�0jkkQQQ��M���c��������=�&�2���G������%�.���9d������������7C$�f����R�������c���/�A ��`dd�rw�����H���P�x�b�������6w��ls�:^��A/o����zE������C^^jjj�����+�p����	PTT7778;;S��o>��+N�:�.��
�P�;H���\�nP�III���O>����nP�+ymu�"�N7h�+?~����A`ee���XV����P�|P�+T��@�nP�+6l�`�=�j�*�<y?��#>��S�_s�����������>�"�����{(8�����W������������������hhh���#�����*��hii�P(�������6l@vv6������I9�~~~(--���),--�NN����=+�g���y����J1���/����vvv����������d8��N�*���b���EW������[�B,���������������s'� �����q�(�'�X������|>���g������iiipww��)������B�P��>y��v6���������+���)1D>�[XX���#���B~~>� hll��	�J��===add���H$XYY1*T�^^^hiiAII	���i�&cvssC�=�s���������\�t����k"""^X����!!!X�n�L����
���<x0����5e���`��%�:u*JJJsi(�;����
�x����Fee%�����Mx�@������a����2���)���555�D4]An>��+���q��	V]!_���'��+�
��"99�a���A$)�
�t���9�B������*H�`cc�<Y�uE�=)111Ju���+���t�:]�n�:�7<x��G�b��Z]gee�>}�`��)���o`gg??�gt�8�����A%|}}���g��O'


X����'��/�$���X����_�51w�\�����<�-[�������-�@���k���7��<y���������9����oX���2B(R�'''c������>P��<n�8b��J����QQQ���&cV�~���DCC+���/��1c�)))okkK|������655�&~��g��;w���'6n�H<|����4o[[���#��������#���7��g��!
DxyyQ?���'bbb(~��1��;X������w�y�����Y����YYY��I����~�{��!bbb�?���x��	��w����GFF�w�f��E��={��Knn.�k�z�-������z���7n���lY��s�.���AS>))��:u*���C���h����}����_�h����2����n�B^�nP������Rb��I*u�:]����+H�������d�QQQ���K��l�"==�

���?>1o�<�ku�<���P���
l|@@QPP�x�!������M��z���Z�o��Dccc7���� 0@$$$`��i�������g������"��������TY�����,��0g����b��E�={6���q���^�S�N��C�=`bb�={�(�3Vvv������P*�b�����~~~*���e�����/�������<����e�������I�o�>Z��U�PWW�G;�t��~~~����g�x???��� �H����8��xMLLP]]
SSSZ����%���X�];^�������1{�l��C>���]�v�z�J{h�������	eee6l������'n���zn��q�{�.�OMM}�c���!������c��)�������O���o�����s�K��b���F����S�k�8x� ��/��P>7h�;;;���k(((`�P�WUU1b+++1v�X���/^�[t�b�MxU�A��J��&�������R��NW���a���:�
���!���5*�9 ����0t�T*Eqq1�����_�^#�;�������:]��W�����$�� ���@�~��zkkkTUU� ������3			���Add$���|���
�y��---TUU���c��!�j�������<r�H]�r�n��QcBy���[�l�g����I���B�g��3	�X��1�<_YY���@� X�b�.]����������B�������a���jy{{��d2dffb��Y���) ��P���l<Y,��������MMMuj>�c��� 011��a�0x�`�=D"�z�-���B�4����65��q�>MMI^"�h��P�wvv��[�A~~>�����1![�����4&T��ix\^^�Q�F�����#44T������z�
�_�v�N�	I>..��+�R)
i=ZZZh�D^w��+7�iL��k��P����7x���������RJ�p����2�000��������e����ED.�/^������!33C�e���A��k�.�;@Ws������_+����������#F��]�Ih3fyh�^@�>Dxx8�I��y��W�a???�]�V�b-�)gZ���x<������M�bnaaA{������}�h=n������S��hxzz�e�i
@��wqq��W��X��������� ����
� ���������sz���pt5	��������G�����r444�L/x����$��y3F���9tuu}��NNNz�(�|�J������R���[��c��U���:���G����}�6���?a���������'8��A��o�"�DT��=z`��U�u&q���D"��������8tuu�L&c1�����}1�e�Ahq��o_$%%a���������%�h�������i����X�~���|��m�����F�����1~�x����;w���Z��C��a��Em�h/����1p�@� �����h�"|��GT���T��C///��sG�����Z����qx��5�8qFFF(--�@W�����g����I 
��N��u+������ann���8���n���0�$6������l>h��K����-�����'�A���#:t��V�K�.Ehh���8p�.p�b���=z45)�G������.]b]��>}J}��gO���;������7�a:--
o����K�����*���#==�f������I�����V��?y����6.m����C���kedee!$$�a�D"���5]���Z��:99A �\�{��A;.p��=�A@��W��iiiZ'���J�����5������CTTgp�``X�p!����8���I��Q$E����'`���;���"444`�������|��WJ���������I����H1�����i&A�=PRRB3�����;���n>��7m���q6>11���3h��������1y�d�����������������g V�X����#$$��E�I�*>;;�5�X�Q���;Z[[1u�Tl���p�6l��{��a��)�{V�W��_�v
W�\���_��4�+�*�X�����5g�f�k��Q�W��G{���5)$
���5�#����X,�z����j���+,,, Amm-***`aa��� �z�$hoo���{���iY��&�2���G�Y��|���4�|���:t���A0v�XZSQ�/F[[���is��	�6w��5�T��&���}0M6���yyy������������'S&@QQ������L]/�����8u�.\����&�������U�E]����0>����+�u�B��VW(��&@SSC7���u�������@3�����;�����t�:^ (�
�t��
����O�n�:L�6M�k�v�Z|����������88���z�j��������W�i�*^U�<^{�5���k8}�4������x{{c��
�C���j���={���������W��_|�q^����Fy��x����wM����c�^�b��q�|^�b���;i�L� IDATA\\��G���#�X(� ����xI��+&�-,,p��XYY!??�f466b��	T%������022BAA#��4T����������p���������k�.DDD�O����:u���
4��%K0u�T���0��P6w��5�BBB��+�P@�����D���������������x�@������a����2���)���555�D4]An>��+���q��	V]aoo���h�h��k�J�+�2���+���AXXD"�R��NW���C(j�+BBB@���k'il��b�666���`T����!�+z���H1���Q�;�]���������MMM ���211Q����u���A������g���C��{7�o���+))	K�.����q��aDFFb��5J�s��\���9(���/1{��g�W�p�BB*���������=�.]�Q^�"_VVF�B����db�������+�4�X����n���+�&f��1c�������%���k�����+�4WW�x��W�g|��b��A�������x"&&����C����hjjb\/�U���c����b���DFFk���1���_�,���Hb���J��
:;;	??��}8h>�O��q�6w4773^���EL�4������W67h���$b���DNN����1���C�����~��E���~��>>>�����+W�{uu5��P����p������4i�J��NW|��z�
u���"�.]J�����M$��+������P����������FQw��;u����t@h�o��x��@�/�G,Y�D��%�5�
DBB�M�����g�W<t�P4B����@��������b���+�����&�R��V��.�X�<���xyy1�)S�0����<����e�������I�o�>Z��U�PWW��u�"/Et���1aaa���J��j�X�z5n���Q^�<���q��=�>}�g�@�9�����x��k#����R�s@�����G�^�T:��>c[[[���SSS_�����tl��	G�������HLL��+W0o���=4�b������)����������3Q�]]]��
B����Z����3�]����F�U|UU#����c���]/�Hp���g�+���1x�`�.�"lll���ccc���t�"/�JM
��~��A���������5��R�T�O�>J{��---]!�JQ\\�� ��z/�;������<���D"��;0q�D��Q�t���d�---�����Q����`�_���*��}�[��F��*8$8��������DFFvk�|�ae�L&�{�����B������Z��������-[h���g1i��no ����1c��6��t��n�B{{;�,P�����TVV"00�2V�X��K�"%%��D���~�O�>ECC��y�������2�����5k�A�q(oh�^ ��������d��%��D���`��/�Ap��i������Z�<y�/_���%gpxa@NNN*��j�����N�����N=�tvv">>_�56m����
�y{@��C{{{8;;���[� ??���Wq(��qhggG�.��������033�:�0++���5j� X�|9BCCunL����Uc���Pj]��3��qa\\CWH�R�z���`�������###�t���y� 22�J�����>�������o477#77���7n�F_�F�BDD���}��3d�a```�F�����������	&���+V����9���)���C�("6������4�����1bD�w>|8�R@�1��1���E)3	>|���pZ��y��!""��D�3^���P��������_WW�}���z��u�����8${�b8���W�1���@,��e.������p�7��������DGGk�5j�(�������/H�@ ����q����?��C�� ?���b��pwwG}}=v���-[� 88��PU[����	���8z�(� (//GCC������|P�$�t�����z�*lll�6	6o����G3b]]]����>�@��X��MWH�RF�!9����U�V=��]���M���oc���m<|����z�p�`�x�8�����8u�����7�o����5kQ\\�8�w��u�����J~�����2���3gaooO���}��!���G�a���:u*Q__O}��-��@�TJ����~�-q��e����XL�������7��w���
�t�����*���?ODGG.Tz6P�1_�v�6l�zv������/�L�Z��������	�DB�A���D\�|���� ������k��e����?t�1|�p�����2^y<y��HOO'�|�M"55�qv����C���������B�9���x"22�qv�������_�1c��w�f�x�����L���;���YW}��b�
b������w��%�/_N|����C�T����/L�}��K�.������n��-������/�~V__O�]���<y2��~FOMxUs���b����u���k���_�����v��u�o�&,X@L�:����e�$ �3fk��a� �2e
��7�3f� �?��9@��3f��+�y�u_�1_�x�8w�����_�~����:�����z��N�%QZZ���HOO'
D����'\\\��}uE~~>1|�p"11�x��!�����g���ptt4�MMMDNN���
�\�">>�G����;�.�?  ���(..����,0((�����
�;�dV=l��	K�,AXX�B!��������[�b������F�= �����LFE3�:u
---�<c�P���`=zeeepvvV����"##�VAp��m�_q����!!!����x{{{���s����������@ �� �3f;;;���)))�s�|}}i;
...���kQ__�����8���`F��H$B��=��7���������p��������SSS*A�����R[d��H$�������
oooj���---������vxzz���������l��������� +�����o��������oll���C @,S��GG����9���`nn�DB�P������>|�:������ **��+��9a���������m��q)^,\���KKK������YYYT	�6������7`bbB��������C���8�����{&�\���q��1XZZ�*H���+8~�80}�t]---���Eyy9N�8Z��+���q��I��B���
��,��t�RH$�tEJJ
#�`���������
y���	�����]�p��
xxx�t����^��X,�JW�������VA������V�������'���������&����*����1<x��
�tEbb"��g���������Pp`����HNNf��t�g��I�;w����m����E�=moo'


��s����T�U������>��+Vs��!����[YYIL�6M-���3*��K�|���Dmm-�zy������c���I\�p�=z4��w��v�>{�,1|�pb��N1���  !����'Oo����^�?}�4������0�3����3�����8p�1v�Xb������������w�y���ek��a�(���m��'N$�����D��scc#���D|�����C��}��="!!A%��TA6L�kg����w�������1z�h������HJJ"��}b��}Z������������{���/X;�����%�����?�����?|MM
��������-ZD|��g��?��M�U&�_�NWh���[��y��eZ�
��T��^]�����&L ����(��|������'3*����Rwh�+���O����Dtt4�f�����6��/B�ADkk+Q^^N>|���q#����R��8pxQ�U ��Y���6664����W�^����acc>�O;[���z��L�0����������Y�	WWW����vY�.W����������<������#GPYY���X���9AAA(((@kk+���g

���S����������|gb}�LB$�O�>������)��LB,#$$���;,--akkK�;w������������~~~������lmm)G������,my��Q�3���TC P����)\]]!����+++������>�����d2�*1y�dP��W�=	N�:kkk�����>��>c633���'���PVVF���Y����J��;w"""��� �s��5����g�%K�`����p�cn�������={���T��:^��`ll�M�6Q��s�lmmaoo������u���5|||������
��|ZZ>����v�����9s&��
�G�!::��YPSS�7n����t��W�+4��?��C��4f///�<yR+]�VA��A��hmm�P(��
GGG���G�Egg'���v��\�E]akkK;�O���������1��R��}��CS]��711�D"������XYYQ
����������b��������G���HHH��c���>�����F�8�x�&|}}�y���}�����z�1..��������|�����6���K�.%.]���=��3��;w.q��Y�<cU|YY!
���
yL�6��?>��C� �������C;{�,������W<v�Xb��D]]�u��O��vvv��_~I��w�q����)G��'��>���Jb����/���z�Q��9"22�����~O���P�;��Cl���5o���������[�2�&>��k� �={�~�!�����������|�*8p�_��'n��A�[�;t�����iii:��s���UUUE�D""66�v6�����0am������2zAl����:u*����a� ���O��[�N/]������f�$��l~��J��NWL�6����C\�z�u�!u��x����TW|��w��"==���'+���;��NW��kkk���hZ�m�|��M�u��PA���C1h� �*9pxQ`��@��|0h� 8;;���Gaa!ZZZh�������������������T���#::qqq8u����S�N����!��4���N�>MMM��};._�L�����n7�������������e�TVV��������������g���322�j�*��}�q,������D��w�q����U�=z�@qq16o����zgaa����999���/	�D�O?��BZZ<x�������(�g&�O�4	���{���C��woDGG#++���G[[�3sEE���h?8p BCC������<~�X+��	�����C�����!C�����jn(((�~����;v`��-���A���1r�H��������K����w�F^^�<yB{���(���)��QWW��
c���KW������3	mt���@b���*u�:]��W_����7oFUU:;;i<�;�xm��~�z�����3Ju[J�<�u���Booo�9s� >>^�1;::��+���W1�����"!!S�L��!CP^^���"8;;3����?���R�������*��������QQQ��G�"))	+W���c�PWW///,[�o��#P


�u�-��,�����T*������*���[�l�5),--��I�X#�_���`�w���q��}�@W�{rr2����h $���7����� �,$���*QGV�X������~Ccc#�AY�������O�;����I��,�
���k���h
��x�q���dffb��Y����so��6u���{���L&�5.433���333''�n���������2��yyyQ�*���W���K/��W@��D"jn�����2��---8t��Z���R��p��%���+������)S�������{������S1�|Z���������X��	����D"Auu5:D�9,((@���i�	����B�q���`�HT���|�d2j��d����FW���a��Q�#qqq

U���
�P���{c������f4&$u�����LM�{��}���/JuE�>}�~�z���J�(,,�5)lnn��o�I��������Z�
6����Z���b���5���EW����6����-������(++��[�_FFF���9p��A`�HHH��q����O[�����upp05����C*�������3���p��I���`����t��n��'O����b�������PSSKKK�M��������#G�`���Z-�����D���c�:�27nd]�MU&Amm-"""h)s��EDD�����I���U����bN�!������o����71~�x`5	���)!.o<z��2��s�<��3gp��
�M�'N <<�38p00��;���O�<��P�>|X��0h� ��kmm��C����>��~��^z�1����L;;;���!;;�f\�z<`�l&���U����B������skk+.^��P�����y3F�M3����D���d�A�I�]�va����]}u����%�����[�j�� �Jq��I�AP\\���hV�������P�[ZZh�&&&pqq���3!�oA[]AjC7����O>�����g�"''�����?����d��y2��J������� �H$�����X�b}��}�������R)�{�=���#F���i�0k�,���+��hmmEee%rrr�����+W��?���[�����+�@���r����e��[���c�����]��\^�=�1��|������z�)))���d�k��������b���f1OKK�U���0b������o�*
�McccZ�!)�)��Y�988���x��)����V
(�o���A�q��"&&"��_MI5�P�������aaa�AKKK���H455� j]��$8~�8d2��?O3�����R@�$P����;"""0b����1�j��O�"!!����~mt��m�0l�0�A`nn�Q��6&���#���w�U[��d��2��MW��u�a?~FFF�����G���������
|||t�|��]���l8;;��P�+~��7L�8��
���4��_������C��G}���o�����?0x�`���B�3���=z4����������L��/"<<@WF�����mnn�^�z��7��g�}�/����hll���'�������\����5j%vrss@��l���222hAMM
��x1���g��<�1;88h��+.�YYYf���Z9�����{<��677S��.���������g999ppp�U������0	��yVc�����;T��3	rss�8.\OOO�|������Ett4���
2����
D+I������'�t�RXZZ�=N���;�


�>}:�.����'�={����l>������Q��I�������x�"z�����`K1�;w.�vv�Ip��i�=��g�&���>�����G����
333����GGG�?�Uwh{�@��H$�����3������������q6>11���3x�`�������***��O���+J�g����8q���M�g V�\���`�����Et��y�������:�
t-�...x��	-"G,,,���O=X}���������=z���"���;��u��u�����������G~1�|��J���4����k��������W�"$$����������W��K/���k;f�����s�v��/����4h����g-��4���G�����R���k��ETTM�hmme]��������L]������S�*$/_	`dd�P�0������j!$$���4	:;;���	�����U IDAT� /�#Ah;f'''455����������7�^�&�2~��������/XYY�����z���gk���7a�8::b��077��###XXX���[������#�1�Me���/N�<��7o���?�W���I�(�������^~�A��P�;t�<lmm������B\�pA+]����0�N�
�PH]����
E���C�aT�h3^KKK���O���d�mtEmm-i���%�����;��l�"���I����N�nP�+6l���� Pf��s����@�?6���c�����9p�	�A`�X�f
lll��gOZ^�&y������>m��G]]��;KKK��H�k1���#1}�t|��7��Ekkkj�W��9r�������eH�R��9S����O�����t��>}���f�$���B!�q�<��;w����8���M^qjj*����8H
�o�>8;;�~w����_�:��|����(((�L&Caa!� hll������0�@@�$�������S�Y�FFF�fV@��,/����������h2fSSSxzz����5�\]����%v������ �����d�L�>.\`�-�	 ��p��YX[[S�
4�������XL�4	��=���P^^SSS���������=z4�,Y�W_}���---������TTT������Ssi(��|>������b����2���)���7n�����
r�A�� y'''���g��\N����Z�
�
��� 888(�
�tEkk+�B!M7����x������w�����[u���-m�����oGgg'>��c]Ax�����mt�;;;S[�������
�t���k_� 55U�����'aee�� X�|9e�q�`���u���O�����ex��A���Gvv6��������X�l���oeeWWW���!??nnn��u�P|���������;PRRB5(�_������HNN��y��eL�8B�o��&~��\�t	nnn���7�|K�.Eee%<==Y���9*���\����V!��Y&��������������oq��0L�w�}3g�����)^� X�x1LMM1`��b��gO�1_}�=z�^�z1������{�s����)���nnn����g�}���z������P���b1~��G��?ooo`������W�^�H$X�b<x@K1�{�.�Dj��e���`����			 �v����S�N!66���4��������C� 
��m�'

���m�6����g��4@�u�V.�������DB�-���4 $$2�III�\����� !!&&&���5�l��	K�,AXX�B!��������[�b������F�= �����LF�U����^z	UUU����Y������p��QZ����8���+���s��!33Sk]A�����q
}�\[[333J���j�+233���#�R�R��NW=z������c���W P��L?P<n �1t���rss������ x�����@s]A������:���Q�y�����G8s��?��:v����p��5WPP�m��������88������i�������� ��|H��@�?s��R�����CQQ�B!i���~�Y^������\���3������M
�\�B;������
����������&|ss3>��s����W�^�����_�o��ggg�bt�io�������0�����f�\�---hkkc��������7ofM/��=zD�"@=�n���?�u!�L���:<y��������xPq1��U������>���0{�l��Ckkk���f_YYY�=	����U�R�)))����5T��G� ��h���#�S@���*>55�38p0@�)��FVVx<���� ������>n�8���Sk���k����i�����?Fll,F�{{{���������u+�.]���|,\��u���J{�����1����3f�z�D���
������z���@ ��a}��e����2t�6�������������V����W^y�����!�5Sw|��{���m�X{��uuu]!�JQTTD���$�uG@@�J]��_?�g�����[o����:f���i�w��6>99��0~��'�8qG�e����@YY+������XZZr�g 0e�2����y��/^���#m�666���7�m�6���C �x]#MLLP__�-[�����RL�4�[��T�dY_RR�������X�kjj�~�z���H(6���BPPe�X��/�o���L��$	z���m����������g������aff'''�!]��b�q���dff�*H��-�P���������l\��W�\�����F��q(�H����r� �D�������1���3cG�Z_��8�	&P����
QQQ�5k"##������@������lii��1�</�HP]]�0


��wo����}����i�����>c>t�����C]QVV�Q�F����8���j��������L���>�%��1!��_���+�R)
i=������oR�/�;?~�T7���`�����333��`�g�;v�����N�$_XX�BK�,�����#lll4����T�	gp0$p���9����;�H����Wg�D"P��QDl|CCRSSi��#G0|��n�+��$P�X��^ �`(""���p�������+���P4��$���������e����]�!������o��i0#e2���56�x��aU&����������'N�@xx�o>|3f������y�f��1PRR��?�����=:8p0T��;���O�<Q�^������S�q3y\�|vvvpttdpFFF���@dd$F�Ek��o�>TWW��^@��nwvv6� �z�*<x�6�Pq�A~
{cwww��CS]�y�f�=�s(�H�J/�����>��655���i�;�t�V!o#::�Uw$&&*�
���T%��sUUV�\���f�����+H�`�ARR����y����������/�Dbb"Uq���!�3�A �H��"R����h��:�@��6���'�q����choo�;��PM���DFF2R�����"rqq�D"Qi�3	�.���iii�J���F�AQQ�~�m����{����X�JE^�dX�3�����n���A�^h���/��_|�;w�PW��W�1��=��� ����r��.\����D"]s�&s�KNN����QPP���j������	&&&����������;v���U
(��?�L�����������C���=fl�C���m��a��a����\��C�X//�g2������w���u�� 8~�8���Xu����R� �o=����������:���~�
'N4x� 33���<;w��'�|��w���~�D||<F�Mu��"��8�<��Y�&�*���KZ'`�������A3jjj@��e�����l�����jdee!88�a8::vK^�:@�m�onnN;.p��}�A���Z���I���@����&%��xKKK����������za
���wc��UHMM��M�0}�t\�|o���+++�9s�����������p�Bxzz"00P������ZG+++�}�vTTT����HJJ���+q��1��������-�o����cC�=����[�ni|���'w������<y��g�Vz�@��Cw��������������s�Rk��&AMM
�����g�������-�������4�������g��t����I��������+1n�8�6���0p�@������2dH���� 0@�\�����LX>����\�r'N����+\\\(^ h��9sEEE���������"((g��U�?~%%%��������w��8q��Z�����z�*� �v�.\����;w����E��BS|DD�����#������,\�x���*���3�������~�
W�\��A����b1BCC�u�VTTT`�����t��=�&��A���@+����_q��M�B��'cOOO�����������<���b���<@xx�V���;������f��b�Ap��=����������������=z ++		�xr����������������u����L�oaa???�'c�?~��G�*�w���!C�����?�����c���?t�� �l***��W/�&�8�,Y��us��___�T���R8���h���]w\Tg�~�C��7)C'�%!���D���A��l�1�]���l�M�
�{Wc�����S�Qa�HQ�0(M@i��&��?���|���Ffr����G|�d&��>�y��}n�@^^���p��1TVV"))	033#��q����HOO�P(����]@���"����1iT���+���Fdee����x����Cpp0���8u��������?W����Z��]�v��U�VA$��g�.]���Jk���3vtt��Y�������������a����������t�o�3f��===���������o~��������ap�
�?���B�D"888y�AAAhmmECC,--�������%	���kkk�B���*>$$555�v��Y�������PUU�w�y�����k�"44���hoo����5��(P<���(**��������������t�H���������G-/�	�Au���q��M8;;�<3�p���X�h=%bbb777H$dee�����c��755���;|}}������A899i�������nnn8w�������D?��������GGG�������A����_|���t\��077���7lllPRR�;w�����n���jy___������r������������abbGGGV�����J���dL�6�h
���O����x�"��G����a���������������l�`bb�L�^x����7o^{�5l���>�(���044���/#--
�w�����������&w�+0�lmm�����������������u�222�}!�A�h�"������077't�@  t���s�[}f��Jw�d2�t�A`` ���T���Pl$��W `�������HWP�(]q��Q

��W^p/� 66V��P�~��1pWw��+�!����-�<AAA����/�5k����W���7Y���_���]+?{��|``@k~����u����������Z���_�����������/^�(wvv��y����g�y����7��x�
yii�|dd�����W�o������Z~��m����X����+���������������W��8�\._�d	�/Y�D��w������|��5�k���^{��M�s�='���Ot�����K�.�o��Y����5_WW'�����m����k��������#?~<�g;v������4�b�
�?��Oygg'�������+W�w��)�����?{�����^����W����5��Q��/�,ONN����j���9S��O?���X��?�����q�F��]�r������m���7�������������	��������|��
��zHnbb"  ����/Y�D�������W�^-���_�7n���OKK�O�0�����7�W�^�z��]���������3�����+�L�"?y�$���]�V�nP�+~��KAS���+>,������7m�$��w��a�E(�������)��+BCC����Z�W<x�~������5k�`dd���������;�����M����c��������,�����GAA������
�HD8�����N�����j�����

Bff&.^�OOO8;;KrBBB����L???VT�:><<G�����D�,��?p�FL@dd$<H�'N� &�o�333\�~�����O�����hiiQ���������_~�mmm�H$*y�����5D"�;���.j�tww#??����s( p��I��������k��VRRR088����]u���#FFFp��Y�����������b1n�����`E$*��:����������k�`���8r��q����J1������;w�h}6(��������������O���[�i��������(((���KY����������������V�aUU�,YB����MMM*uEQQ�-���s���:m?sAA��������x��'�	�o�����S���
M���X���2�X�j�{s����GQw���+�
MMM�������W���������={��<x�x�������+Wb����r�
�����i�1Mu�.��<5�w��9�b��������{	��������e�fddps���2@O��>|��Xk�GFF"99��$��)�������A�m�6l��))),�Tf0���v���(3	�|ww7Q���?e���W\�dnn���?~���@�����_Y&u�@�	��W�.�%����ue&�2>99��
���H�����J�pss���3�R)������!���"..�}������<��A���B���
�����leee���� ����)�`cc���P<��SX�v-��}"&tpp�~=u����YYY,������FKK� ���Fpp0aP�
u�"O�����C(�����,�����k��������b���$Q���R)��������X�ha���c���Ju�:]��3g��������.?c
�����L&C~~>�����X�p!��W�W�^U����E0r����x�����}e���>��?�WWW�tEQQ�,Y�<x�x��A��\�bML��c]L��4�����HLL$���Oc���Z��6	�&�:���G%����[�6m�F&�*���CjMU��?��Q�V���y�x�okk��#G����X�t)p�����\�����&�oa�;w��w���`��)��e���[������[�l���~���������y3bcc������1(�@(�g��[�4:n����$������N�>���Q�����0���8�6�_����l�!][�����o����g	����+���b�\&�������{���~���\\\���	��������H��)�������z5Y��M�����R7hb\�t	�����N ������vvv�����}�6LLL�n>Pi�A^^.\�Tw��
{������9y???|���hnnfM j�3��;���LL(j�+jkk�t�R� ��c�� ���dsm'�<3�X[����M�Ie��q�XW�X&m��������1c+� ""B�Ie����F��xggg�}e���G�I���V�A^^�,YBL(�CCCZM
0y���.&�����N
(�0c��5����/��2Z[[Q[[���a��}������|���~�<xh���8�\������j R|__��`ff��7o����(,,��)����s)))8v��F���[�n����0�r9$	��SW�j>�;wN������@  �������+���z7���0{�l�A`ee�V7��+���������
AAA���%~�������$�����+ZZZXAQQ���9uG``�o�|����������s�':�H�	�C���^�
<��A`���c.\H��S�\&��t�@]��6&Aqq�V�	�x�P�'NAss3���\$�e8;;k���k?~QQQ,�@,ku�����:���okkK\���b�������Ip��	��0y]�>����ht���OMM���s�� ��7�=�6m���+W���_��;�f�xzz�����Ck������aaa��*��������������?���	~��qpuuE{{���	����F�UaE IDATdgg����H1��
�^'�������_|���R��r�D���|�J1x������[���a�������5i����}���]A%�("������C_]���`oo���V|��hiiAHH�wk��q�eBq��]x��gy���1o �o����p"+��"�}f^1��W������������4�4�����())a�+su��P[[Kuuu���O������
V^�b1�����i���>�b~��EL�:U%?c����X�kjjXy��x�bN-OR��?�L,)��H�*����D&�:�i��������g���^V�:���Ou
���vtvvbpp��������)=	��U�5)����u���033#����&<�MNA��J�J������'�0j�����@h���J#�x�0����������������5=T��	���	������I��@qq1����n�:�bcbbh 77������b�A]A�\����R����*uGaa�V�b��],�`��U�D����A��`���
&?u��K�000@���x��79u�����|P�+:�k��q����.���o�����1F�
�?���B�D""��*�T^���%X��*^"����MMM����7����*�+�X]^1����CUU�y�w
�L��k���+f��B�������"\�~]-�I�*^,s^'��#NNN&��[�b��E��7uy��x����"77���prr��W�G����Q\\���Aoo/^|�EcddNNN�$���7�%af�S&�*^U����s���/�������I���o+�����z��}��t�R������.k\�cE||<^�u�����M�e�&g�*�2PSSSSS888h���u�Aoo/-ZD����������9�+���>�"((���:�
�D�L����� ����J��NWPu_W]!
���������P�t���G144�W^y�����X��c�u5�������/y���1o ���a��I������5<<<���GAaa!N�>
{{{���*^(���CZZ222�����N��wpp�O<�#G��	�XLsu|`` v���w�}�=� &&NNN�={6������b�����g����Byy9����y������ ��8��,X�_SS�y�`�������P__O�L� >>w������Y��x�	|��ghnnFHH�����)���1i�$l������� u������ �H�c�\�~�5���777G`` ������_���6lp� hkk��o�M�}}} ��1�]�vq^'P�[YY!<<r�{���	V�GEE������������!��*>))��S���+�D"��5,�����}��-[�m�6xzz�gs��>g���Aokk��~---������,������6���;�_�����kL�<���8~��}�vvvz�
�P������_1s�L� ���GII�R��NW�������YWP�D"�YW�d2DDD�t���=�R)��Y��9T�;���A�����7			X�f
FFFT�+��	����t��&�6y�L���������111�������(��	�M�2�+���bqXXN�8A��o����_�N����b��@.>44�X daa�t��X����y�@���n�����7�@�
�<y�q��.q���W�e����J����� (((�|�?��j��������+����CP)>>>J�����KM��
������@vv6k��*����sXUU�%K�����@SS��BWP#�����~�s��)�
�tEPPN�:�������j�u�3u�L&CAAV�Z�4((����p�t��VW0y]t��={x���1o �r�JL�>]e����Im#u�+f������w/a�?���F�^�,��s�PKK���i�`��m��y3RRR��2���?���]��C}�S�D"!��������X�~=� ��8T4	t�8dN<��Cooo$''�A0q�Dl��S�N%F\��u�Vz��Ce����RS�����9��������2����6�P�7&]QZZ��9������u^L��������_~�Eg]��|��d���'v��q.��u���W�����������+����d�� ��c�*�088X�("M��b�.�\�(".�������Ap��iL�>�wqH��>�(����������w�6�\�-���M�!���
G�!v466b�����}}}�9��kd�A����3��������G}�C����	�������L&�������/�`��Mc��y���A 
����DR<���������+�����o����g	����+���R�^`�����D�A�i�&xxx<��U�o�|��d�����<,\�P����sBQ[]Q[[��K��c� 0@P����oE�m1�6���7n��������2	1c�V�ADD�oE�I1���c=z��hiia����a��%�����+�����8d��b(�k+�0c��5V�Z�w�y��������3g��O?!99��:q�lmm�"<x:����r�J������T��C___���i5e������qH��n�BEEa��rH$�"���������g�++�q� uEKK� (**B?���������/�`�AMM
n��N~tt������u<��A`���c.\???d�.�>����gF js���
�8q�a477C h\�E"�^���q�Ip��qDEE��X�w^�>c��am���x[[[��@WW� ����@  &
M*"Q�`,G�SSS1w�\�5���������{O?�4������7o&N����"���{c��y��qqq���DXX�}��dee��U$&�����u.���������"R�a���	�����b���o����fP	>��H$Bcc#���WW�������v����>k�Aqq1z�!$$$ 66NNN����a���?!33�����a�
����Nd�SQD��+�KJJP\\�2�X�����#T�3�.����0�����'�h�W<m�4������3��#�&���G?��3���2D"��y��b�*����$�X�|�wssc��������� ��M	_SSSz@1��kR���u��NY�L^�,����c���x��'�� ������3��;�`��iJ��|�I���k�������F������%LMM��C����kz6��) 33����yE�@���b���c��u������&��_�aK������x]uEYY
���v�b�V��H$�_��
�t��VW0���+.]����� �����o���;��������9�������o�zIaMM
����\�U�V�����=Dii)������������A �����8���!887n��������C����Pttt���
fffprr"������q��U�d2z�O���&|ii)JJJX1�k��Edd$���QSS[[[899�'''�����P(d9�=�d2.]���������3	G��	(++��������������~�a���...4��9��u+��������W����Q\\���F��bzY�:��

��������X{{{�x333xzz���.\@kk+�b1-�����,www������+())!���^�Y��������H$�;����������������HDw,--������@ @yy9��� ��n��S�SY�pvv�����5`nn��ONN6����

����������<y�xW<x����x�������e���
�xM�U���-!��QYY���a8;;��
�x�@���oC*����X�h$	���PYY�;w��B ��+���������

Ess�V�b��=,����B�P�nP�+jjj�������x���6������4S����3����+���^�All�R�1�����T/]a�1�~~~x��G������"f�����p|��G�4,<��A`����/1m�4�����b1�4i***p��)V��:���S�L��s�p��Y�<cU�P(�#�<��g�"##b��56������w�}�2bbb�����{G�ENN<<<Xy��=����������c�����1c�Z~���(..FPP����bM�!k�!<<��������s�b��(--�y.����S�L�����	\]]���TUU!44Tc~��q�����	��W_������t�Q������������k�\��DB?���������777����F{{;6l���A�����7���
{��Akk+1Vhaa������a��}�~�:h!������D"���	���q��
�uu|hh(���?bxx�5R��OJJ2�����C�b'�C��-[�u�Vxyy�gGPP�Vg�*^�������Add$:::p��a������[c����������N,^�����&L@}}=�?~�u�@ �KW���i�+N�:��3gATT��;�T7��G�Evv���������������x��W�1��t`����
����R���QQQ�9��������Y��������]X��d///�y��x___\�t	�E�����GEE��Cu<W�auu5bbb�����EEE�b�������X�Z>,,iii())A`` Q�5���W���!,,���'O����'	�`���prrB}}=Q����;���,�\|xx8Q\,,,������������

%�����������T455!((H+^ ��������q#2�P @(����,����aee���ttuu;4����������DBff&���XY�����D�6����?��^z�8�x�0TP)�Cuzz:n�������4:4�]\\������l�	��ohh`�VVVb�����Q����.tE]]���C�~�-***��u�"00���:�
�/**�YW�������,]!��PPP�U�V 

��#""B/]����L^]���h��
� 0@$$$���q��������[�<cm�����:��;X^^�rA�ec���E�����#����ku<�w��Xk�GFF*5	���	�����m��a�������t��b��b����x��q�]S�b������bmff777������3�b��+F���cxx����������9<<<���������8O�P�S;	n�����+�����A����������W�WOO���������W+�����!�2�b1}vP9���
L�kR@����������Sjp�����z�*� ������aP;
us��XtEQQ+�p����0a�R��NW888��+(>55Ug]�'N�t�L&C~~>����FBAQwTWW��+��mu��EW���`��%�A����7T��D"!����Z��cM�����F&�*�������A������h���X�L@�I ��M,)��q#�M��q�V��8qB/�����kU|[[������#G�;�t�R�4	$��&����&Aqq�Q� X�r%��]�;v(����/������Q�\��XX�����2�B!}v��r��E>--McQ/�����x333���"--�0ZZZ����2�Lcl>$&&b�����C777�&�o�+���L&c�feea���������c�|`N(j�+d2�-[f4����n����7���>��c�������'�*��W_�M���F��e<xx��A���D1�����$ppp��X3y�����fff��oa���������e$%%a�������P�}.���['G���b����2>%%��hiia����`�������I����g��b(�k+�����:� 55/^�O<���pH$���������y��3f���e��6j�+V�[�-,,�2)~ppP�)#.^*�j4)�����D?����`ttQQQ��L���III�5k� ����hR��tEkk+� ���@{{;��������/�`A}}=f��E'J������g�����1s�L�^N�<��/���7���/c��=��xx�����������7�+����+����Z;��|^^�V�	�x{{{�<y�0�������q1wuu�z�O���Z���c?~���,�@,k=���`H���q��i=�������zzz8
SSSb�@�$8}��^&�X��9ss��5Z� 77�f�����o���_+W�����g�Z�
UUUx����J<qqq���oW�,--u����{zz4�N�����"++]]]D�A?��_��:��7v���J1x������{3	����@$����Sw��+�G�A�	��;w��g�5
�`���������/^�������]]]hll�?����gSw&&&������[�7xx���}�v���1bT���+W���///xyy��b�V�Scjpuu�y�	��/++��s�ND�(su|nn.���	������_Q\\���L�4�X��X�

�ZE���"<���*�Y�f���uqq���b1�p�,X@�L��'bI!e�D"V��x�"�xH�,����D��:^�X�>}W�^%��5������Ttuu����ettt���]]]D�eXXX --
�����'�$P���rH�R��}QQQ4�(���g�����9���(�322�����7�	���6�?��ig�����������&y�0D������###�������kz6��) ++���Me���?JKKq��e�[���������&@vv6D"1���|�GW\�rYYY:�������h�+v���2(��S7��L^[]�����())��[�����
o�����WW0���
�	E]u�7�|cK
SSS�������;������s�����?�
6 <<�O�����1�|z��B\\� �aX�
DBB�B!+�8  7o�Duu5+�X>((]]]��d�<b�X��%	Z[[QSS��+���:���%%%����^{
!!!hjj��K�Xy�T1ojjBuu5+��*�����y���L&c�S�����3������K��b^VV��#��9�?>=%BkJq����b<~�x��������T����Byy9g^�*�z�wqqAee%�\����� �������QYY����D"""����x�"+��2T����������YY���W����������rJ����+�����zATT�Js����	���p��m�a�CE||<�z�-466��M�e�&g�*�2�r9���0<<ggg���2�������J�����2���Q]]�;w���j>��+p��u�uEPP�]������g� ����P(T����K�.���Ag]A����:�
ggg�$�tEzz:�����+���b�Tw����&u��sx��������>#R-���"""��K/���[�n���?O'���s�}�� �aX�
��_~�i��!77���k�G����#V�W��}||��w��������5�#V�k�G��/**��+��#�2���1e����
9�������777����F{{;6l���A�����7���
{���L/����U@\'P���enii�W�yRR�Q�h����������e�l��^^^�������Ww6��mll���>|��:�*����������N,^��]`��	����������z�
;;;�u��S�0s�L� �����s���u���������YWP�>�����SWX[[###���*2�P���[W�A�s�N������_�����"&&�����q#^x������o �f�����.���<W�auu5bbb����+�4�X�i�*^����#���'	�`���prrB}}��y�L^1��>�Xq�0�[^�"/������\l��s�~t� IDAT(�Fw����r��Mxm�����Y�����/������{����O��%�*��z�NOOg-5�?;����\\\��P�744�b+++�x�bB7xxx����w�+���0g�� ���oQQQ�T7���������YWP|QQ���"--
���g�
�L����Z�
iPP�z�
&���`������D�0
1q�Dxzz���i�����
���:�{�9XXX��o ��?��?���Gq�\Aqq1V�Xa4��EQ`.jmmEDDml������("}�S|pp0�xpxx�������W�!s�@��CE~,"}}}q��A�6��}���!11Q����;�i�&�����w������F��Xl0KM)���O�����Q�������,� 77~~~j#����+����h�"� ��y3&L���bB�#�����������'X�B&�!??��A@]#���;��������.��ImuEII	�,Yb�A?rrr0c����Kaaa

���������;� �aX�
sH��s������D� HIIAtt�QoVe�d2DGGK
7n��i���y�>[�)����x�omm��#G�


X�t)v�akk+$���]]]�+�P_������w$&&����hhhP������s�b��]��<�A 
����D@ZZ�^�������:Gfgg������HKK#��������84��Cbb".\��9tss��GG����@-�V4���0�|N�q���1o>0'��2���-3x� 88��9������h�[��'O&��*���'N���QSS�7xx��A���FE�����a��}�A��������"Rf$%%a��������1�"��zE��� %%��hii��9\�x1g����g��8LKKc��b(�k+�����:� 33...8q�>��Cl��	���.�������?����ys��Q!..+V����SKM�#���188�W�����R���������D?����`ttQQQj#�������Y�f�++��]�aXXZ[[YAEE���9uG``��7��P<x� ^x��7LLL0c�����HII��' �������s�*}�����S����
� 0@|���x����`�QD�8��|nn���>3�H��\���=N�<I���pww������j=�����b����1	�?���H�A ���+�g���2���oooO\����4LMM�IE�����z�c=2|����;�h
���B<����3glmmaccC|YZZ�ey�0���A,#<<��]E�����*������:������,tuu)���X�~�����|��{7+������k���$(++#�H���^N������}'w���g�}��
���sll,��///L�4	�6m"�,pA("66�u]���o �o����L�<��3*�H�<bU<5��k^qYY+�P�W��sssQ__O�����_��q^qtt�Vy�L^�<bm���y���O?K
)�@$��W�i�2^�<bu<��������.xyy����������S�N�_O�HKKC?�U�4	��r�\�,sE����:e����b���F=A���Hb)�������###�������kz6��) ++���Me���?JKKq��e�[���������&@vv6D"�����+6��W�\AVV������999Z��]�v��t���
�t��VW0���+JJJp��-� ����o���;�������BqBQW]��7���B
&&&		���s�`���kkk��ap�
DBB���`ff�XLv�@�D���Q�X��bb��:>$$CCC8�<�r9D"qwP�7n���������n1�����Eaa!+����^Cxx8���PPP�D"������<�������H������s*����D"����C������jywwwV^���Q__���\�g������'�D@@�{�:<<uuu(,,���;�5[O���`\�|���pss�����fffpww����QSS��/�������������7���QQQ���J� ����������.]����q077���7\]]Q]]��������	V�������/^DKK\\\��sMx�@@�m���Y�~~~���S�'''����TWW���CS�����>@SS����lP�kr6����|+++������...���:���###�J�������E`` LMMQRR���~BW�����+$	u�!!!����JW����e8;;���^�nP�+�I]u�3'��"�"�����tE^^:;;�z�j�Rbbb���������KWK�!�G����/���������+���Edd$jkkq��I�������.��x�@�	&���)))�������Z�����0i�$�;wg���������b�	��������e������S�L�T*���g���WWW��S��' �J��T�
��6m�Z���C���DPP����b������h����4DDDQo����>}:���E�L�`��������)S�bjbb�H���'#))	����uxx8���{���"$$�;T����������Grr2���Lku<�����������]#b[[[�������
?����� �H����vvv���������@Z���-,,���SSS����������?����

��[�p��a������������$�N1x�������
���.��������7�������7����'N|@����e�l��^^^��!�H�:T���u���5BBB����c��app����	���v���9C� �����%K�5���p��U�8q���
[[[�t�@ �ZW�9s3g�$���hdff*�
�t�T*��3gt���������fff�������
��9T�;���A�����7			X�f
lll��!{zz������077'��&����������*������G]]���X�\�sX]]��������Fvv6���D"AYY���X�Z>44������fkM���,dgg��9DDD ;;��SRR�`������Cyy9Q��{y����(,,T�GDDw�nzvv6����b�����c����pssCvv6���!�H��mmmq��
���shkk'''dgg���AAAD^���=lmm����24�annN�dE!�	������Q��(�U����Fm����g��\.��O>���T�Y���������D�����ny��T����7}v�r60���@��My

!;;CCC���!F���


�����2,^���
���Jw��+0g�� ����Q__�T7��(--�YWP<�Ih�;�R)KW�d2W(���������KW0ymu��EW$%%�c� 0@$$$ 66���D1���#{ttt ++�U�������J��:��;���������B�X��p�%��b.
��X����ce�Z�i0E�������m��!..����blbbggg����3���q� �������,�<�X������Ui1��CCC�����A;v���@��C'''dee�Lj'�2@oaa///���#++�����������R!��?t��Q)))�5k.\��/���B__"##	{��y|�����y3>��C��9��������W^ye?���HD�R�T����kz6������I

!++�ep�~~~�v�� �������V��IW�������&���8DEE)�
�t����^���

t�aaa���L���|� �����O?M��+�}u�����`������
,Y��7x�����9

"�����������Xs�^^^�����$&&��S�0e����X�L@�IPZZ���XR�a�L�6M�b.�J�2	�R��&�!���G�!v���c��e�iklp����m�������(,Y���������?������C����s'�R)<H?���������0<�A 
�����L��A��J�z�������Q@zz:a������G�tcl>$&&b����C�&�o�+��	���@-�V4���1o�<N�!�J�����P�VWTVVb��e�A����7�A���Is�T��I�m�f��L
(�---�o�>�AGG�/��$����Y���Gk��s�>>>:9����������J��I����J1�����E��IE�@�I&�o7�92������5��L��[�b��u��abcc1u�Tddd����x����5Z[[�����mmm{�o������������t���@��;w�h5e��K�R�L�T���>������(�N��9)�4	����w�^��5�eXYYi4)`l�����e\�t	�����#00p���N(&''c����A����7��9��������W����ur�y�T��I �J�6	RRR�����.X�swww���yWWW����1	�?N\1��X�����g��Z0������H\���e���!&
M�T��I0�#��N����s�� ��e>��S�]�

�#�<��+W���>���G��}�p��M�gKadd�������{{{DDD���HT���W��������	�����������H1�����u��^'0������Y)o��&��������(//'ggg��rN������}'w���g�}�7x���b���

"�������ddd����84��*���	������;�+kU|mm-222AD�(su|ZZ�\�B�������Q]]���LL�<�Xp�X�3331}�tb��b��J�j�y�����uFF���b1�����GS�����%��A �X������g��g���rbq�:�Y�/_�L�k�3'���XAgg'FGG������h���I`cc���,:����	����<����yE���OOO�\.Gdd$�+
���,���0c��5���}������4,^����Cbb"n��I?�PhllD{{;&O�� �6j�X��7og�6g������L���LXYY!$$��Me������ ���n�:�b�-[F�YYYptt��u��������@ZZ�������N�TW����e���Kpqq�_��
�t��VW0���+rrr0::J�����q#���WW0���
���.���������1F�
DBB�B!���Xy�������(++c�k����[())a�S�Z�������b��ohh@aa!+�p��5�H$���Caa!+��*�}}}���c�S���3V��������b�����W�����{������G��9�����O>I�5�X����3�XO���466r����b������zV�:�z��������QQQ���J� ����k�����/���Kpss#&	<<< �q��%VV9e�����������VV9%�����������2�������R���F�� ##�����������t�VRR�A���	�X�D�@�/�">>�6m��k�Xg��g�2^��AO�VVV���Dww7\\\X��x����Aoo/-ZD�fff(//G?�+���>�������:����@���k�+����2D"�����u����B�Pg]A�b�Xg]!������������K1X�|�R�1����P�UW�1�<x�x�����_b��������y����������3ywww|��w,� &&F��bM�����������:W1� ��u+�	�4�������knnn����q��5"�������:�����?�����H/�������U��N���7����B�,���$�N1���W�F��� .\����������y�p��-|��'����'�(|��x��W��*<[�l�������E��������u���5BBB����c��app����I���v���9C� ����;�666���Wq�����+lmm���@k]q����9�0�������T7��R�g���YWP�>�"33�SWPr�Q�s�Lw��+~OA^^N�:���z
���.\��y�0$��"!!k�����
��A�����<W�auu5bbb����+�4�X�i�*�+��s'AJJ
al��~~~(//�:���+F��+nt�+V�mmmq��
���shkk'''����XS�s@^�,s&�k�ybb�QAAA����_��|�����m���;��y���������L��3g����&M8p%%%X�v�
<��R����.5�?;����\\\044��n��ohh`����a����npwwW��0.]����9s���_���z��A��@ii������L@s�!�JY�B&������b@uGTT�^���k�+��.�"))��
���2<��3���Oq��1��������IIIHLL��O?M�.��1��
DBBbccm�QD\<�APXX�+V�!eQD���_�N,)��m���PZZ:�QD�FVWW#44��.088�c��a���H��+�P�$�%��9I��#���p��!�6�������n��,_�����QWW���l��
K�.��+p��a$&&b�����?\]]��#���e�D"�YjJ����:G

�����]c������Pq��$0]������~�0�����bB{{{�#CBBPPP����l>�d2���Aww7�~�i��\Qw��+��]"�������
,Y��h
���v��1����������z}}}x�����2�g��H$���;1{��1~�<x�o ����� ��"��{zz���H�N���)S�z��*�����s�a�L�6M�b�o�>[�)�������#G�;����l�2�����:�q�52��Mj��1&&&�:u*V�Z��k�b��������-���0i�$�BX[[��g�EYY���'N����'(�@(KM��8477�T*��$�'�0++������t� hmmEOO���Ccm>$&&b����C�1M/
��I�A&��b���1o�<N�!�J�����P�VWTVVb��eFk|��gx��G����3f@"� ++���'����?������O�0���2<==�>�������7��&:::�>�H�I������?����("j��>&�T*%L���V�Aff&-Z�qH��q�5��I�82�������O<a��6ptt�3�<�g�y�������������T��'����w���j����J�z�R�}}}���!���QL�:�sR�ic�a����5k� �����EFDD����e\�t	�����#00p���N(&''c���Fk=z[�l!���������q��)<x�%x������c���?~<2�HG_��J�z�R�To�@  %%�0������I1www�z�O�wuu�z�O������� ��z��3�G-�f���wtt$��������|�����&�T*��$���S�Na����/���X<���c�6x��qqq���GDD�}��daa��U$&?88��u.���������&R����n�:��	����{�nV���o�I�|~o&���=���	����r��Sw��+�G�A�	��;w��g�5Z����Sx����?Sf�<y����)B<x�x���}�va�����QQD�����������kkkYy����b&����+W�Amm->��c�����#f���k�W��#��~��XRH"�H��bM����������~~~,�������hnnFtt4�z�$���AVV��@A�P�S[���2W����u�2�����0c��0�r9������x��w���o��w���o���x��b��y�8;�9�xM�U<edff���
!!!4�h(����PUU�L�u���s�l�2�������#���� IDAT��}tEGG���t����t*���b��],����^"���A��`���
&?uENNFGG	����7n����
f�A[]��P�EW|���F����_EHHa�p���x�������Wxx������P333"�X�<bU�&y��x�<buy�L���������5k�h�W����Q�2>''G�<bU�b�0p��s�3c������O�bm���������|\�|���$������k�|�2.]�777b����b��.]be�S&�*^�,s�����)����
0��������D�+V��W_���[U~�������������V�����M�p��5���������lP�S&���*++���
���2�����j�8A����E��&���������O�
��������������"00���Z��={���H{{{��A��(,,�P(�YWP�X,�YW�D"�$�tEAA:;;�z�j�R�/_�Tw����&u��s8::�U�Va��)����6�h�"<���X�p�X�U<X�
��_~������3������#���>���,.�����+�i*Y^3���u]�{�[�)��r�4T$ED�AC��5Td�}a~�:����}Lf��y������������|��g:=V�����+���ERR����X�%q������N����.�\.�XK�TqII	���`jj�8`H��������e��>����:u
����X!�������GGG���0���q����dxzz2�)S�������gG�?~��V`aa�>��s���c��	�bN�'$$ ==�G���S����/p��y�����$N�������(,,���7"H�T76��A||<���K�666��w���Abb"JKK���I?����������p��	TTT0�
$q��\WW����}�6����i���CCCHLLDSS���sq<66V-Z�o����"TWW��>��SSSq��%zT�����255��#000���F;v��������D_;EU��!�� ����������8y�$:::���xCC����3���G?Q600���ZZZ�����}����R����Hn_������`" �>}:N�>-�7H�HLLT�WP���Ca_���,�WPrk��@����z�
u<==q��5�[�����v�}�����~�
6�����'�GX�n��
***
k�����#q��9�b<�#���Fnn.r���;::���
YYY���#kY���3�������X��������[����l�2��nnn���Ezz:c1@����1kY���7���p���b.+/))Ajj*c1����<==�v��???\�x�X���7����())AVV�T���O��Q}�����p��X�����D����>8�\��+W���,������8w�P5�������DQQ�]�F��c�fjj���BF 733������q������-,,�����/2��$���������`�����/\���� $&&�����z��wq�����+U�b���@_;�o�����)���JVVVb�,��o����9�z�*���O�;;;z�����;w� 44�����{����
�|�������OIIQ�W����	���QXXHl1�J��#  @)_!����\_q��a���^���q��1\�p������@^^���0�|$$$��X����@���L�<�X�]\\��X__...bki�+�XK��v���F���$�����9,,,DDD�XS��-��������XK�&&&5jn��)r������9UuD���N���/��[�nEMM
c11bF�	www\�zU*���c$�bka~��eF�oee����/3sQ����������������B�D
ZZZ���hkk���Vl �������N������[���"��8~��q�����x�b"WS������K��544�����������'&* �����yyyr_����I\�����N��������������������$6$P'_������0" ��u+=� �7H�FFFJ�
���qCa_1j�(����QPP@����?>�{.�;233������\_Q^^��u@����3f�u����pqq��e��y�fl���x������
TPT��������|�kQ���I��Z�2R4$���`���?~�\��p��!������AAA�!����e^�����"�kA~��%�kI\�&���'O�$� �����%K@dH0j�(�CQ\xd�i���_W�3�)  @j8@�
X���������v���+tm����S:$�. oH���hjj";;��������
	���Ctt4�����9�����������Oy�P^^��9LOO�/� �w\�re�>O(��+JJJ���PP����2e
-Z���L�6�80�+U��������yff&�ka.��O�����D�Iq\__�"���b���?���i�qqq�2e
�����S�D_wttT(���������8^PP@�uuu����l��3��4	�����
���k�+**�vA?���C���b�W�g�}�����ikk+ R\CCC�)#Q<''G�z���l�������1u�T���!�:>|���EHH# ����iR@�|EKK# �������E�e}��x������#G�: ������477����?+Vr�
TP_}�f��	WWW,�]]]
%��<==]�D_�������@744Dzz:���b���2/�\.W��?Angg'���2!Arr2|}}�����c�\��?�by��Dqb�@ww7# �|�2����I�����V4$��a����P����������~��]�����"55���Cpp�p<V��}��g��������������V$a>88(�vQ�zx���N����`��ub������~���b��������Bsss\�~�,,,`bb"�w(�+���e'��G����m@������O>��3g���K�jaV��Cl@����k\\\0i�$�kzzz�b���[[[8;;�\p���[[[���WWW�i
@.��xCC��=___XYY�\p1��y<��������
}�jkkq��L�8�8�Fp1?s��N�J�$�X���b��i��9s��������;W..���:u
/���3=~�8qH!XZZ2�����������_�/^$���q�����%%%��G�p�&������pwwg������Eee%�wL�&&&(((@]]&O�Ls�@����������g�}���F_���A?�sH����'����!((H����^��;���;6l���{�b��l8��/���H��������v�sm�e�6H�Tp��yhii������!�8������*��yo��6�?j/^L�999te�����������HKKS�W���!55U._��~F@�b�
������
�|�0��W�'�+������A:::x��wE�e}���E|������b��}j}H��C��h�"��o���������%kf�j��*����fff�o|�?c�������D_���.^�������0}I�����������#`cc�H�����6\�p�Qs�z�jxxx`��������������#���`jj
kkkF�?44�3g�H�III����� %%E*���'�������HLL�����k###L�5j������������*����������������=#���������������e$��8u�������:�������������o���EEE�r��$���-�\.����p�>d*�����`cc���j������0�J�(++CMM
���O�,--����8L�8Q����~DFF"22�������_Y���������V��C�k�8.��A�Bsss\�v
���t(!+���Cvv61A����y���!���1������J�
���2����:::
�
WWWhii��+�����������i�"##&&&
�
����*�+�������7o�D}}=V�^
���������+�	EE}������"  aaaR�788o���S�T�X�&6 PA�����OGAA����{{{���<s�O���������D��I�������������t��@i���d��-���p��e�x<���0�������T�cc����322���}�&&&x��gd�III"�L�0)))���p@�������&L`�����#%%E�)�����,--�������c�85	�������{%q---������			�{�.Qs�����k����<Od{�����1RRRPYY��N ������Xy<���`i������HIIAss3c$X���Q����~|��7HLLd�V�3��c�l�{{{��!|��2�i�i\OOnnn�������@���Gzz:��������@kk+x<�����J�
�}EVV�����`���8{��X� �W\�|III
�
���N ����x"}5E�f�d��8����P��`������/���
ooo�k���;��`V*%6 PAEEEa��59r�_��X���� 66��bPVV�e������W,k�8.k�$.���������D@�k�.�������r�s�*"@��b�S�������!z{{q��9" �j


�V����3d��v�sE������" 8u���[G|�����ibbbK�>===F%"+V�$�����A�������CM��������9 ���u�Qsx��U��?��
vvvb�$��W��s���D@�o�>��wO�o��+���P]]����xJJ���������_Q^^���Bb�P�J�
a.���������u@���$&&b��
���Ann.������F�<�k��a��M���Y���*���(DDD`���j_E$����0j�6��"�$|�Pgg'�������/����[QSS3�UD��2Lqb��������B'�����C�Iy+�'	�v����+�?���c�����_7n�/_��������������
X�������Re5����������pssCcc## ���������C�Iu����#��[����O��	�����8�����7��F������D@������������C���<
>|P��Px�@^_Q^^��m@����;w�Dee%z{{QYY�+W�����x���o000�����#�bE�
TPT������W���� 55���W�S�%����

")|��w8�UD��2Lq�����F�<y�8����K�,��8�v�F��p�aEEcd�i���_G``��qqqX�j��1������APP^{�5��.'''��������X=Q���)q��2�8w���!AGG���yyyx��455�����b���)��P]>DGGc��9��CKK�am/066�S>���3j�����/��W�\�����������9������!�����;�����b��|�M,\�III��a�pdV�h��
�
�\��W�����8t����^�����qqq�2e
�����s��������8�p8((( B���:F�Avv6���#�����H��CQ#����#�����
�|@p������Rp8<��3b�g����aY�X��>��3,^��>A�:�T��C;;;hhh(Uq�������+���������6TUU��� �N�*��P]>���"$$������*�������jkkq��u��CY_�$>(;�x���
���p����}���#..�=���J�
TP_}�f��	WWWd�"�� OOO�;��iiirm'�


���N���;v���9���{�O�����=��LH���___F@`ee�t_�2c�)�������v���nF@p��etuu��!u��hH0�#�<���*>|Xb@PTT��MX��=�x��?�#�b����g�AWW~~~Ol+����B[��������	Dq��A{{;�b����u����N��~��'F��?�����W	���q��u" �������H����x��P��������+|||�3��i��1���
��+��*�]�v����&M��FU��G,����J�#��}����ba���PWWGUUU����d�+�:u�\}��|��9r���W,�G��')�KKK���e�#�e�#�������BTVV�������BWW����6m�~*$011AAA�����r�@���W��\����(�e��r��� �v���U�V��	*??b���z����������+22���hii!��\DqY�
�8�?ZZZ�����`H �;99���
7o���o�
�������!@NN����j]��wuu)�+���������hkkCjj�\�b�����`��DE��o��+����B�?I_���


" �������+�w(�+>(�+'����S�C
MMMe
��?������X�z�b�w�}333}���K���K���������6\�p�Qs�z�j�����#E�����d�#�������a���\T�p�add$���i�6�}�����q�&���uuu���GEE�������F]]�����r�I[[[p�\��}��UN���2]����P��\WWqqq�8q��7nDdd$"##��g�1^g��Err2�o��`��m�_|===��/+V����H��?�Akk+��!��A��� �S!���9�]����z:������!;;�� �����y��������hmm%|��A_����}���+�������������FFFb}�4_����}�mmm����D�A���7o������E�,^�X��n_AM(*�+���P-\�������X
���@�{�nL�>O��X�>bI\T���banaa��2�e����W,k�8.k�$���$r;��>b�����?GCC&L� s�*��o����`mm�����{��9lll���kamm
�'����������*�N �+�e����T�yLL�Z�DFF=z$�544���!�lpp����R���[�l���=}�>�T�k��k�4���777��������N ����#==�qH����{xx���<���
}}}�|������"++���D@0s�L�={V�o��+._����$�}�Em'��W�x<����"Y�f
��P����W�{@������<����}]�z��Grr2^�uFe6+V�%6 PAEEE��7����233���"Ytpp���q��Y<|���g,�������������b�K�nnn���@rr2

aooO��I�---���%���y��===q��=�<y����p8D_��Q�PWW�������vvv����������������������+**p���������������YYYD@��W_��g��������KL"hii�c�'N����EEGG�������p��i�=Z"���#��
������dggc��Qrq###���#''���C###��������ljj
+++����D� 9r$LMM������r"D��[YY��������.�GGG�E@������mCDD,X������
��q�PXX���FT����#}��y����a.2�_;(���B[[999�A�u������+#|�����K����Z�����?����.��A��������w�?r�����������a����r[������3f�R�B���+��"�"..N��M�6a���8y���WRR��?�������0jV��
TPQQQX�l<�J�����������dffb``@�D�85������4�b-�Sc�]]]HMM�����K�---�����DDD����v���d�bnhhOOO455�cu�����{ IDAT4N�S���b-�����[�p��Q�bnllL���^���gl���6+����#`jj
TUUI�g��!c


���������HKK��srr����r��q�rss�r�*���$''c�����@SS������Aii).]���D������#Q\\���R����vccc�������%$$�E@������8�7N���i�p���f�+UXXX�������
��I7����������q��="$�=<<����


`bbB�����B�������������`��-������L_Aq*dP�Wxyy�����+���QPP@�S"�;��'O�$>��+Dqy}Euu�ZR�����������;w.BCC�WHH<==������P������'���X��bUs���J,����"�9�Pl1wvv�)��;;;������S]��
	�CI!��s�0u�T" X�ne^���7n(�XS���T��Z�hhh���'�3����d��=Z�@5j��F�I�7o���I�T> 8~�8^�u��;�G]Y�RuQ���)}�P�� ��Ds�����!AWW������C������b��Bu|����g3j�=������5��O�����E�����a����FL(��+�\���5����1y�d���s�a���X�v-Z[[���C�Gf�������������g�^������\��0�S$$044����������o�~����
	���1y�dF�����\��(����p�onn�#s�/��uuu������=��4	JJJ���eeeJ=
���`�K������!$$D�]]]��;�kVD���c�t�Rm��
/��"]#F��lH����pE�`s�,��xff&���������� f��)rR@8$P��111		azzz2�u�mmm������.]�;����������V��@GG����=#F�����q��aL�8�=�����
TP_}�BCC���
�������
%��\��?y���d����������"���Z<���2/�r��	r{{{����		RRR0z�hF@`ee%���0�c����5�]��������q@���@�����S�����#���+���������'��jN�w+�0����y;�(���������v�����k�� z;��?|����-������W	,,,p��
" 9r$E�e}��x�����?���[%�����@oo/Q#���p�
TP�v����#�L�BMWW�^��Sz� kI������puu����b-�wvv���S���#�xsi<!!���D@PUU���7���
'O���I��Spr1?y�$BBB�������c��yXX�/�X=z,��.����/�L�L�;FRH�����:11��g,�.�eee8{�,�/QN-�������1{�l�8u�_RR���Rx{{3���6������3f���O�����r�
���Ds�@766��&M�DsA�/��;w===?~<�������G�����W�����EEFF���
�����C�k�(.��A�nzsss������'wpp����q��u������9\�hdee��������>(�+���������Cbb�\�b�������W_���-�~a� �W����
a�$}EBBttt��@[[����;���������b��}j}H�<����������R��
������������p��#'''������shmm��a$�����,--������^p8F�/����b�����x���-��X���Gvv6��p��Upww���N�8���Z����p��!�oX8�711��#G$��UG�����1<(�;::��N```����NNN4�9��c������������ZZZ���������d��b����G�!>>NNN�D_������N�:F�/�S7����hkk��3gPSS��{�=�������t�7�~kkk8;;���������cR@������n�����"����]������\.���p��5���3�������G�������+Sdd$�n����n��C�k�8.��A�����Aii)�����r�����.z{{���COP��y�����������#|��A_A�%��
�����+bbb�����i����066V�WP���*�+lll��p��]�W��{555��������+���P
���6l�|@L�X
���@�{�n��=���a�2L������������������$%%ASS����b-�����>%����1(�������f��-���!���QQQ���XYY1�����q��u�UC���������\��_~�E������L���C���g��x�"�=Js����/�@MM
&N������F^^���D�����b��������=`H����\�c�����&���`ee����o5����x��7`ee���l2�lll`jj����������$qmmm�x����	����'iii"G�%����o1`��Q;v���GGG�����#��A�vm��;::b``�O���@���Czz:qAss3�DWWW��������{��BOOO)_���/�����Epp0,Z��N�������
=zTa_Aqwww�}�/��___�����G^^V�^
��9�;�����?/��2>��S���[���~���s��+��Gf��������f�p8�{�����(wpp�7P������n�{�������[n�������...b��������pI{�d����8� ++�v�����'#--��7���)vo�(.XE<6�������`�
�O�5q{e�������CNNP5����b+��f���B���p333���e�#G��oX���fV�TPT����=}�>����!x�)��������������$�[�n1j��W�������+����Z������{q��}��A��pqqAcc��������
����:>|��+���QXXHl1�J��c��1J�
a.��������8���=��W��������������_���;v,�{�=|�����+V�-6 PAEEEa��e��UD�xKK�����js���*"J��������8�`��m�w���W)s�0�}}}��{zz������� Q����V
���8tssCBB�b����@UU8������
W��whjjb011�Zq(<I�.�"##���'�-[����wX+===q��]�}���jjj����D@p��=b����HLLT�W?|P��P���������. 00iiiX�n�����7�|��/���>���TNl@���j]]]���H���d<���j}�������s�:u*�[�����^E��)�/(( n�p��I����j,Y������K=z������5j�R���7o���I����+�����*Sqhll���<�*�������p��������---���A{{;����V��������=�Qshaa1����������rF�����1}�t�����|�>O(��+�\���5����puu����pV����������}�(nhh���Aii)n����UD�B���xL�<��b���6�UDG��C.����bb�����b������g��8,--EII����F�		G��5�eee		aV�TL��m��/�H��Oj�lH����T����rrr�8���Fff&���������� f��)��P]>��� $$������*����������q��%�����}�>(;�x��a�&N�����Vl@������J�		V)�����T�}A���,�vQ\__YYYD@P[[���^�����A��?AN<�� %%�G�fVVVJ�?��?Q�����.����������LL�EEEro'��=2|��)����+V*����CCC���Ol+����B[��������	Dq>����������;��AOO�j -$P��?����������~�j!���n��A#G�����H����x��P����z���_~��?���/�������}�6�������7X�z�b��]�����)S��_���d�#��e�#��;;;}����ba������F" �������e�+		���X������G,O_�p1;v�8��
,--��+���X��G,�S7�%%%(--���7# hkk���JKK1c���TH`nn�+W������*$qE����s��2������G�����+V*���H��������v�sm�e�6H��Monn.�|>������}�6�_����~�5��-�C���,����~���e|�������}}}HLL��W���������A��7H���<�B�?I_���" �������E�e}���E}5������o�ZR����c�������������x8u��?�W^y�8����)6 PA}��w033Cww7�W,k�$.K�$.��XZ_�0���Gvv6��p��U2�:tH�>bq���2�K����"���#�9��c������@�����|�
���3���a������p��Y888�fLSS���pvvF}}=���
$qe��)��r�2?r�&N���X��"##�u�Vtww3��^�qY�
����=8JKKQUU.����uuu������zb�
���G����(,,D]]�+����
j-Q�W������\._����``` �7H�'N���������\.Wa_acc�C��R����������5k��b�p�B��C�}����������tuu�����n�����M����QRR��7����O��������f�
��v�����g��������G,���#��W,�MLL���?3�e����W,k�8.k�$~��!�o��>b����/�@MM
&N�(s�*��o����`ee����o5����x��7`ee���l2�lll`jjJw�{yy!�$�l�����R]�111l�+V*�;v���?���#}������� �K�6��100���O��N ����!==�8�����~����ggg������=q_�����������W���"88�-Z�S�N��
�|EEE�=������������_~���/�W���#//�W�@����z�
u���PTT�?��W���]�p��!�������'O��_~A||<\\\����9s�����/�.]JL��b���*���(�Y��/�W,�[ZZKl1�y�&"""��K�+���X���Xw���YYYD@�k�.L�<iiir�s�*"@��b�S�������!������CT�������C�����������e.��2���fV�TPT����=}�>����!x�)��������������$�[�n1j��W�������+����Z������{q��}��A��pqqAcc��������
����:>|��+���QXXHl1�J��c��1J�
a.��������8�<<<0{�l��q����p8hjj����No���������{�n���#F������pss�?��Q��
***
��-�����'������`$����HMME__��'�8��

!))	|>�����_700���>|����C__����X�8�����9���GDD#���>���`aa�������111�����e$�����F����V8p�p8D�/�������	���C@@�������>���?q��;������h�P�>5V(��������9r$���QSS�c��I��N����������>`Q���'&	z{{������� j�������233	�@m����7�'
$q��0KKK����D� ����������/^Dyy9�i�(~��	6 `�JE�����@�k�0�y��L�I����1I`hh���������]"���Bss3# (((���.\]]�	}� W'_A�_[�l��1c$��?�WP���Ea_1z�h4662|Eyy9


�����	��������8x��R�"::c��Q�W�����;w���!�{�����.rss���k���?��O888`������������?�������������c���������Cp�\���!++���"O!���BZZc��������;��� kQ����^��3
����X�����NF@���b�����������X����������^:t��XK���bWW<�X��q�l�����~`������&��k�"00MMM���e,�����������cj�wvv���w%���*�x<�bmff���H��7�


8y�$qAUU�,Y�q�0r�Hp8���#;;���D��]����(((`����G+\�(��}����(,,{�� �����I����+�����sss��
�<??_�k�$~��"��3"//w����[ZZ�������]]]hkk#B*��|E[[��A_!����\V_�Y�f1j������?�WP�%��A�������Qs������`�����^)_��������WP\p�Q^_QPP��K��m@����"**���������cOO�FGG������#���}���`���O�s�bZ�������p��Q\�x��QSS{��Ezz:�������~---�xNNF�M�R��/���������&��������-[� 99Y*�����G�h������Al���&M���;1Vx��}hkk����������u�b�O����O�9s&�Ji|hh:::X�d	���.�K�<������#tvv�_@tt4���144���,[�s������}|>_&�����_~�f�"N����|>����|�r����X��������*BBB`ii�;w������_�p~�!1�888������+D�R�'���R��U�0y�d�����
sQQ�T��s��0b��={����+++���
V�X��Q[[K�h����m�����w/��]K�����'��!�;����c�����r�������#�����+�k�������� �������|>��3s8���!11�l�2��kdd����o�_|�E��hll��3g���@*�����LLL�� ,,L"��S���a������8���3	.��7J���t��?���i_#��9���
��Uu0e��wH����X�r%������	&��A����#��?���;w��s:::�<  �����^�u����ol�������s8�����O>��|�	|khh���+W���?�,���g��y3<==<�����b�
���H����b�� ]]]��JKK����������I)���V�b�45�/���v����7^CCC������&�|>�|>�4S77ZZZ���x�����1b��������G����������oa``@�����7_���������!��K��!444hN����555���EpMMM

����X�~=m&���������E�
q����?��H���_�S�{�r��M�0�^�111��������������E�������{�xoo/>��Sl��Y���X��Sehh�e�����>"{���\����x!�,���8v�lmm�@V������xzz!�8?w��D����={������~�:��w���_|���,$&&b���DH===�����c�0m�4"���n���!))I*�5k�����d���`��y�K/�D�������D���"""��������O0k�,���


�����v���/8s��x�
"����"�� IDAT�����CHOO����O������������d���{����Dvv6������D���������vvv���f�T���\�|�d�555����Q^^N��c?q��-�|������#B�q�_UU�������$*��I����M�6_/**��M����	�6m���q��
��>��S�������������������x�
~ff&��������c���;�������>����������_�t��������������?���W�>����q�oaaA���~��N|�������q#�������������7��������r��s��?��c~mm-hhH!�u�V~SS���|���S	�`����innn�_�~=��������n���������


�Y�f����k~KK������?o�<��={����r���b~PP�������_�_�b���������3���y��������������������x~gg�����c�W_}���I~ww��<88������~V�X
��������������������[���c�������YYY�7�x�%7�����>}��j�*b���www��m��������}�v�[o�E���$��+�����c���#""��O�f���.��K/��?�<�wvv�:$�/\��_\\�������~���'N�H|�+W�0�������o��y���J�ykk+��o����5���� 7�w���/����1C�z"�777�?��3�����AAA��7m�����h>u�T�{����w�����'��s��������?���t�R����7��6m�����>00 ��5������������oii�3f��U�7�|������������?�3���|###~}}=����������=����\�*�]�v���o��&�S�����={����K�,���/�xK����;���p8,Y���@������;����������H�e���oGuu56l���9,++�����E�����8e����O��������>��S��9S"_�h�����PZZ����X�t�T�p�BF{Aqq16l��5k�`��4�9���/�u�Vx{{��Daa!�m����Wc��9��>Y���������(�Z�
�f�"��I�}}}���Bll,^{�5��1����{zzp��$%%a���(,,$� ������6����r�J����HNNFNNV�X����������������b�����4i��J~������X�|9&L�@�0~��==zT,?p��3X�R1EFFb��x��!RRR���L?	��pwwGmm-�������8s@��pss��stt��-�p�777\�z���pttd�9 �������999X�v-��[�:;;1o�<��WWW\�x���ppp *�������������q��4����S�N��������������������2�pvv&xLL�M�F�A088===p8�wPg899�������8ndd��8s���	�w�����T���@���GGG|���������DnooO��Rg
tvv�����z@�,X����ptt��-[���FOQPg
xyy���;w����+=�"755����{�n���2�����������...D��$��5��2e
bbb����+W������mCkk+v����{����^�G}�U�V����o��k�����pL�:u����G�!�[X=m


a��1���g�{��E}}=�N��8+@���N�������H�_~�%=z����3�����������oUVV�;v@WW���pvvf��={6��o��l�sss����/|�������A&.*��q#�������N��488�K�.a��-���������$N��������Chh��p@�n����CBBD��xOO�����c�b��q�?scc#��N�J�===HNN��'��3�0���I���HKK��	��������a��Ix��gE��x[[����+�����O����.|����������|||0m�4���c���rq}}}���c��������P__/3700���c��s��������ESS��\__�X�g���g�����������x����������DZZN�8���v��s�=�	&���HIIAWW�MLL���S�b���������g���Ks333���@�����������>}:��'����/^��X��

E@@�L�����2<>s`��9������~*����.+++<���"}����0z�hl���x��#`gg�y�����������(�p


�������O>���7e�ZZZpvv���3����������Bf���2e
�����������{7n���[������:|���x��0k�,��1���pvvflM`��i�� PA}��wX�j��������a��=������K���G�<S��4���#DDD�����T8@"����+��BWQ�n�������3g"99�h1���_q��Up8�X���������?��n�=<<��k����F"���y�?n�8�^����rq*

�o�A����D����+aiiI��o��
���X�r%�~i�������1}�t,_��8G�n�������P���KD0%?s��=���g#<<���HLL$&222�T\0������$��;s��!8�x<�<33aaa�1clQ7����R��/���� ���G8����"<<\,?�<BCC�	V�TLT����=���q��uF�!������Bd{�(>j�(��x|�(��@nee%��@�u������aaa������h/l7;;;���p����vY������a^WW��3g{����#D������������l'www���|����v����{�H����t��b�����/��#�~0n�8�!������Y������Y������q����j=A@IGG���5j��YX��O��+����b�����+VO[l@����{7�,YB��_WW����K�.�3�<#rr�
$����#  @���8��W�X��T8 ����#66�Qs8q�D�X�"'�p����X��o�]\\DN���7�\.Wb8 ���Q�{��a��\������Q���������W^yE���$���I��/]�T���4~��!��=/��"���PWW�jkk�e���@ZZ�=���0�������I|���5k���*��g��)rr�
�O�.�wvv"((�
X�R1Q���#�z���/+UqX\\���2�*+**����p����w������fF@p��%���I�8��Rq888���Oc���D@��'�`����Zq������N�+===EV'S�S���&������������JU���b��1JU
ry+y<������p�dQ__���annN���p�
TPQQQx����r�p���J�K�.��q�"""����T8������DGGAQQ�m�&S8 ��!��q#1i�$F@PUU�T8p��%���S�p //���S*��?���K�D���X�|9�~�p��<P4�;w.����T80k�,�i�<�@xx8���1q�D6 `�J�D������������e
$���|�BI���;RCI���������%���.tuu1BQ!����\!�*�111�5kl��	���RC�?;$�%��'��������D@������`b��
	���e
$�c�����CI!AAA�.]�?<��3�"�X����C���':.�K�/��&O��T8 ��
��"����6n�����444<���8����%���� ������^���mmm�g����_�p`��m�9s�����_���g+���"""���������Q]]
���o����������`��sE�A.o80}�t��?o��6^|�E�b�Ju������G����!tww���{�����!�7YxWW������������f��������;::���"�S�OCCw�����[8u�,,,���###X[[���� ��711��������
���055����������A������
#G�����\���G4������9���W|���X�j��7�S�L�?��G�������v�������X�e�MMMhoo���=LMM��_@cc#:::���D�/����ttt������@YY���_Fjj*444����]���Gcc#���������(ohh�������LlEW�666J�<����������MMM����K���3
��J�����Oe"��V0���	��+h$(`�&q	���%���h�&2�0	
��`�����
�����P\y�^�S]u���K�������C��N�Ir��7�<��s��w���	@�:w����j�7Z^^��z����Z�����w����HE��:��*C���;����|}}M"`������?U8p��y����o�
�O����III!+		��������x�
���H2�p@��B***��]�v���/k|)����z&����{�.�������$�^�������;���C������+:���&�}�6<~�X��k�����
Imjjsss����-hjjR��`��O�Buu5<{�,--���Bc��O�<��7o���XYY�'�K��?���*���X[[�����o�����������7���^kkk������S�=z���ZyEEt��z��666�����?�����G���[[[5oll�k��A����r333���'����{���S�g��_������>���r������Sc�@CC\�~^y�����(gNz<�,���p��
077kkk�8h��u������
z�����=���l�2X�z5xyy��S���,X������`�wNE��}�����������___�t`�����@�v ����Bkk+q&�����C�N��_��p��G�0�����Gb8�j�*�/�R���K������_*
`��a�������x_���������#$q��x�x���0r�H^8@�����������G���R��+W��������+W`���0n�8^8p����� <<���_
/**���CDD���~��18u������/�b���JYz��� ##*++���>���p?~<�����lHKK\�����!++Kpm�_�5���Add$2��[]!~��������s���0q�DHII�x��-[�����b���PUU%���G}��JF�
b|��y@�u��������{��}�BXXL�6�����`���Z����}����%�w�}����c����={6�7����z�j�k{{{����u��������7��x��!DDD��)S��B������3`��D_!��\�			0k�,A���}�����1� �����������'��[c��p��m�����~^**)��������0g�����O|�����sg�={6899�Nh������������J�{r@/++���Tpss�!C����=���_�v-oce��o�AJJ
A`` ������)))���`cc�;9��_����z|}}�{�����}��$@<9���������C���o�N�:u
RRR`�������ojj�'N��; !!����6���c���������wr@��!>|�=
�'O��7j|��������G���y�����wr ''N�>
���>����wr@��>���Op��%�����}��N�qf:�{����8|��]����B'&����@EE�z��um����1^SS{�����x����w�����w�455i|^�q��7oBFF b�����JHMM��W�����m�t�$������#}���

���`�}���+|}}��b��
���\�w��0%&&���;k�s���,\�P=oK������?"��"K�2�Z[[������x����[���������^#^+��7o����0t�P����Z�6���---
����kb������}�����^z	��k/���5
lmm��
���E��1c�G��k�������7n����}���(sm`�����o_u��T�\HJJ����������
�8sm 99���a����kB��6������0`��g���Q��� ���������{�����
���{���������������|����A��h��#�TTT�Pkk+<x��vH]����A������4���_���<==y��6~��M�����������A�eee��7o���+�n�*�Wl��Yo_����C��1_1|�pY���r|E�=4>�+����|��}ESS�,_a,#�^y�x��w���E���# 88X�_���_o����J��@�����z2/#fgf
���[�sgq��3�	<w��gf
p��qgh����������1s�{<�;��=m�?s@�s�x��]9w�W��pg
L�6M'��)0e��8w�w����)0n�8�����"r&\`f
>\�sgqf�@PP�����#""���W�sg�G�?7�a��0t�P�����@�R�m<--
���`���0p�@
����W_}����/�����H���?���>��+@/_��7�\� �+�\W_��/�W�1��yo��-�;���g������+�>}�����!C������?�b��6�i��tR)N*�
���_��K�,���x,**��O�j����r�7o�$~��Yljj���/_�w�y,X �KJJ���Y������o��K�,��/\����wW���Ttrr������+W���E��/^���HA~��Y;v,�Z�
+++���g:�3g�`hh(�[�kjj���U'^XX�~~~�a����E�
��������Y[[cii)�����c�0((�l�������{����l��������O�>�������G��_�������Q�;v`CC""�<y{����s7n���`5g����;v����p��{7>x�@�������W_��I�DyVV>|�P���{�l������xcc����������i�0;;[+8p ����������;cII��3]���6h�qqqx��a|����q��\�R���57m��j�f��:u*.Y�g�����������3�b��Y�}EQQ�,_q��Y�}���'<xP�4�G1�`l�"33����/��={
������c�|���
KKK����}6����'x��e������4C�8TT�DO(\������uuu���)��k�`��M���*���6����>LoccS�N��I�:u�o��&888h���bX�b�����s����>�6m�n����_`���0|�p�6mXYYi��EEE����&M�i���~��p��f�


`���	111���={&�'%%Add$���Gg������#�|��m��o��	4��>z�rrr$���(;v,�7(l���S�?x�~��G������(1b������:��w/<x&O�,�������������UMLO���a��)���a�TT�T�v�4������ym q�k�6
���OMM���JQ}���}���R����������8�����@9����]���������G��o0v_����E�w����W0\���V'*Q������:u������3g=����	_�	v����/;��r]~.����KJJx'F�a�	?Wl>f��	����	PP�A~�sO>|��7n��o����5����#]N�����rr��!!!��eff���_G���rN0\����{r��O�<����N����� qc��z�"� 0����g���g��!�
�	���x���r}��-[d�
��W���(�A]]:88`qq��*�&z�@�����H����d'�l�O���|�z� IDAT��`s������Q%��������BDHLL4����������S��'�'t=9����`s]Op9�2��O�99�p}O0�[����Y��������<?5!��@qq�,_�p9�b��������g��5�l�!�W�����\�����@*Y[�l��}�����za��Bu��a��>qHKK����&-����@�N�����q�F���q������~�5k����qX�|��&-�/X�@������rm�������755��#x�4���<K�,!n�$����w�2�w�&qn���7��/� n�RxYYdgg'.3��o���p��9��?���~��I���#|)���#p��Y�/�b���J�b���
\��� ���'�v�1�������7����d|��o��
Z}���X�f�,_����
��|��'Ox��b�����u�\.�W(Y0f�C�TT/V�>�@����=��7/_�L<�����_|�W�^%���/_���������
+**�������R�;w.n������������������g����������������������qqq��~���!�����999x��]���I�&I�B�
���yyy<<<\�����%�8qB��---�����&M���|��?m��������111x��	��?m�������������"��?m���w����g������7�0::Z���9C�V����			�����h�w���m�������������b|�����'�`qq1�h�6H�PQ)Pfff��������A���q��_������o��h�;w���}��_�Y��}�]�������U�p��
m�+���e����/��+|||xW�����A�W���[��`�_q��]����������_�l����p�B5'�D�����Fq�`����_~�%����_�����v��-,,0,,w��e����J7�
"��@�R��=x��������x�OOJJ�v��APP�����i����`ffAAA�^^������"*d������={�$d���5�x_�>}$�n����
4H�V0t�P,��}{���e��AHH�������}������<x0���g��%''CHH4�x�O�3����[��TWW���x����YYY�k�xFF9r���������b����}��%
��kkky������jmm�����vH]����Ag�
\�t	����O�>�kB������������\+������`�������+6m�$�W0���l������������|E�n�4>�+�����I��0��hjj��+�sU�"����_�
���p��5���;���@ee%���@dd�~J**�D�O����K���3w����58�n�g�����ip��@!��
�����������y����Q�n ��5�� ��9�n��O��
��sgp����{��{�/::Z'���7i�$�8������u���#G�$~���*"g���`�H��I���������)S���A�48�����1�sSQQV��������
$.um���3���58w��'''���y���3�w�.�W0\__aff�������\�5�7��
.��Wp���!!!��{��-A�!�W<{�L����$��+��T(E�f%t��&N�S�L�zq��m��QQ�-(P�����(���!��H��666��\^^��`!}��>���T^�|������r1	���C���l����8{`�>	�4tL��***��}���B����wO�0S��2������`��a��.766jHh��MMM���$T� d�� ����J�PNJJ��+y����gO������?�����&(\����8��\�N�Lb�v �9(a�l��M4x�I
�QQQ�C�t�H����2��];����+Ir���������e����}���}���RI�@LL�l_���.�W���Wg_q��=�gfdj��P����"�;��
%�$�`��=�:t� x-�=�H�4i�7���2�M\g�G�&�����C�x�������_���cbbdm�111������G�x5�����C9���#d�r���[��gLEE�,q�$�	�|�M�U�r����h��������>gSS��p�X+�������s���i�2[��������-I����k�
~v%���+��O?����_�~���������]�7o�l���J7vF"I*�
��\�d	��5����S��������XTTD�*��_�|�y�\�`�={�8UX/--�7�|�,Y�%%%���B���������-�.^������|�r�r�
o����gq����j�*���$N����9�����n�:���b���7l� �f���+++����-[��
;v���$q�T���l���QN�*�o�>=z4~���:���\�r%�����m���|�M5��c�����;�m_}�N�4	w��Ml3������[�l���h���"N$��kjjp���8m�4���&N$'����b@E�@�������5�}�.��6H�7n���+Wb\\>|��f@��F��[�f
N�8���_�n2������bp��q��A�W\�xQ��`�_J�����-���C�� ���+Hm��
ci1�������?
��������&�WL����Z?�X_�.}�$�K�������I���	F��W1���G��������2����
OYY|������]���R��]�\.�����J�b���
\��� ���'�v�����V�n�x�a���&�+�o�
6h�
b�b��5�|���+N�
bC���C���r]}���TTT�����	��k���;;;^��W_}�>~�������i�eee�����������gO��?m���~��?�!((�w��;�'��-[F�C������a������������7n��3g��A�����w�����(_�d	xzz����x_bb�$>p�@���U�V��
���^<��?�	"""x���?�6m�O?�^{�5�xSS;v���X�v-������i��=�C�Aff&����>}����i�<���l8z�(�����f��������==zV�\	*�J#�����������
�18;;��h�������L�z�*|��G����;,����;�����K�����h���/��W*������{�Bee�z��um����1~��M��s'�����E�����w�@�}�6oh{�������4���S���k��������(++�M�6��+H7n6L�7����'B@@������kR}���'�W�^�^~�e����;��W�:v������GL�7n����'��OGE��h@�@!"0T*��s��?��XW��������>bg�2}�l��j�VVV���}7p��!`ii��s7��@)�����@}8{�@`` �����}{��o�����k�y1�������������8{�@LL��
������[���������:u*xxxhp��!����
��7,�O�>
3f������
���Z�g���2�Z[[����w�y��vH]����Ag���_��8(�+++a�������3f�����
e}}��M��C�z����$����^��-???�����3]}���+��E�
777�r�
�3k�����$}|"�>����
~~~z���������)z�@������z��x�����K�#���������<<<���u�+�����u�#�����G����{�Hn_��>b!.��X���9��9�����	�ml��
H\�.s6���<==�N!��R����[;tYH\��������kp�@BONN������r�	n��������
�BYW_������k�o�\������+BBBx����[��C���V(��+�-I��
�+JP���y��>�����i��^�h@�@�o�^c��n���:�����mllx����\����N�r]�
�m3�|�2�3�>U��u�*���L��6��C[[[g�<��V��U�r&�k�6MEEe8�o����xW��V��tB�R�
�x]]6�w*�����V �f`h_�O�2�J��V`l-I�}���C��C	�III�|Ecc#�3+Mfff����������/����z�2��D*�T*""��k�0!!���C��[VV����.&$$H�BS�/^�uj0���
��%%%��{w��IMME�~���T�����D~��i:t(�_�o����
,����7m�����C��xAAzxx`rr2o?�{yyi�X[[cii)������7���������H���������������������������������}�4���'�w����7n����������_��G��}���&v����_|����?����k�;w�`RRFEEaNN�����W�^�S�N�#G��&~sypp0m1��R��F������K]����^@ee%.]����D��S�0''��b����s���S�N�|�W����B��@���r)������b�L��
��+233q��!�?�x�b>|�����+���e�
�������o1��2U��@�bS��I��9�$6q!>v�X^@�c�El�r�?t�:::�_�k������\�G�O�<�5�TT
; `���@TT��p���#�����ljj"�����l8�������������e����B�� �������r}Ejj��p��u�...4 ��2�h@�@�T*��o�Il�$^RR�����������~��B�8#nx�XZZ����"6������e����N���b8��4 ��R�����v�
rrrd�\�k8�pR@0i�$�
�/_�����e�g���:T�����%����L���W�^�x1.\�P���}�\_��t8�������4 ��2�h@�@�T*�={6�����Mq�������7i)|����p�B�&-�O�6
?��#�&.�KJJ�k������`��	�j�*�&��8l�0���O��������}�q�����DDWWW
�
^y����Ox�0"bCC��o���7o���q���KKKq��!�M\
/**BoootrrR?cEEEF��>;v,����o�>|����_
OKK���h����i@@E�L1{��gmh�����-[p���p@'o��6�����&�+|||x��1c��1_1a�Y���r|�g�}F����8`��kR@��l�����D���������y�������:���R|��w1==kjj�	�6~��E�6m������CL����Q����J���={������x��=b�����>1�?~�(?y�$���!W���8|�pI\��@`` �;wN�s+++<}���{[ZZ���C8b��p�1����<y�?��#FDD`qq11���q���8e�,--%&��x}}=����[o���v��� ���V�K�.Ol��
����eee�����;wp��M�����W�����~�)._�+**�����h@@E�@������k�l�[�xee%�X�����xr@��c����_�Y��}�]��k����%Kp���m�+�������R�}) ������|��d�
�s��� ������/���!��h���TT�m1P�������Fc���+W ))	��kAAA��G�ybb"���+���������+����������8X����[c�/#f*���������qj���xyy�������3g����!00P�{zzjL�x>5x��y0v�XI�;U����0g����777�i����������38z�(,Y�&O�������-��>}
999�n�:�����}�j���8SU�u�Vx������Ec��ohh�}�����;!""���{��
5���7��p��;v,8;;kL����(OOO���=z48::��/���w����/\�#F�{{{����n����T����{��LEEex��������k���A�KY����*HNN���*[[[��1^QQ{��������M�6ACC:��+***d����$Y�"11Qo_�����V� �+|||d�
������r�W}�6�ah_���SY�B��i**�?@(�rrr����g��]�u7����
d�>3�<77�7�p��a:���n ��j�������D�������GGG��f&��3�2t����� ��R�:v�������W����`���G777�s�������			�|����u������7����+v���R#�;�����Y��E�$�**��
����7q�x�"/ ppp0�M\��A�=��6q��@FFo� ) 

F�-+P��1///PQ)P�;w�K�.i<���sGv8�z�jY����Kq��9�u�V����XI���V({xx�"�V8���@l1����J�P�����[7PQH4 P����o�$N�9���0�M\�{yy%l�r����P��R@��~n���p�4t����`pp0
��(v�!���Cn8���$;�:u��p ..O�:�999�����SR8`�m666������������%T(�mI�'��'(PL@`
�8����#G��&.����v����M\n8@��BGGG�kv��iV�**e�(�J������Dl1pww7�p 22�������O�I�2) �7o����PB�����...4 ��2�h@�@�T*��o�Il�$^RR��������C��B�8#nx�m1���DEl�/:����e�������; 0�p��RQ)UL@��+I$�k8�pR@0i�$�
�/_�����e�g���:T�����%����L���W�&��}�\_��YG�����p���R�p���&�W��%%%��kW�kR@ �W,��X�K�#����D~17 x��W��O>���X�}�l���7:99������"#����U���/����TT���}���Z;m��g��A�qR@���o�����h2��4�p��1Z}����0a�,_�p9����>#����L0`��5) �����W�����p��eoo�			m�W,��X'���G��VVV�g��@j_��>b!�o1�� �s+++<}���{���������t|���p��]����j~��%���m��	v��q�]�w����e@**�����]�fk��� �+++q��������������;���U��i1`t��5\�d	n���M|s�@__QZZ��� Z}���8p��,_�p�t�$^PP�}������3v@ �;��W�����p���R\�^^^��b�}����>bm\[�X_1�{��M�����Xj�������}�����j���F_��������xCC���v��	`gg���7n�P���{����� v���_���2g��]��n��{���>3�����
�&�R�!.em����� 99��� ,,lmm�����$���
��w�`g|EEl��	`���<_QQQ!�W$%%�����z�
������1_���#�W0�-]}�3�"((�����C���O���B�NSQQ�2p@AE���h<�v�������n ���9������!���
�����w�U[,&� ��@.�� �8::�03	��9���c����cGLMMU��6�g��'$$`xx8�����3'�fs�2�Amm���
=��E���;w������%T(�mI�-TT�
(v�!�qo�$~��E^@���`�����=z%l�r������AR@*�=ZV8���c^^^4 ��R�:w���.]�x&7�s���p`�������K���9sp���������c�P����9D4�p�����b`ee%�;�P�,�%�[�n4 ��2�h@�@�c��I�Ts���a�����"J����������� ^�LX IDAT&&F���69�i�������`PQ)P��C��k��p ))Iv80u�TY�@\\�:u
srrx�����p�X�lllS�5����J�P���DOPQN4 P������+8k�,�;w.�?��I���o8}�t\�`�������/�o��~�!^�r��I�qf�]�jVVVJ���`���:o�'O�D___��y3��wOg��������m�6���G�����GQ�Razz:q�>��7����a�����������<x��$�g��}��	���
$����x������������8�����b�^����-��uuu����aaa����{��{�p���8n�8<t������F]�����3�b����l�2����'NH�����J�b�������R�m����������qqqx��Q���Bl1pww'�S�NNN��@��{�������|E~~>�W�����o��3�C������d�
��W�!�TT�
(�J�{��1�M��KJJ���Z��Ts��p@hg�
�-���hooo�8�����������V���b8�Hk���*& `�r���v0�5`8) ���2�p`��U8p�@^@p��Y�����e�����|���;�Wdff�����5����;��
.7�����DJ�R���3q��Y�Mq������@�����3g��%K����+W�$n�b����v��~M
F���o���_}<O��_?LII!n�R�P8��hgg���A�.]p��u�.���z���q�����������IK�������C����'N���':99����'N`PP1@D����#G�$~������{��� x)�������'
�6N**e�	�k�>kC[������������6N
�y���W�Xa2��4�p��aZ}���5j�,_�p9�"%%��+233q��������;�2F_A**��
�����?kkk�	���3155����3�x�"���bFF���~m����������?�����z�!C������; 8}�4�=�9�


�����XTT�>$&�!!!�����w�
�y�?x�`I\�����^�~]�s+++���_5��$�~~~XYY)���'O����{1,,����	�6���C���o1""o���3����/��cbb���� �2e��WWWOl���~�m�u������?��SLHH���o�'�W�X�}���s���?m<  �TT
����X������A�WTT��E�011���G<9��o��]]]���FW�\���x��ys����~�M���x��������_�o�G���+��.����=�����~��|�q�
PQN�RU*E����v����{��%X�v-t��������\g�r�J���___����F�nqq�(�����������/��OX�{{{�|�>���pww333b�pHH��o��!!!&N�(�U*�F�.@AA��3����J��.m�c�����3��>;;;g�]�v]���=���.\���`kk���)8pa��Y����jtm����F��o$''C\\���S'^__�v�����6mt����������G�]�����}�v������h�����������PTT�&M+++�����oK�eee����������K+�{�.�3SQQ^������G\;��
B\����_�~6o����0z�h����:H�W�^�]�v	v�_�z�������
��W�^��+��]+�W�\�Ro_�V�~���1_���.�W0�-]}�3�b��	_.'�C���O���B�NSQQ�2tBA����?~\���+Wd�
d��w���.����
)

�Cq������-��y7���3H-�k�L}g(e����=A@E�@u��w����y%l���6�5kFDD�����9s�@l�������~�����t������7����+v���R8e�A�!�W�������+h���D�]s�h��8��;;;�����XYY%l�r����t��AR@0|�p�p ,,LV8���c���4 ��R�:w��eee���
555���e���
����s���/���7� &&FR80w�\�����T���g`����`�!�i��="��������������-I4 ��2�h@�@�c��I�Ts���i�����!J����������� 66V��/��������i@@E�@�k��r��5k��bcce�qqqx��y����nnn��cm3����`@`j�"��p��1��C	�rO,:88�����@�������8) =z�Il�B|��q�� --M���p ++���=77{���~�n1@4��C�b@E�L��\Ib��p���3���Bl1pww7�p`������D�<y�M*�I����7���a
�tH!��DJ�R��={Lb'������V�&�*=��q�n����%�����&Nj3X�x1������Si�!�R�J��D���'QQQ&�Z�
��9"+8}���p���W��pww'����L���W�&��}�\_��YG4 ��2�h@�@�T*�9s���syII	v��U����K�#�R���q�p��G�
�t��������X�}�l�8q===���I���8q�����"jt���
�eN**e�	�k�>kC[������������6N
�y���W�Xa2��4�p��aZ}���5j�,_�p9�"%%��+233q��������;�2F_A**��
�����?�M����k��>b]��!C���J��H�+��G,���#fs���>bn@`ee������{�������/��cbb���� �2e��WWWOl��Y��\���2�����e@**���W�X�fk��� �+**p��E�������#����o�������L��+W�`||<n���M|�o��&�W\�xQg_A
�����7���#G����J_A�G�E{{{T?cB���}
��'r�,�������+��G��K�#������3�����c�K_��>b!�O1������s��];������X��X������]� ##�M���u�}���*5����Fy}}=l��rrr�]�����\N�9���2�y�&��{���������V���#�R�!.em���_��7o���Z=z4XXX@�$��W���]�;��^�
III���
��
����W���k����+V�\���`�_�~Z}���pww��+������_1a���/��|��}���Oe�
������:������	�?�����+��2\����g���������������j���AAA�D���������f&��3�2t����� ��R�:v��;v�P��6�g����5#""���M��9A 6s��+�I'�����~C,|��b��]�!�S�L�J�P���dooOOPQH4 P��5������xqq1/ ���3�M\�����1 P�&.7HOO�
$�����d�J:���M**�s��XVV��L��PSS#;X�l��p`���8w�\���/y3bbb$��Z����!Xs�hZ���G��-�����C	�r[�,,,h@@Ee ��@�b����8������$6q!���C����
y'HAll���_t���'�����J�b�">_;��k�������
��������������$���f��gO�����Dr���1c}�*���Xtpp���D�	._��3f����{/]�������1**
.\����:�s����q����?���*���3g044��[�555�9) 3f�����B���UO
��Em���o���^�������
����8q�����RSS������x�onn���,I����<����c��������<77��<x�������������W�^���D����l��AAAx��1�������~�)�5


t������'��������g0�xee%.\�cbb��_��i��2���C������
����r�3g������Eykk+�������L�W0{#& �
m�+�
d}}���G���,X���~�w��YYY�|���+��B**��
�J����w��&N�%%%�-��m������������Lb����,X�����g����DZsHE�T1{����������IAtt������C///^@���++(,,������*���+233���_��Ts�����
.7�����DJ�R��3p����Mq���8�|�&-�O�:�-[F�������cbb"q�%%%hnn�~M
���q����M���Sk��wtt� �����t��?��3����������IK������O�&-�_�p=<<����������G'''�3v@����~~~�p���~���P��)|���8n�8�������1**�h��qPQ)SL@�^;�Y�j�`�n�:�>}:1��I�����~h2��4�0  @�o�����|������t���������������;�2F_A**��
���~�����#b��iii���c���s�0""����O�<���9sG�����z��
� (,,���@,,,��9g�����N��_>(������������*��������:
�
�������e�~��a}}�`�/��������~!��������#F������������9N�4	>��A0e�5���d����q��z���j\�b�����������/�?������h@@E�@������K�l�[�xyy9������k���G:���4tqqQ���/_���8������W�������W����\��A�W��B\_A����hii��b�B���}
��'(Pvvv�{�n�s��>��%]8s����������8s�����<�>���/]��7� ""B��_]]��l�������b\h�f��������"L�!"�xWb�{�OW�>�w��!�9��@^^qH���������=q����q������y�}4X����s���8�h�g��RQQ)K�:u���`��!um�R�m�}m���Dg~��e9r�`@��V�mr`�\_%�W�7Ng_A
H?�.���u�$��|��E���6�ah_���cY�����TT
(ggg<y���3�&���@�&���@�&���.?~�8/ :t�A����!C��x7���3H����Z.�;s@)C�h@@E�@u�������y%l���6�1cN�0�������@l��������������k��0_�g�^@�f3���e�
���vvv4 ��2�h@�@�k�{'qR�����Il�B�,,,��6q��@jj*o� ) 5j�`8$+P��1PQ)P�;w���r�gr����j�����e�s�����{�����B)��{��'�Wb`������������fb�A���}�\_���%;�����kWPQH4 P����o�$N
h�����#J�����������`�����m��HN�RQ)S��CD�+Ir�E��@LL��p ../]���������p�X��w�.�Z8�H�9����J�P�{b����TT
(& 0�M��I��1cx�?�&.����RSS���
H����^�z�_�[M���TT�; P���Uu���Jl1���0�p 44T��1bC����mR�L
,X�{?�;L�B�)��2�h@�@�T*��{�Il�$^RR"�b�H����&��p�ZZZ����Il��k,@[[[�3v@`��"�9��R���@IW�^D8�pR@m����u������b '(,,��������[�������������Cm��0�YG4 ��2�h@�@�T*�1c���syII	����_���b�}�B\j�6. ����A�.]���>3��b�����������~�������� �FW�>�P]�4 ��R�����v��6����h��u8}�tb8���v�!�?��d|iHa@@�V� �+���e�
�������}=33===��I�w�e���TT�
(;;;������XJ�6N�#��8P����b}���o1�� ��j/\���^c�+F|~2���?�I�&����y3�L����.�;w����������.���jY]�4 ��R����p���m�v��
b������q������#�yZZ�`�!���qqq�������(..��+��;��� ���Z}���(,,��+��.�B������Xs�p��@4n_A**��
��������\j�6.��X'�3�+���K��fDDD��W�O1���G,����%�05����+�#��kyyy�!����jNz?s���U�>,��t������e^YY�>JEE�,u��	����k���A�KY�q����������q�����ZAYY��r}S����`*�u��������+H\_A�/�W,Z��h�����$}|���
��$(P���x��I�g�M\N���w������������C����a��"��@.�� vvv�kL�����spp����cG��g�b����>3�|��8a�tssS?g���\�L
�5����f�g�^@�f3^D����$;;;PQH4 P��5������8������$6q�k��@	���p 55�7p��5J0

�(a����
�����;cyy��3�kCuu��p`������9s��{����|�
qH��p�X+������477[:w�,�;�P�,�%�k��4 ��2�h@�@�c��I�8�$6q!���G����
���y'H���S5����=��)��R��5���W���r����Y�@\\^�t	:�^{�5I����t��]0 0�p�\s!�;�P�,�����#
��$(PL@`
�8���1c���0�M\��?����*b����?���z�R�f� �f�!
���)v@��+I/�������b���a��@hh�z�c�������B�,X���~�w�B�2RHEe8��@�R�T���������?s��y�%K���7t���������U�����:���B����
6`mm�N���D���QAAzxx`rr2644����&+T$�u�r/�_y��`D��jp��BKKK433���\�{���q��=hcc�������J���G���099=<<���@g^[[����>���������Z��a���i\�at��m\�j����/���3�q�.Y��������:���
������h�A�b�TT���}���Z;���a\\���

qR@�{ii���
///^@�����7�����Y���r|���
�Wdff�����5����;�2F_A**��
�J����X�3gqGD�9s&.\���IK�o���X���IK�������M\���������5) �����[�7qD�>}�`ZZ�`�������&-����/����]�t����{��������IK���_G;;;�&-��;w]]]�������...����~�������� >�;D��/���������^
��y3FFF
�6N**e�	��v0Z�z5N�>�h����]s���>0_AR8p�@��A�W�������+�����L������;�2F_A**��
���-.Z������zq&�?p��^�I��m)�����������_�p��~�WVV9���q��@��%��r&��J���	���=��-���=�Z�$����zq�d���c�3&O���$1�������3���={��<>>�,YB��o�����?
��(333�?~��bk�gN�]�V/���_�"������[����+��?/�W���/:�
R@ ��S���R}�U'`� IDAT��S�N��C��|�q�
PQN4 P����033��\��?f������s���?��c����I��.��_zz���B\��>��������6@
,x����V�����o�:�p}�WTT���3
���N�:a@@���$1��Z���R

EWWW�3v@ v����T����+���t�����]_������X�|91 P���G���...4 ��2�h@�@9;;��D�&N��N��!!!&������
x3H����*l��AV8�j�*��@xx���@||<:88����J����#����***d�eee�'NDwww�s& �DGG��K�,��+V�Z��� ��CD�	<HR�f�@ss��p ==]��������D�]s�h��8��Z�w�n�8I'J������������t��}�@N8���c���4 ��R�:w��Qs�(m`�$�	���e�qqq�;w��� �2e��p >>^��0��Bwww��)�����^zI�w��{����T*Y��k��4 ��2�h@�@�c��I�4�$6q!.t�@	���p����w2��kM���)��R��5������p9�@\\VTT����J
������Z0 0�p�DFF����_�������=����D**�
��&N���`��q���&.�I3RRR���
H<''{���~�
L-@�-TTJ; P���9��xxx�l8����*��:8z�h�T(�n���|�)T(�!�TT�
(�J�&���xII	ZYY�_�j�m����7 ���D333����������mmm����)��4 ��R���@IW�^��BR@�{���6l@///^@���-+(((��T*Y������+233���O��(y`�>��TT�
(�J����&�W�UII	����_���b�}�B\j�6. ����A�.]0%%��^c�+f+//]\\���Y��������1@D��r�v�����J�b���V�^���O'��8) `�2���L�W��8P�o�>>>�|���
�=$33S��1) �����W�����p��ekk��-"2�}�R���qR��������������b}���o���bR�X�!�q�#��d���c�3&O���$1���*�r����c�v��������J�233�������!�6�q�d���k��_�5����_s�����[����+�
e}}S���� B_>��
!.�W��+:u�$x�@�w �����D���333y���c6q9U��^+`��?��7� ""B���r������:���L��������6@
,x����V��%svv����S'P��$F�^+`TZZ��������~��Tc�2)  }A7�L��+�/_N�|�@nK���
��$(P����/Q������S�xAHH�Il�B���Z
���
x3H����*l��AV8���c4 ��R�:v�H��������
Y�@YYFGG������]��	���Z�L
�5���<xP������Q�,�%����TT
(v�!�qo�$Nj1����Il�$1�(a�$''�N�����9�����������J�����F�!������$��PN8�����s�N��)S�H
��B���]k@`J�"�����^�J�P�����kWPQH4 P����o�$N

d��:A��M\n8����;@
�5����f@�RQ)S��CDe\Ib��p ..+**�C
]]]%���f`mm-�Z8�H"##y�e���
e�'���h@@Ee ��@�bS��I��7��~c���8iAJJ�"6q������`�^������������J�bJ���"g��
���P�RC�G�m�
eR@�m1@���0�
e:����p���R�0##�$6q/))A+++�kR�����M�7<����hfff�8W������������; 0�p�TTJ(�J��XH
bccy�7�p`��
�������e����J%�W���}Eff&����_�%,��W�����p���R�p����`��T�g�����q��Y�|�r�����������166��[�w����?x�����7o�
��O�>�����g���yHH~��W����_����s�N|��1�744�r�J�YYY�M������%q�M����w����A�.]055�����&���BGGG�&+�c�~�����)�<y}||�_�����V|��	���������Y�����!!!x��������c���s����?~�����122���u��=�M�6��������:qPQ)Sfffx��e����=�G�����q���X^^��������g��acc#.Z��M|��H_AR��7�����Y���r|EVVr����;v�@OOO�3v@ �;�����D���?��C��g��aQQN�8w���/((�Q�Favv6������c��aPP?~\o�����V?g������Eooo�c�����*"?x� ���_�������1++�����L��X�!��~���uU����z��m<X/~��=��i>\g����555�n�:�4iqATT����_UU��1���[z���r\�p!&$$���{�=��������KZ���
��(333�7o^��bk�6���3�x�"���aRR�^<%%]\\�����g���_������/����+���d�����}) 8q���R}���+H�E���]��?��<.��o���������Y�be���������>%ZJ�W��E&�!�K�����������h�H*��������0������3�}���6�qF>���3�� �3v�s�����G�t���+�A���<0����eK��L���������������:�\�����p��eT��+�J|hh�h��A�lE:""����<��������y���i)�_��k�0`��A�i��=9�+��������sE������+��9��gOLNN��:u��$8sa��Y����=����O�������{��W�?��s��?N������� ``pA��U{��I�;��
R���A���'N�H�P���;�={��=�qiL�>��9p��9�����?��+����YW���P7(�
�EW���?���� �6m���g����"]��M�6� ``p�A������m��s��III"��[�n5��K;�����A��"�����������-[J�����e��5K�9���o�90y�dl��3\�<�����+���]�e\�t	?��S>|8z{{�8� Pc|����u��?��KW��?_������I������C

�0s���\�9�r�J]��E�� ``p�A�� c�"N�i)/��B�(�Bp|�
��+q����%KD�4�@�TA�Ro�������m�}`G\�k���V���I�cL�<Y�9���O���7�f6L�90}�t���6�H����J��]�v�AM3�)�k���zuETT�ns���[��h��3�f� 8��&qO3:v�X#����[7�Ap��E�(�z�___Qg@bb"�ga����uh1\�u�
)d`pM�1��r$����'N���j�A��mU�4�q��?�<� p�9`6��+h���?
���WW�������_~�N3\�kD��4�@�v�&���)\�x�Kq��-�`�����U+�5� ���"K1``pUp�+I��Z���:t�������n�Zd���9�8p��.]�{�n�����CRw���p��
)d`p�A��0%Y����$��������P��^��+������qc�g2���\GD�"���+�jy)sE��� h��6n�X2RH.OX�/++�+VHi%���/^,Y�����\�0a�h��v�4rssq���Ts1;;[��_
��I���OKK��r<3\�A@���
��;8���J�r<� �����+|||DALL��nP����+8^���������������3� �{i�8�
f008� pApH^1�G�h�"�CO�������5�X�'%%a�z�l�H�@m^��<b_VV�?��3&$$P|�����7�L&�Z�"��+����
���{#""D�;;��j���74�s��F����:����������;�s�h4�f�+��a��5k��wO���e����x=Y�� ``pM��S�_���w�Y��J�P�������144'L�@���>,2��C����2���o�+8~��8o�<jg��UW��v��UV7(�������+H��+8� �9@�BTUU�����7��]#
)�����BN7��� ``p�A��h����1Ct�:���������O���b~~������F������|�v��I�&���A�%���<b���������Z��bj��iy��#d�!�����}���_%y9�����BR���o�i�s��RY�J��[�����7����j����q�fffR�WYY���O�+��j��!�.�:u���_-�wL�>�L�b��7���������X����l�H��<V�j�*��zu�,L�@�+���t����������
)^IW��jt�]Q�~}�9���x]����%��3\-[���z��E|���h�Xx��M��f�����������
�tv�����9���)�������|�M�f0@� p�����r�s������tvP8S�ft��Ir�@NN���w�����j�������7D?_��bOOOf00� j��%�����C{f���s��g���<� P3s�q�P��tg,��YG?���� �6m���p���)Im��a������'o���"^XX��RSSe��#>����rZ&%%��n��9��s��o����2�v���z��|��=�v��E� pt������x����ET7XH8p�f�l�R��7o�.s`��Y�`��u��b�w,��jZ�j��3�<#z{�
���k�t��.]�O?������6�3���k�2�  �LM2>LR8h� �����7%�E�� ``p�A���b_�O�8��qqq�k)))8s�L<|�����d2����q��y���I3�����-����;">l#OLL��fj�4h@5]����088X�z��v�aR�0�@�9���������>�#����k�b���u�������!;��b�����q��u���O���7o� 6l�*s@o����s1//�����/��2��f��];I��Q������g�Qy���yyyXTT�yyy��E{R�hA���%u�3#��f3���_�S�4h�'�.� ��".�?~?����>">|`z��W�E����/��?�hk�6<����C�A��cG�:�����{��Uv������n�����/:��#>|P~������~�{�&LP,������D4��d�����f3.\���5��v�
)d`pMp)���;����O�|��p������FfddPS��m���u.z�%geddP��#"��q/^lw����?O5m!<��{#�i���?��o���a��g��7�V_� 4��E����� ``p�A��0������bDD����������v�������#��H��?�k���nnn��[oa��y�����|v�f�.?��b{����8|�0uH����V����������DV�zSSSE?_��[�V��?�j��v�4mpk\�v��k�{�'e0����5����������%%%�g����{j58�ft��������s�����t$�n�Zd���=s���#��8Z��~�c4]A3�1�����+�xG�2�lH!�����`���(���?���">,<G��}...�?��G�-*Z+V�P�+������qc�g2���R^��<b5o��%�8�y 45j��7�+�Xm^��a�$�1j]/	�<���\�0a�h��v�4rssq���TsyY���%^J�jY���A�,sf00�&8���;h����#i�����q��I����&� ���K��k'����/\�Pm�����v����g���n�>>>"� &&FV7(����+������q#�����Uj���'�@D[g����`�.]l�i��K�����D�,#%�@��A���<0��a00  �!y�d��E�DY���X�x1��9S��<����b!��������]#
�y�j��i|ee%������g�k�X,��b��Z�� x���0""Bt������W�<c���F�ccc�C����i�8����w�N�0��Y�J|EEn����������5�;w��,sf00�&������_W�;��Y�C��v������~����'&L�v���chh(�?|��� �b�������o�u��HHH�=�HI7y����]���%]��{wY���x��1����t���9��
a��o���|�M�5� ����
����f)��(�+�A���<0����E		]7�Lx��12d�X�>..���+A����p�?x� ���K�<x;t��M�4�]�����w��w�y����iY�����������3g�������,n����kG]yy����v�@�Fn�O���o�Z1//�.]���w��Z�?����w,X���322����#FP�2�����q���1'L�`��5����q��-v�3--
���u���)))8i�$�3g����33\u���I�&Q����W�\�i�����~k��]���V��UUU��������d�o2�p��e���e�F&�	q��I�_���������5'''+�!O3h�k�R����q��i�k��WTT����uE��M�G�t�~]���y��wu�������|9]���.��-[��={x��"�999v�7nD��(�w[�Vj�D|XH������DD~_�b�,?w�\���������E��"�~�z�Hs`����k��f&��V�8 j�'�4�������A�'o�4|}}�����Z�VLMM	��������D<g�����?O5|||l<	�\�1c6/]�$�9s@�/((�m�U��KJJp��]8~�x�q��#�9���_f����?��C��A>���gx��U�|JJ
~��7���Om�g�
��:u���wUU&&&�{���m���]���9s��6p����a�]�t)O�h]spp��n�4�@�>�nP�4���7����i(����P�A�������C��@D������b����=�k���m��a������'�	�[�9�������b��3g�����{���q)))��8�OJJ]�v��"��PZ3��".5��S�N���"N������+|������w�g �c_z�%Is�������u�����2������I��A����pww�?���w���no����`��5�@rr2�1��������aPP�*s`��v����d�n<-k^�|�f]��cG��C��5��
���V]AR���:�(**��K����#�}��Z]��ysf008	� pAp1���S��;��f��]�X,����'O�e#>,^K�.��������i5
�)��7wx�w��e�_�7nL5���������]/�E|�����A0p�@��Gv�cdeeU��CBB���.]�0����Q�vm[�!��}B�9p����Ax�K����@`` ��9���E3���9s���b��!�p�B��c-3_�{�]��k�I�6�f3fgg��d��^D�^:��z��I���b�����������:��e�EW4l��r_) IDATN3\�AP�E���[TT�>>>��O�o��3f�M��������3�1��;w��"NF�Y�?���0���'2��;��"��;�R�{��!�8y�$�L$�b�(6h�J���7xQbz�|��=���q�R�����R��w�5�M�&i�Z��B�90u�T������m�V�9@���t8v��bZ�2331??�wM��h��)� x�@VV���v�Y������
�A���K��9��WWx{{�^:��c���EWxzz2����I`��`0`BB��"�
N
		���0����O?a�n�044�����>�Z�j����k�3f��C����S�������^s�n����w��"N����v{=kNMMU]�9����y���]����099��w�Dm=��Z����b�]�v��/�h�Fz�������8c������5�}�"K1``pUp���5>��3U��f��/_n�F����A�9��4��c��1N�:%����������o�����s����i#2rrr��5�%����y3UW�a�!�;��}����e���_��`"��+��B��.�������E�a���� 9�3��v�a���w/��hE���C��{�Q�������7�}&c9���G��#"��K����t=k����i�&Isq��u<^h4l�[�lI-~&�	W�X!Y����z�[\\�����qD���Y>''�������v�4rrr$�D�X(����w������������g�{������8u�T�9���B\\:���[� C.\�1c�P�9�f�[��9�KW$$$HF<
!����\�h��]���#26m�$��t��={��e��;��i��9@�4]������4�@�;H(�
�/**R\/���i��)����.OOO5j���P��������������je���/$�� >|;�����"ZYY�����a��I:�J|||<��_�v�4�F#fggc��}1**���ggg���n��]VlU��ITTT���w�C�����M/4���������������oR������������{�Q���<z�(��X,XTTda���6�38~�������B��i���+���f��oD���q��E8a�j����D�:u�����{��l���U����?�v������,Y�aaa�}�vQ�<���������UUU�������8m�4j��+R��">�
���l�������jY���]AK1�����nP�}���5�]oee�M7Hu������j�*l����iH�J����_�^-k����xf008� pA�h�CBBD�������������D}`Z�v�h��TUUQ��9H��:`�&Ml�9�@K^1���#�LBm^1-��v�@�F5y�������X���;�y�Jy����#FP�2�����ZiY���C����C��cR|����A�����S�N�4��������[�<"bZZ>����%@777|���q��%�6�%K���,�����%KD?�<V@�M&.[����l�H��<VI�_NW�|vvv���Dee%���i�4��v�]!��g�g����
juE��M�G�t�:]!�����t����
\nnn�����VUU��7,Y���o]�t����������z���}���y��Abb"TUU�'�|�����������f3;v.\C��6m��x��G�U�?��<!66,XAAA��E_YY��6l(��{�$�F#���������www_QQ��o���g���+E�[�V��_\\����l�2X�x�$��i��!&&�.]
!!!"������YYY�v�Z8u�L�6��w���Sy��
YYY�f�HKK�	&�~�#���b�@ZZ�^�,�������TX�b�,������e``x4�X,p��m��B����������s������1cD{��K��������p��!�;w.���N�>
_~�%4k��v�
��=������#������/���{���f�RRRd���d����T��� 99~��7h�����{T^JW "�����{�`��A���g�L&�8q-Zd���Y�f��B� �+��_�����c�;v���-�b�������fY���+L&������7���C��Y3"BAA��nP�J������p�3� 
OOO���P�*m��c�|�����W_E777������={��i������*��q��-�������4>))I4��k��vr��9�I$�;u�$�A�e�0��]��5��y !�g
�:^z�%����@*��vT���0�L�@B���/�������H�@�k�����D�^PP��W��w�}�~�i=z4��,X�@�@B!?b�1

RH(���5#��s����h�"���c���1��������������:uJr �Z]AR���J�%]�z��E0�3����7o�:�f� ��CD�"N���S��w���������{7N�2�|�M������������'O��=���
��@aa!5��y��v�dQu��-�ns`�����qc�A����X/	-S��i���y����������/J> hI3���3\�k���"��A���]�v���������2�?SQQ�����Zff�.s 00g�������!��Ve�"��fD�9`O��k��&ih�:<s��C�[\\��@����WORw�����
�����f���K�.E___���`��
�A���$0���JE\ID�i������S~AA�����_�o�����V�Z��W/�={6�8qBH���C�A��sg�"������!C��2�����s���m8r���#���'O����$S�E����_����y���:dC
\\���5Q�111��'O��_~���9#�G���+Wj�����q��9����S�bff&5��m����!O�2��5s�^s������iS�A��X�~=�T�z���4�R�4��_������t��� gU���V+n��	}}}����qZt���'3�f� &$$��+����|��s'~��W�����O<a{�j����{Wt���"� ���?�~�y���6�����T�E���<�
)�7o����#�kO^1	����v��_|�v�4����
�k��9|�$�1Y����3��E�����x����N�:��`XX&$$`ee%.X��gX�!??g��!�[��O3:v���0�L�N��\3b�tp|�6mDANN�&s@�W�z����26o�L�4�@sH�9]�|�r���b�`ddd��IIIlH!����`���H]y�z����;v����'c�^��y�Z���|jj*6n�����9���W�}�v[^1��C�3h���5�~��M�$�Dq�� h��!�l�R1���[�VUk���z���4�������� ����]#
���IsyY�JQ���S=k&����'N��r<3\�A@�-���7n���S����={�A�8q�Dl��=�C��g�����c�����_Uu��6����8f��9 ���c���3gu9��������������t����� ��i��nP���^!6m�$i�<MW��������3� ��� gU�������6�t�g������'�5������RLKK�����Z�+++���K��Q��d��W,�����~���k�A�6������Wl�Z������+�<c{A�Ku����A��uq��u����_�z���EY�V�KKK199���;�w��]k<w����b��FJQQ�M�yzz�8� ��P;
%���V�-������c��F#�����n�������h�"�0a�s@�g�k�N�:x��E����WV�Z���9�<HJJ�~���>?x�w��E�������z����0<y���Q=���yyy���M�v������!�\�!����������������5Q;��
Z�a�^�du���p�z��A�s���(//�U�Va���m�H�@Jwp����w����xf008� pAxxx����E�+**066���q���v�{���A����GE���i���;w���}�R���2U|����I�&���APVV�[�l��={R��I��c�PZZ�����w�yG�:t��!=$JJJ0"";v�H}-..���p���#�����<\�d	���;��_�'�����K����E��������/�n�X0==���C��f3��qCBB000�:�p���6�vjj*~��w8e�_UU���?�L��!!!�k��d2����q����`�*��Y�S�N� ``pA��S��O�;��������
��T!�(����#M�����G

�����������p��������F#�������e�FF��=��a���R��Qk&Q^^�{����+h����� ������~I��VW�j��z�@Nw *�
G~�V�UV7(�
f008� pA�l������F��������?h� ����1??��sE:((���Do����������o_���=h�E\�_�p�h��lE|��-���d���e���#����w+�4?--
�_��4�E�������"��� ��_�~�W�}}}y�jx�g�RRRD?�d2���������f�+�r3BBBp���x��%�A��CO�3���;9r��8!�9~��)8n�8LKK�-557n������6I�a��)�����Y�!�k���?��c��A��/�w�n��_~�����O��l.##������~#��)������W/|��Wl�9��4BCCE�9�K�G���;
�YW����,��J�b��_���+��A���;w�� ����eu���p�����'��tE����A���$0�����������Zs���_�P2�)�4>99Yd����6��Vs@�+i��@qq1���[��su
$~{�xzz:�@��Is $$D�9��w�I
|�����8q"zzz2�������.zK�vo8x� �g��f�������!//�o��s���������������G���2T�����Z3�Xwh�;v��9��W��Aj�
7�A��Ni��/_��+hC
{��m�9@��A�6#A������uE�f��A���$0����"*q-����u��qOK1������@xx86m��j�5���t�z~�v�� J�:t�.s`��������2e
����� ``pA�1���#Ij���}�H��)Sx?[+�.]j�9�����u�V�����2BCC�����3�u�VLNN����
<r�.X�/]�$9(X
�qG��P�+^y�I�@�9@�M&n��YR7h5K�CW����K�5�b��	T������O������d-��Q�F� ``p�A���5E\�����=E���__�k�����������$����%Kt�z~���IHH@��`�L� ����Z�{Z����}�6R���� 
5G���R{��p��ux��i���������u���=fggSS��m���zu��l�};]UUU-���^�z���b���x��9EsDh&��4]A3>��S�����������
���K��YIII��Zt���'3�f� ?~��E�Y�"� 0`��~W6��8�y@R���?:��k9v���f��m��/����i�Ds��00�*8���G�,��#Gp���"^�9��4��������n�E	VVVV������� �c�����F��\��������!2�������CRw��Zg!����s����lH!����`��+WJq���`��a�g��Hi5��]�$�������5�}&c9DGGKqD���(�"��_�z�d�V�K�����/��B��a�����E-�����h�"�"����
+�yyy���?S��>++G���k�A����3g������o��o��������z�*~���T���OII�	&P���g�{�={���g���1c�P�9�f�5Jt?7��&�
�A�f�Y���+���u�
���+:v�H�111���k�L3������+�A���<<.D��'O�+���F���M��8������={�@�.]��O>�F���+** ;;v��}���!C�@���U�������
��o4h<�����;w���b�����233!::��~�!������7�����W�^�����6��������GEEAXX�������O����R���P����o��K��_RR���I�9��f		��;����k� &&-Z��GD(,,�.���Ga�����C���j���S�����
����y�����������O�~wD���\HLL��7o��Y���W_����������<///�|UU����_�f��N�
�������>�j��	&��/���GD```pM���Bjj�m���78r�0�Lp��}����f��A`` �h�B5_UU%��y������������Ct��h���,�uEEEdeei���/}�;w���
J�"::Z���x=�",,LRW�L&��I^Jw<������Ip�7� �={��:��'�+V�s�}G��d{�O�#� �W,�;w��M�4�]�:���I����l�S���#V�WL�#�1��V�+������}�j�����x��@`` uH����m<�~����UN�K�rY�JY����Py�uX����� ``pA��S��O�;��
r��� ������5�F���W����]�b9�;V�a���zu�l����w�f]A�9<s��~����k�4��tE�V��G�t�su��d��`����
1�x�	���
����a�����cG���3�7���U�VA������_��p��E~���0l�00<���bccU�C��'�x��[�V��w/�X�����y����I�|������s'�X����E�|������u+���CXX�f���6n������o��R���a����i�&���_4��������(8p���=[o�Z!33��� 11���5�w���u����+W���������;T�b��������� o6�!--M�_�v-TTT@@@�������TU��O?
C��.\���HY>//��n��b�����E{���A�W�7��III�f�h��1������L&E>118nnb9WYY	���m������Sy��b����t��U���B�������
!�UW���c����d2��=�t�
��WW(�&���
����3`�{��=	I^�@B���LM1p��ag����[�z��$��zr�p� ���`0�f���$t��1����d.www����]s�0S!�u �����G�������� ����{�r��%c��E�����!��{������7%�Y�f�����I`���9D|��8���xxx��".�7m��j�B�k��3G4p�fQ
�����c������f���9D�I�c,�5&N������P��u�hH���U��k��+��"i�4s��b��qcI��
�zS�5j�'�.� �	E���__�Q���w�}Wd$%%�D�k���O���������L1@��Q�,����5A�����2e�ns`��)����������)m��Ue<��/��� p�9PZZ��e�A�������p�e�Q����� ``p�A��0x���Q�i<� 0`��~W6��8�y@R���?�D�ky�����m�_|�v�4j�9��b\�A�JG�h�Vs��i���o�5����^^^"� ++K�9PVV��X�~�.]A�4�@sH���B�?js����lH!����`��+W���b!������� IDAT�5�}�RH(���#������R��8�Xh4l������#v��bYYY8z�h����]#
���,�9s&�@D^V���_
��,sf00�&8���;���wp8s��3�j��4�`��Q����5AW�����5k���%]�KWp�]��cG�����A___�g�A �$G]���)�NHd������+V�G,����������;w$����+V�G,���#��iy�Jy��f3���h�#V���y��


 11233��������������7o��Y�f�������$??�?n�*���R�;;�9�����\HMM��Z�G�&�	��������Y3�-Z�����D�9���rrr`����F����������IW,_�\����SV7(����h]��������0I]a2�Dk&y)��8�
'�y��<<<p�����j���x5y�r<-���T^�����36i��v�� ��WlO1���G�6���GL;b |����b�<b%�<6HR8x�`O��k��e����R��,sn��=Y�&�	;u��:\u������S��{���7�������p���h�_����l����p��q6�;V�a���zuEll�.]�w�^���S�N��3g�P�W�+h�]A��KW�j��z�@Nw :WW�)I��
�A���<������������C\\l���y������eeep��E~��u��x��7x|ii):t6o�,��_�F��[���%%%�w�^��e�"��'�@XX��X,�u�V����I�&������a���6�A�<������a���0c�E^�7\XX6l��[���4��v�Z��m��� ��l]�����?����k!66-Z���Z����k���S�N���U�-��s��[W�\�Y�fi��_�������,���"�:o���j����fHKK���())��S��x.�<**J����777����x��d�.@TT�"������a�x|ee%$%%��
�n���|^^�h����b���"�2e
�����������'O�����������+**�������;777����������i�&x����g��T~��u�t��nP���+�x��x���AIWy��B�W��?~<������FX�jUw������v�
�_�z���BN71008N�'������+++���'�|���-���\��/--���w��W�^��
F|�`o��
���o�����y|qq1n����ONN
)������w��):XTT�����|aa!�X�{������JM��p��e����������J|~~>������K�����|l��=���j�bNN��7{�������{���g�,�"/70Pi� ��f�:���$���c����<�{{7m�4E�����[�n����J<}�4~����x2

����'N����188X�o��5� ``pA����_����uo��j�9>00g������<����9���5
������6.,,����8j�(\�`������t��Q�t��e�����W���+h3��CI7<n��6��G���C�������+8^��h��� ``p��3����O��7��K�.���
6�����������n��6�t������������c�I����_/t�rrr��/����{���?�'��S�B���yg��x���={6�������J<���������������<�����}{��_�?u��l��K���O��9�R<�9@��m����iii����S���`����9��/��V�Z�x��?5�������7n�,O��e``p<���������4�
4^�� �{xx�����Y�f6^�9 ����k��wo�n��>l��	^{�5�&M��8RW���k�u����.]���k������@Y7<������Weu�3u���UUU�u3008� pa��".��h��y�+�$Ok�,,,t�"���r����X,`�Zy�%�{�9���:u�ns�������
ed``p=�{�s **J�9P�n]]����@�z�D��y��*s   @�� y{t����cl�7���t�
N(�={�t�9��

��+�A��� pQ��Q���
4x���".4h�.&&�%��^s`��Y����w�J����4���;� y�Du�nnn���q���2F��{�'Q�^=U��?N������Y�9P\\���x{u��
$u
�*�$
����+������i���_��3\�.]��
�8�;P�siEZ
����%^s(�#Y����!::�Z���QQQ�EZ-/���Y�F�7��p��!Q�x(B��YC-�4^	TZZ
����"M��"
�PdDFFR��>''���'����k���<��������>���9��&����/_�|;��g``pM�{�={����7(�����<v��'���)�
�N��1��v���5���OV7(�
��WWp�]�u�VI���rO���B�k�B^��```x�`).��
�����}{>|����}�69r���`���"�_�/--�[�nA\\���(r������q�����'�|}��9�J����E�����!--
���`�����{�����48|�0|��7������k��)��������U�T���+W 66V�=�j�Bpp�������.@bb"�����V+���BRR\�|���������8y�$��{�����f�rrr >>JJJD�	��T���x(,,�vdgg��c��b�P;�x��YYY���0v�X��?%>##���/x������?���{��$/e�0008���p��U���uo����%������G���#F�u��F�QTS�Y?������G�u��(++��7o��+JKKmu_��X�x��;>v���nP�qqq�t����g���R]yr��q�N������8g��urj�������������Ta)��*|��YON���u��M�4�]����A���
�����'�{���xr��O�&�
���S��8p 5��9U��������S���'�
�5J3O�L�4��b0h� O��K#����D<�V �s�CCCE<9�\�?~<.^�X����x�b�����]�6Q��{��fo�������Wk����p��y���e�������\Z��-[�����w���+�m��YWt��I�b �����t���+h|u�
///Q�����eu��u��d��h��-K1``p�����������w���������}���v���x��@)�k���������r��!CD�-�l�\��_|��������J�\����5���B�������0OX����9s�&^x���o����3&N�H]gzz:��fp3F����3�x777���Ox����_�n]4h����

��f``p.�V+�����-{�W�7���L�����g�����C\\����x�����w����y�]�B�����Y��t����+�|u�
��]���#R�C��@D]�B��d����M�S�	*<==y����y�r��<b9��G��W,������������S��W,D~~>�o���A�6�X�W�G,���#V����q�����Z����k��y0v�X�~�:�';�x{��I��,����c���Y�������/�5�{�W�7�����8{�l�����d��?j�(;v,z{{����0�u,X�srrx���zu��e�t����Wk�>>>���P�
������u���CRw��999�t�����5cN� pA�o��7�L�Z�
y�i4^��<\W��9�����5������:�2UX��8H�m������@kZ���;�\8tL�D�F�I�����yx��'y��WUU�J:�x{�NH^mZ���k�A���E]y����L+�	��������Q����^�*�;���7%Ii(#���FM(�j��7o^��8��n�Z�f.*��E\�9p���9`�XDC����u���
{�Q��������:�k��[W�9���P�^=�:o����x\#������������"�F(����������P�$i��xh�Gf�(�Fc�(�j��
<V��R��B�E\�90k�,Qg���w%���a��Vs@�f���u�����Ns���M�90n�8]�����EQ�������<.������Y�9P\\���x{u��
$u
�r�6m��L���B�l�9 L3��+�����f�(.]�Tc��i��b�}XR�+V�G,���#���~2�����f8t��]y�B^k����G�������}�$c�rrr`�������r���^k�����e����� �{�!�uoP���?/y�@
O���S�N�:UctE���Ek��o��nP�o���x=�b�����A����zu����+��^]����h���1�V+$'';$�XM�O�#V�+��/_��sP�W�6�X�W�G,�KuH���Z��)�X�wv^��l����������xBD������x(,,�vdgg��c�lY���9^o���d��������#33�^�j�;��
r�����WTT���w����`0`����9�h4�j*9������������eeep��M�uEii������/}�����
J�"..N���x=�b�����B�+ONw<������Ix�3�������#��6�X�W�G,����9H��n��a�&Ml�#""p��A�����#&y{�������HM1����b�<b%�L#�4i5�`��A6�v?�F@�*'�
�x=Y�oo���hD�b�����]�6Q��{��fo�������Wk����p��y���e�������\Z��-[�����w���+�m��YWt��I�b �����t���+h|u�
///Q�����eu��u��d��h��-K1``p����������\u�#��������I~��!����ES^��<b!�5�XK^�0�d�|Qg^��<b)^M�O��8q"u����T��I���=g���d�����e����u3008V�JKKE{��������xr��������3h����!..NtL@<s�����;[Wl���.]!���?��,�
J�B�k�B�:u���.���)��WW �.]!LI�GW��&��1pA<��S�BSZZ
qqq�m�6���;|���<���<{��Q�����
�)**�={���}����x���y��
a��p��U�K/�$Z��{� &&&L�=z�������e����x��/??��� ..���;����"O�����Bdd$=z����S�N����V�X���e����o��[�?��w����?Ex��Up��Y���_���_����}��Yiii0w�\^{��jU��_�������l�={65�P�����������`0��S�Dk5�L6��po6�a�������p����i�,����������FHJJ�-[�@�����'�Z{a�����iS3f�$�*10�.����{��
4������9~��M`0`�������28v����C�������[��t�f3����:t������X9]�[Wt��l���x-��vL�<6@�
J�����$_��"##C���g���+W��C������?���n]��w���[W���������h�:\��u������i5�\����y�����������G����|�-�4�,�_��l��d����d�8�'���y�����+���P�f~

�-�R<W�CBBd���i�La����h���l����e�%^�90~�x����M��v100��|�Ij��s ))I�9�u�V]���;�}����GQW^vv6����fH������+>��c]�B��������@Y7<���Cff�����+V�Z�KWp�]!f������FM(�r<�f����"N������|�(�z����l�9`6�Eox���U���<y�ns@84L�90f��A�����;��[�l�m4m�T�9`0`����4��G�������+H�]A�juEii)��u�9����KW����2���$u�^]q��Y��@HH�.]A��f``x4`������Fq5�@���+s@���a\��H$W(�z����`Qg����%����~{��w�9 7���� ���@���u�c���e�9���O�A�����ty��2


t�QQQ�tEdd���@AR�0���zu�0�s@�r�UW<�;���,0��E���;w��q��G������EZ
��A��w/�H��w��%����[����m�&Y�6l���i5��5k���#�"���s����ey��III�"
�����/�*))���WS�4�'�4������>;;���/����-{,���;�a�?����]�&���OII���h��%����5A���
B^����'%%���������K/�$�
			5FW��UK��]�v��%]�m�6]������#G�H���$�F��zu����+��^]����h��9��j��/B�.]���>9�W�\�S�NA����_�~"�_�/**���/��3g���>�>�@�������p��EHNN�#F@��=E���i��!��~JJ
�;w��~~~"�?%%.\�S�N�.]���s��)�/^���������?{��*^�s���k�Z�0u�T������N��;w�P~9�����yyyT�_�7�����	'N����r��/�WUUAFF�������H<!"��y���:���:u�����E�r��h�[�nA||��uW��O�OKK������/��|������7$y�����[�������C�� �+�
J|YY���ABBx{{���CE�r|EE�h�!g������k� 11�!����.]�d��(**���M�b����8%%EV7(��s����O�P�+BBB��"99Y������]W0008� pATUU��`��� �u��/  z�������&O�]�t��d�������9S�0��r�����cd��/��/���$.j�#��V�\)�o��I��l���u�f�l��������O?
�����3��w����s'��+�d{_zz:�_�^O������5���D���'���#y��������_~����>��s����`)�k�m��%���<�l
��7l����:�?�����R<������@DX�~=�h�B�w���x5{�O���h�KKK�����o��c��>�H�����;w��+����v��KW��<y���Z����Zt��.]�{�n��
9��l]a�Zu�
��1pA������7�Y�������������R<w�O��%<(�s�}��n��A9~��!���UUU����<b���z���x��@%^�� <������Jt�����O?���������4���_}��f��)0v�X�:����<g.p3���p����6l�����6m
���s�R����f``p.�7���C��@���
r<9S�W�^<^8s�������'D����]�v��zu��={t��}����+���%]!���
!_��b��Q�����K���B��UWS���Rs��A��x���x�FX����38HX��F������5
�gp��38HO�Aff�h��
�z���4���S�N��ZUU%:V@vhH�JC�X������?��a�F�Q�0S��2��������`����z�f��@��=B��n�u �+B�����z��?�<�Uw�B����$�����<��v�q/�4^��<,�5��K����E\�9 7p�D�6m$����]��x��=z&�7l�Pr����O>��o�<���X�kl��U�9�c�h��=���C�������x\#������5@�3�feffJ�W�P���$�obb IDATf������FM(�j��5kV��8�{zz������E\�9���-2�f��
�������'O�m��:d���$=��^s�x�'�p���P�n]�:���U��k�rii)��u�9�M�wT�2	???I��
���$����g��\;�c�Eyyy�(�j�����?V��R�u���9::�%��^s 88X�p��m���4s@�f�����a{�u����p�#I��9r�(��C�
T��4��EW��=x�@�9PPP�������+"##%u�0:X8��zu�0B�s@�f�UW��Y300<0��E���Rc��i��u����OQ)�Xm��6�X��s��<bo6�!))��<b!�5�X�k�#V����a���"1C�r���r���^k�����e����� �{�!�uoP����`���Ts@
O���^������+���9^N7(��m�����GW9rDR7H%Up u�^]!���
!�WW000<Z0{�a�Z�����+V�G,������������%�|����#������R�Ry�$�V+L�:US���WUUAFF�������H<!"��y���:���������ra���7��h4BZZ��Y�R����[�n���Wm{���A�W�����2HKK��������C��:����
��C��)--�k��Abb�CtEqq1\�t�n]QTT)))�t��D�qJJ��nP������+8���VW���PuErr�d������```p�A�������AAA��j���x5y�r�\�R^1�o����:�%�8<<\s1�o��Is���bZ�O?�4���+����+V�#V��c��'OE�Cxx8 "���/�������{N�UN�K�z��9~��
ve�WTT���.
D����C�-D{���A�W�7�����n��A@@�&�����=+�v�<V0`�����D�^]q��A��s���b��=�k�.�t���'����
�EW�����w�������dJ�=�����y`G\nnn�����Fq=y�j���x��B�(C�2d�h�rUU���b�y�B^k���ba1�>)��+V�G,���#V���c����3==��s�7S@h,gH��f�����e���<����������
�-{�W�7���L�^�z�x��'N����gt������\������P��+���%]!���
!_��b��Q�����K���B��UWS���Rs��A��x���x����<�^�z��xS�a���p��E�k�#����; >>^�9r$�����r�����-[������-Z�����
���0a�x��wx�277��_�O���d{����!""��=�|�
t���7Q���b���{�b�
HII��~�	:t������gee�o������p�Bh��omYYY�c��E���;���0w�\Qg���uX�z5��������M�66�b�@ZZ�,��eX�v-TTT���3y����nnn����B�V����S��Z�V��d2�� **
���u

k��!�3�7on����!11�o�M�4Q����h����/++���x��{7���K ��T000�y�Z���_�����;wB�v�`�����qc_RRqqq�o�>Y~�������BNNo�&�	����___<x04h���s����C�u���+8^���E���h�AIW��=����[W��uK����$h��	Uw��o������R�u�TR���:\��u�������������o�_u25�3R�<�b(�NI��#�����e�X3Vfou5O�S3�aR��<�Z�����Dy6��(t�������y���7������z��=�j�?~���=��I���m�Ns�o��N��R��ys���_����g�n�j�x��?��&���7��_]wW������������O5���7���~[w����������k��Mz�����^�������K�������fs����Vn7��={����^�zI�o"�����w�o��e�9���j�9g�9�u�V�1�G�V���t�0b�����#L�z�W�
���V]q��u��5��nh�u�����l]�h�[W8r3u��E�DT�� �b�a����t���6qq�v4����^���m��yS����T\�$�������7�x���M7��������%�n�wr<;�66n�h�9��W/S���"&&Fu^|NN�K�����u�8w���������__O7._�l�����s�9����u���"++�ts���_7UW���&�����r�9��7qW��������6qy�@>�I�[��+6q���(N�9sF�����������h�s"�N�g���@��M7�O�n�90u�T��K:tp�9 �R]�va���WM5


L7V�^m��X�b�f]!���|L���0[W����������B�2k"����K���#33S��A����k�.�;V�I�����HLLDdd�b�v%��q#����i���~��,�_>#�$`��uHKK�3�<��������6iW��?���������^���%8u��fn��q��Y,]�T�I�/����Oq��%�&���7a���+V�@QQ�b�V���4p��Z�f
l6�bw%�t��m��X�8���������Z��s��~�z�n�Zu�����5���|W���tl�����oU��w��w?;�y6�s��gyZZ���{<X�p%�����nHNN����E]q��Y�����;���k�
���u����+���"33S�n��T� �;����h]!���DT�� �Bv��N����c���=z����0a~���+:�zyaa!>��'Ob���x���~�����8t���;�3f 44T��w����G�����8pYYY�;w.F����8p�����������+:����w���7���!C��{���k�HNNFQQ���@A��K/):�/^DRRl6�j�_/������BRR|||T;�zyee%��?���$�y���7o�����WTT����HJJ���������j?~IIIh��f���89p��i$%%�[�nx���'����r�<y�������?�s�gff"55��?���?����_4s��D�y'N�����k�F�
z��g�����8x� BBB�89�����).���SRR�c��!==�N����b<x������iii�����+������u���"++�T]���N�ZW����u�V��Ww4����<�
/TUU���@<������s��k4w��7o���%����V�8��h�"0@������[�nU=:&>���{�)~�,��,Y���������~���]�V��	�������p.>��e�����6m�>}���Z|����K����%�Y.>�WRR�+V��}����r�k�Z��3�<���d��)..������U+�,�������X�h�$
��G�������Kr��`��?������gKr��`����D�}A�����xv��l��]y6��������S��KJJp��A�W���DEE!""B���+����c����M�6a��=n�b�=��bD���B-7RW���UW���Wq�A�����+�v�����<�wx!4H�{�M������C%���@�����}��'���j��w�����A�<&&Fq�ree���@��K����y��w���qH���@����9����=������?C���Fr��/����\|���v���V����O<��$��9��;�����������^�za����\���V^\\��n"����j�h�B��0�lP�]}6���;��|��P��o��C�IF�:��		Q����w�6UW$%%�UW�u��Q�ky������F�
y^�u���]���_��0[W�`���OIr���jzQ�c�����I.��o�f��sq�|7;�p��a�5����X������;��fp��%���.��f.w��L3��pPN��O�s!�7]:�6��������k�2���rS��:r#��			�����T^EE����
}����
�/$�����u�=���Xozz�f��
#��NI�MDu�
/$��zC���r�o��_��(6q�iZ�7l�f�_~��K����{k6|||L5Z�li�9 �	����n'"����E�.]j~-~%�Lc�ls ..�Ts`���1bF��8�w��%��
u�����U��@�kh�et��U���F(����u��=6�Xc��]u��K�F����^�z)�|��e����6n���hTVV*.���F�i<�����fG�o�&"�#%�Lc�ls�W�^��DLL�bp{�q�9�PG(����~}=��|�r��P

��;�a��|J����U�V�k'������q�F���]i����j8������-[JrA�n�:����6,X�8p�������iF��yt���Gy?oz%���iL�:U��R�\j��4��B��87�(((0�X�z���b���u��'������Z\w��+�#��i���+�.�&������Tzz:233��b����J�k�<`g��]�G���:�X/�������v�g�����KM�+6:�X��G�,�t��m��X�8���������Z�xV���Wr������Y�D����w�
�����Y��������V4\��z��������}��FQW�={V���������u���b��u��
Gn�������***�'&�;����h]!���DT�� �Bv��N���y���#����;�W,������n����]�G���:�X/�:9�5�XL���K��{�����
�={III���G�f�$k�����������v��a�����O�FRRR��r�����,���rdff�=�\�Jy�'N����5��������Y^ZZ���<x!!!���P�����������)))��c����^'uEqq1<�v]QXX���4Cu����_���l���Y]���e��p�j'\�+�x�
��B�n��;z]AD������B`` �|�I���:�X/we�^�7����bG�u�V��cF�/Y���<bq�v�Z���]�W�6�X�i�����O��==���<bg����V�Z��g�Arr���c���h������O��G���G��r3������f�������D�}A�����xv��l��]y6��������S��KJJp��A�W���DEE!""B���+����c����M�6a��=n�b�=�,�=#u�Zn��P�k����w����8W�;<]W��$�SW���/����A�I~O����W��<b�\k��y��<&&Fq�ree��y�F��s�����+��#n��bv^�����rW�;��w
�`���l���\p�) ��,�s@+ww����1wf�'%%���Xu�D�Y���h�����a������l���w
�����9��o�������b��;BBBTs�u�c���u�c����B�c���_��gu�<7ZW����+������Zu���B>B�h]!���N]���"��������\�#���L3p�� �&nv���a�k���5t��;�sw.23����K�5�]$��\$����f�u���<�<p�BBo�tLm|'y������e�����.3u�F.$T���_?�����
�	�e�+_H��!���{��G����t���F(����5���_1�B���!..)))��q�$��k��a���8p��K����%7�`��
8z�(&M���c�:�[�hQ�_�|�������y7�Y����X��7j�
�������W���S�yNN�/_����c��6l�d�v�_�x��-CNN�z�-4H�I;������G����x�����o_����[�k�3g�`��e�q��}�]����&s|��,���Oa�����o��{������X�B7���/��Y3,\�=z���'��]�4o��5�����0P�O�>����f�������_���/���dV���7k��;.�����c�Fq�{�;w�D||<����i��)
tq~��q�������*���������e�K��<((111h��]M^RR���x����i>f��i��w���9;;;v���1c)�����3f���?��+����SW���w���;���nh�u�����XgII	��Y�Zw|������e������������+��sx����7���P�M��Gu)���'N����;r�o��M���P��t7�Y�f�n�/����&���7�W^yEwW����[o����z���O�sssk6�E��n�z��n��t7i��Y�f�?��&�,�7***����������sM5��C��90m�4�d"j������8�������j!22Ru^|~~>BCCu���l]!���+���u��k{�����+rrrL�/^��+�BBB4��u��7L���L]���5�6������&�Js���Ts��&.o��.��Y���������%����'Nh�?���}w�����qcD������^�z�nL�6�Ts &&F���C�N�\j���TW���:����j����n,_��T]�l�2��B>�@>�R\w��+-Zd�9 ���+��� �����:|�0���T7q���Gjj��&�J�y�f9rDu�v%��a2224��w�WUUI~-����/����`�����+��%K47iWs��?������
EEE�M��^�'�|������M�]D~��g���Z.�����+X�j��&�J������x��T�����6���]|��7�����gffb�����+��#G�u�V�o���D����w�
�����Y�o�>���C�9�J.��{wE��{��FSW���a����u�����/�4UW8r3u�����A��c@Zw��+����B���+��~�L�r���0a~�aE�������_���G+:�zyAA������\L�6
>������_�|III�v��~�i+:���~�As�yyy��gO����
St�������J���K<x����s�N����/^{�50@�����]��N����E��7o����&M���^Pt���;��m����/�l(w\�s�Nt��	O<������WVV������{7���L�:U����m6�?���Dt������d����HOOGbb"����I�&)Nddd %%DTT����^^VV�c��a��}>|8"""?�s�>|iii

Exx���G�����T������p����g��g�^����,/))��C�p��1�����GQ���KKKM�f�������������'O�I]q��5$''�]W`��=��
�tYY�n�����q��������p��x���T�����k6�����^W�g�A�������o_���H~_|���������
���}���SL�����.\�Y$>������W�������������>R��D|����?���/_��	�����+���}�y�r~~~���W�����n���/��B������}>>>���O���������
�������%���_|����o*����o���1o�<I.>��;��2�>��$
���l����PL�>]���k���_yA����b����g������g�^.~m <<\1J�Y^TT����+���Z��I�0n�8En����q#RSS��+6l��#G��UW�=��S�����j���B-���������r��O�v��T]AD��W����/���/�=�&����b����\�n�V�x�O<�P���;�
�o��w����hE'���B�n`�N�$���A��F����r�8#@�n��\~����@���k��f(W�S�H.�O^�����1c��:���UsGs�q���)S$������^pdd�$��7������>��$��7���������<���:tP<;�<�rW�
z��N�7��;����8�����Mw����������������G��UW��_���
��
yn�����YW<��c��^�~]��0[W�`��p�f����
����~�A�����$#�����[� IDAT��i�\$���^H(����~��srr],���A������L3���V�p�� yn�� q���4���6m���'�����.���;T�MD���IL�:�V/3-++3u��#7r!�Z����A�)��������P�<0[W<�������'�+�v���l�BBo�Y^Wt��U��C�i�f��3g���+jcJRYY�b�DT?� �r
}W���F:���7�M\k���������m�]��is���^�����������c�|`�F����[s�D�9>>>���_I2�X4����7���kBCC�Xsvv�K���:B���X�f���������\�����f�$i��@Du�
/�6qWG4�M\����S����\����6�5k�hTTT(.���F�i��=�ts���C??^�B����$�i,�m����Ts ((���������]j4��Z7�{�9���S�#��BBB4�o�,��d��P�����^�����bw�9���
�9�l�7�kk����M�ls`�����'N��<5���O30������48����y�+I��Ls &&F1���S�N.5��J]!���1����3�X�|���b��e�u� �_�m�V�kq�a����Pv�9 �f`��P�W���^�����f^�Z.�qY~����bW�k���#���:��y�jyUU�����G,���#��F�;�����y<0;;�����%�g����w%7:�\���eND�I��p�� ��>�������;T���b��wW�
�w�n4u����_�[78�+���KSu�#7SW���h�
Z�&�u���B��+���������z!������:�W��<b�\m��y����~�\����]�G���:�X/�:9�5�X�I�&x���#��y�6�
��Gbb"�w��_~�E����j���#11}����I�'222���R3�\~r@/7;�����v{����
"�?����9S��0�l���=��%%%8t��;���0<��#��zyii���.�����iii8y�d����]Crr��uEAA���c��Pk@�����
���7n��+���W���^{M����}�f�]��h�uy^���
}��ELL���]�G���2�X/��G�l^�#��w���1#��?��#��������
�#vu^��<b9???��������W�l��\��@@@�ql��]�g
��_   o�����;�����[1�\|4X+73���o����Y�����~�:�����o��C�U<;\}6h��<�r�k������6�a�����8w�V0i�$�7N���+6n����T���
6���#n�bO=�(�=#u�Zn��P�k��8~�����8W�;<]W��$�SW���/�������K~O����W��<b�\k��y��<::Z�	���04���<bynt��y��y����{Z��+vu�V��<bg��N�3f��3;;[5w4w
�g�������e.�t��Y�;w�DII�����������C�����A-w��������-�s@-�����?���t��9����+#���+#���r�W6�u���B��+�ym��=��b���_��;����F�
��$w����
����~�A�������u��_�7q3���8H���ux���+����c�b!w.��\df�Avv�b��{�s3�;�f�h]8(��iSE.>y�����t��w���n"��&M�`����z�iYY���L��	����4H�>|EE����
}���nW|��^H��!����]�*�{��!���F(���TVV�X3�6�\C���r�������b��f�u��7l�f�k��u��{��W�9���o�9�v��;���������\;y��������W��4�6���M5v�����P���(�����Rs���P...V����5��2*//��;�a���)IZw.Q��^������q#>���0�?^2���+5��FFFb���Ns�&�������
g���c�=���G��;�����tNNV�^���l<��S1b�����r��]�"$$D�<�x�">��s\�rs��EPP�$������KQRR�?��O4h�d���������a���h�"�w�}�M�Y~��Y��o��/�o�[��������������ys���[���gMV]]�'N�������������G�����*����������:t���s��[��������5k\�_x��7�6�M���;7o����n�:t���f�R�t/99�6mB���1c�I��,/--��]��u�V8S�NU�z�;������*��D�]����7��l�f��

����%����B|�����w/F�����|���8z��b�����={6���%����
y�N]!���+���u���sguC]�YYY��?��v]q����w���
�Q�F)����l]��ys,\����B-7ZW���"���^����f;v,���57�	&�n�j�x�v�J������M����m���y��[����g�����?������Z.��_~�e�M\+w|��p�B������A�r�J4o�,�����f�w�u������s?������4�16����w?;�6h�9c�9�x��!  @�9��+���^W�����K�u���������
Gn��������I9�1����l]�`��6����z��6�TZZ<�������c���n������p��i�M������7���T7qWr�O��G�V�\���/�n��l�2�n���|���&�j�o��x�b�����|�n����>P���r��M%%%X�t��&���7i�����+W�n����������<������X���>}�fZ���W���qqq��+���ug�;���;���<���g��<%%�����Wr��]�*��;v4��B�4bll�n����X�r�������+l6�f�`���'&�;����h]�v�������_1�BUUU���CLL|�AE�����|�2�M����`E�_/�����;PZZ����#((H����srr��������g����Wt����|����/^��m���y���;w.
���o��
����>}:���������9����@E���.�S�LQ=9�q�F����U��4i�g�yF��?u����p�}�a�������*?~��m��������������;0l�0DFF*:�z���7q��1$&&b��8u��d�v�@bb"F�����+N9r�������1n�8������������0�O������Czz:����zH�����T�\��,"�iii8w�\�����A/w�lp�b��}8~�8"##�89�����(Nl����W�"99.\������+HHHp�������m��j
�f����
������c���n��\�d��uEtt�j]�i�&�����
�� "�`����v����������x���3��;�������i��Z��x�����>}�Hr��?�<33Su��{�����8�����m[I.>��,_�d��'������}�y�r~~~�MT|��E��y��r����m�����7����u��
/����\��@`` &N��M�6I�Laa!V�Z���@��3G��G����~Z���k����!!!x���%��h��<,,�'O�����Z9�y'A�i�&���*�F�
j�+��\��@dd$"""��o��^��V0e����)r�u�#w��p���bS�L��$�g��P���jym�yyy�<����+���L�D�9|������_�~��o�&L���%���@�������Z@�n�V�x7P������������&y7�c���\����h���@g���b@�n��\~�����7�� ����_6����{���
��w�f��i8�)0m�4�ufee������N���hI.�s@+w�<a�I.oX/

���c%���a����Tu�D�Y���������a������l���w
<����\~��Z�q�F�:uJq�P�90|�p��l]���a��8s��[u����y������F�
y^�u���]��4
���l]Q]]m��p�f�
��(����A�����$�����������������	��������\,���A������rys@�x��k��8H���8H��73�@��A�-Z(r��w.$��K��S��{4i�111�z�iii���L��	����c������f���P�<0[WL�0�T]m��P;1a�BBo�Y^W��l:��������l]q��	SuEmLI*++S����^��o�j�x^�Ceee��������M�ls`��5N���gO��@���M5�.s�37��o�&"����#�o_�J��������]�L5�����c�"88X�������;v���b��������G�+���kvhl��Q�Zu����6F(���$��������b�a����&.�{���XsVV�Wl�f�:tP4l6���>��^m������3L7��:T;�KD�E�J������@PP�����Q�����\i4������__O7����t��Xpp�f��
#��S������DT�� �R����b��A���u��
�9�l�7��A�r�J����6����8����yi�Zs@>��hs�6�����C"��M�$9r3�����{�.5��J]���K�.�j\�x�ts`������?��z]Q]]-�������0[W�G(���O30ZWhMm �����JKKk4���r�O���:�W��<b���y�z9����#V��<�3�X��G,���#v�ggg#>>^u�#����|-A<�\���+��Y����,s"�N�g�;�yn���,OIIArr�js��\�k����a�����P;��[78�+V�\i��p�f�
���Y7�l6������u�<7ZW�s�u�/���BUUU�����y���#����;�W,�������:���y�Z�����r��a@�X�&M��3��G����o���c��!11��S�$k���8p�1r�H�?^qr���#����r�����,���R�����Y���y���4�;w���a����;{68��o�>?~���

U���KJJ'����c������r�
��+����m�6Cu�Z�Y�f�u����y���?��u�#W;�j]�ZWl��I�'�zuGC�+��3� �Bv��������%�od�V��<b�\o��y��<33Su�32���y����y���+�������$����;�G�,�6��'b��M�?SXX�U�V!00s��Q�}���!C�(f���k�ff��swf�������D�}A��M��xvy6���<�r�k������0�;���z�K�Z��)S�����������SW�M�2E1%�H]���+����+���'�9��;<]W��$�SW���/����~��I~O����W��<b�\k��y��<::Z����l���G,���#62�X>���
����]�G���2��Y.�S`��i�����R�����y��;�rwg��/sg�y||<JKKU�MD�U]]�=z(�F�
j����\|���>(��w��7n��S�T/I��90|�p��l]���n]��l�����"�����h]!�k�����EEE�u���B>B�h]!���N]QQQ�X3�6�������V�&nf��;�7q���~��Fm�b!w.��\df���k��8H���8H��73�@��A�-Z(r��w.$��K�Z�h��n"��&M� &&�V/3---5u��#7r!�Z~��a:T� ��l�6��j'&�^H��!�����;+����V���o�lvJRYY�b�DT?� �r
}W��6m�Xgeee��������M�ls`��5N���gO��@���M5�.s�37��o�&"����#�o_�J��������]�L5�����c�"88X�������h�#����kvhl��Q�Zu�7�P6;%I~�#������&���4�M\����C����,����6:t��h�l6��}�����C3��3f�n�u�v�������$3�E����� S��Q�F!<<\1
�]?��h�#�+++U���ndee��e���`���F(��$�+�'i��~���R���HMM�/������#,,L�	���!66���+���0f��&�,�����U�����i��a����MX/���������b<���

��?�,A����[K6�.`��%����s�=���KN�;w~�!|}}kn_|�,?s��{�=�l����*z��-�����w�A�v���?�Y1�����x��wk��^zI����K�����7o�d�t�6���K�.N����K�9�����#G�����g��x���t���^r|�f�!55�W�F`` f��e(///Gzz���Y���HII����1`�L�>]����7�k�.l��C����S��}{����l��			1bbbb$G9����������"22Rr:�YND�I��9r��g�<�<y��g��\��wg����{w���&L����~���������W�9;;k������.\����w��
G����v]��{��U�V�uEuu����}G\w���+��
yn�������7oyOx���Tddd <<\������q��YDFF*6iW�u��!77�'OVl���k��AQQ�x�	�&�J.��Q~i����/�l6<����M>��#�����g�Ul�����_��eK��7O�I��k5������+++��M�&�n�������I���c�������OT7i�\�nc~~>����M���������<x������6���]l��Q��W��~�	�����+yjj*5��w��w?;�y6�s��g��={p��A�o���b��!>>������ok^�r�n��������e��p�f���-[j�
6�M�{b���l]!�����l]AD��'�PUU�]��'�|��
St��m����2��1C�Qt���������I�&�9s&
����������eZ�j������_��w��^�Zu�1p�������;wFXX��������w���~����O�>��7�|�4:t(���q���*:�_��Kydd�������
�G�FDD��&��T1s�LE?33�~�-z�!�?�P^YY�c������/y�<�����^n��p��$$$`��qSt�����r:t���5j~��W���v;������������C=�89��������T~r@//))���{������(�5J��?g����q����V�����D�\�Jy����;w���a����;{68��^��]�v��_���S��(N��EEE�#��}���+HHH@~~~��yyy��e��uENN6n�h��P�!:u�������Y]��sg�7�������p��W�+bccU�C;r�����D�lx!����w��������f���x�p�8���/(F���i���}����������999������E�hq�������2������/�����'�O/���.\h8��7o�b}b�������x_�n���s�I���\|��w���5k��\|�o����>}��\��@PP����X��)((��5k��S�*������Q�0i�$I.>��;��������$
��w���	&`����\|4X+��4��<Gl�����S<;\}6h��<�r�k111x��G�W�\����5���
�x�	�3F���+bccq��y���U�V!??���Bl�����F�
��H]���V]a��$�a�s����uEee�����<�� �<�W�^=z��b���2���O(**B`` z��!����q��s��_�~�����b���R=z7n�p�4�o�KJJp��a��u�i��gO��������k�b���h���v;���~t��IrD���iii5y���%���"���>>>6l��o����%"%%��5�<�8Z�,�z�*�����E�9Rq�366o���~�i��1i�$�k�� ������?Z�n�x���jIDAT�[��������j������C���GPP���C�r����/"==�����!C$���_�p������b��������%K���w���!C0x�`�O�*++������Lt�����������q��I�y��]��_?I�e��p��Y�={�i��GJ����u�N�BVV����<))	+W�T�WMD�s��w������%�#����g�^��/� 77={�D���%?9///��'t����;w���o���?��}l����������+W��w�����������2dff����T]QTT�����k]�r�J�\����p�5�W_}U����
��
yn�����YWt����_Gbb"��7�@BB*++U��u� ���q������~�)~��������^h����v���?F�j��,X��{�[�l��'�{'N�������p��
��%��FZZ���=�����)Sp�}�y�c��{��������s��5?��w/v����OT��|�������g?L=���G�v������~�z0{�l�}DT��  """""""N1 """""""6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""~���97o�Dqq1JJJPVV�;���[�F�6mp�wx������B�}����D�qO%+�~J�x�A`1iiiX�z5v����g���6�>�(���0t��z���!//�;w���0���[�������S�N�W�^7n^z�%4k�L�g?��3�������+����~��a��1���+++CRRn�����`t��U���7�����Q\\���������w�l��C������i��)`�=��)��7ns���M�4^x������^B���G0��_��u���������;v�]��aC��kh~��!  ������	/���PYY)� ���������\�t��+ ���{�1
m?����O���� B���EGG�����5kBBB��cG�o���5����4i�����7n ??999��{7bcc1n�8�Z�����W���HKK���p�#�<��;w�{��3f:w���/"))	���h��-0l�0��+..F�6m
�q`���s��)�3f��/����������wG�����}{\�~G�����M�6y��QC�=�������S����g�T���(�f�����]�&�9RHOO��O���������{�c�l����>���;TVV
6l:v�(�u�]�����7�O;����k�����~+\�tI�v���s�Na��9B����o��Vh����y�f�n�K���nV�Z%�q���#G<�"j������SA��������x�����?b��Ep��q�������7���OVw�{�=�;��  ??6�
������������e��i������3iii��?z��	��l��o~����^y�DDD�������	&���>�3�<�����������s�����JD����T������T��D$�K
-����T!}��Elll-}����#���w�AEE����v����'�['O��SO=��g��o�-[���O>Axx8RRR��}�z���/77#G�T�BCC1x�`�����3����~����xD�HYmO��~
XoO�~JDblX���?2220p�@���w����7AAAx��g1t�P������ ���3�5kV}����kW�u�].���^z	]�tADD�m��;����?]����;.\��>}���}���yTKII	�t�R��)���V�O����O�H�
�6m�ql��
��u3��>��_~IIIu������S��3g��}��u�+O1b�o�������^yy9Z�h���'M����������_]_�V��� 11�{����+��}{L�8�&���T���J4m��s�N�;��>35|V�S�����S���0x�`DEE�o���8q"�����cG�k���5���o���UUU(--E~~>rss�g�������?�p������������6���X�f
:������DZZ���{������1c�4��#""___<������00z�h��y��'�a������9s&���������&����{���S�z{*�S"�����T�����U�V	m��54��}����
<����p�B�����+k������\a�������k�~���������%����A���p��!,,Lh�����m[���@����qC���]�v�������z��D�XXqO��~*��S����X��[���������������_Gyy9���N�u�]h��
��~QQQh����?6�H�������{a�����o�c��N�^aa!�x�
|�����)k_aa!Z�l�f�����W_}�������_�z��D�qOm����r?%"6�������>��DDDDDDD�ylXLee%RSSq��O�zc�5[m��5�LD�g�g���Xo�V[/)�A`!�/���?BBB��gO0'N�����SV[���Xs�D�yV{�Xm����l���O��H���g�U�Q���_8v���?^������^A�����������z�zk��z�H/)��`������'�����KTVV���C��u+BCC������Y���f�������������z���j�%"}lX��	��uk������O��:u
!!!���1l�0}��g�5[m��5�LD�g�g���Xo�V[/��}��w����������#..-[�Td������
���jk��zk���<�j��������^"��K
���"t��m����3aaa8~�x=~��e�5[m��5�LD�g�g���Xo�V[/9�A#WXX�:���N�:�����>Q������^��k&"�����j���f�����c���6m��7k���?���>���S/��f�������������z���j�%"}l�K���KO�zg�5[m��5�LD�g�g���Xo�V[/Qc���=VUU����Z�4��jk��zk���<�j��������^"�����PC�g�<��C���W�m6�=���PE&._����������jk��zk���<�j��������^"���TUU!11����|��f��]�Z�Du�jk��zk���<�j��������^"������`���h�����+rrr���Z���Xm�V[/`�5��Y��c���[���KD�� ��x6l0������j������j���f"�<�={��^�zk��z�H/)�������g�u�]��I����l���\3y���=V[/`�5[m�D����w�y����N�����Ot����?�g�����W-}��e�5[m��5�LD�g�g���Xo�V[/9�D����������<��DDDDDDD��
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD`�����������
"""""""DDDDDDD6�������l�  """""""�A@DDDDDDD�?��$.:�IEND�B`�
0001-Make-multi-batch-Parallel-Hash-Full-Join-fairer.patchtext/x-patch; charset=US-ASCII; name=0001-Make-multi-batch-Parallel-Hash-Full-Join-fairer.patchDownload
From da98217b98a04b3f84512a6bf267b3cd107e39d7 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 29 Mar 2023 17:20:13 +1300
Subject: [PATCH] Make multi-batch Parallel Hash Full Join fairer.

The initial commit of Parallel Hash Full Join never allowed more than
one process to scan a hashtable for unmatched inner tuples.  Relax that
for multi-batch joins, so that work is more evenly distributed.  An
atomic variable hands out ranges of buckets to scan within each process.

We currently don't see a reasonable deadlock-free way to allow that for
single-batch joins (it seems to require major executor changes).  For
multi-batch joinsing ones, we still have to drop down to one process at
the end of the probe of each batch, but processes can safely join any
existing unmatched scan that has already started in another batch, if it
can find one.

Suggested-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
---
 src/backend/executor/nodeHash.c     | 36 +++++++++++++++++++++--------
 src/backend/executor/nodeHashjoin.c | 35 +++++++++++++++++++---------
 src/include/executor/hashjoin.h     |  1 +
 src/include/nodes/execnodes.h       |  2 ++
 4 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index a45bd3a315..83d33fd618 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -2067,14 +2067,13 @@ ExecPrepHashTableForUnmatched(HashJoinState *hjstate)
 	 *----------
 	 */
 	hjstate->hj_CurBucketNo = 0;
+	hjstate->hj_MaxBucketNo = 0;			/* for parallel scan */
 	hjstate->hj_CurSkewBucketNo = 0;
 	hjstate->hj_CurTuple = NULL;
 }
 
 /*
- * Decide if this process is allowed to run the unmatched scan.  If so, the
- * batch barrier is advanced to PHJ_BATCH_SCAN and true is returned.
- * Otherwise the batch is detached and false is returned.
+ * Decide if this process is allowed to run the unmatched scan.
  */
 bool
 ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
@@ -2083,17 +2082,20 @@ ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
 	int			curbatch = hashtable->curbatch;
 	ParallelHashJoinBatch *batch = hashtable->batches[curbatch].shared;
 
-	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE);
+	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE ||
+		   BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
 
 	/*
-	 * It would not be deadlock-free to wait on the batch barrier, because it
+	 * It would not be deadlock-free to wait on the batch barrier when it
 	 * is in PHJ_BATCH_PROBE phase, and thus processes attached to it have
 	 * already emitted tuples.  Therefore, we'll hold a wait-free election:
 	 * only one process can continue to the next phase, and all others detach
 	 * from this batch.  They can still go any work on other batches, if there
-	 * are any.
+	 * are any.  If we got here when it's already in PHJ_BATCH_SCAN phase,
+	 * we can proceed without further ado.
 	 */
-	if (!BarrierArriveAndDetachExceptLast(&batch->batch_barrier))
+	if (BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_PROBE &&
+		!BarrierArriveAndDetachExceptLast(&batch->batch_barrier))
 	{
 		/* This process considers the batch to be done. */
 		hashtable->batches[hashtable->curbatch].done = true;
@@ -2113,9 +2115,7 @@ ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate)
 		return false;
 	}
 
-	/* Now we are alone with this batch. */
 	Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
-	Assert(BarrierParticipants(&batch->batch_barrier) == 1);
 
 	/*
 	 * Has another process decided to give up early and command all processes
@@ -2232,9 +2232,24 @@ ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
 		 */
 		if (hashTuple != NULL)
 			hashTuple = ExecParallelHashNextTuple(hashtable, hashTuple);
-		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		else if (hjstate->hj_CurBucketNo < hjstate->hj_MaxBucketNo)
 			hashTuple = ExecParallelHashFirstTuple(hashtable,
 												   hjstate->hj_CurBucketNo++);
+		else if (hjstate->hj_CurBucketNo < hashtable->nbuckets)
+		{
+			/*
+			 * Allocate a few cachelines' worth of buckets, and loop around.
+			 * Testing shows that 8 is a good multiplier.
+			 */
+			size_t step = (PG_CACHE_LINE_SIZE * 8) / sizeof(dsa_pointer_atomic);
+			ParallelHashJoinBatch *batch;
+
+			batch = hashtable->batches[hashtable->curbatch].shared;
+			hjstate->hj_CurBucketNo =
+				pg_atomic_fetch_add_u32(&batch->bucket, step);
+			hjstate->hj_MaxBucketNo =
+				Min(hjstate->hj_CurBucketNo + step, hashtable->nbuckets);
+		}
 		else
 			break;				/* finished all buckets */
 
@@ -3113,6 +3128,7 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch)
 		 * up the Barrier.
 		 */
 		BarrierInit(&shared->batch_barrier, 0);
+		pg_atomic_init_u32(&shared->bucket, 0);
 		if (i == 0)
 		{
 			/* Batch 0 doesn't need to be loaded. */
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 52ed05c6f5..1f5a10bfbc 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -597,6 +597,20 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel)
 				{
 					if (!ExecParallelHashJoinNewBatch(node))
 						return NULL;	/* end of parallel-aware join */
+
+					/*
+					 * If we've attached to a batch that is already in the
+					 * inner scan phase, we'll help with that.
+					 */
+					if (BarrierPhase(&hashtable->batches[hashtable->curbatch].shared->batch_barrier) == PHJ_BATCH_SCAN)
+					{
+						if (HJ_FILL_INNER(node))
+							node->hj_JoinState = HJ_FILL_INNER_TUPLES;
+						else
+							node->hj_JoinState = HJ_NEED_NEW_BATCH;
+						break;
+					}
+					Assert(BarrierPhase(&hashtable->batches[hashtable->curbatch].shared->batch_barrier) == PHJ_BATCH_PROBE);
 				}
 				else
 				{
@@ -1216,20 +1230,19 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate)
 				case PHJ_BATCH_SCAN:
 
 					/*
-					 * In principle, we could help scan for unmatched tuples,
-					 * since that phase is already underway (the thing we
-					 * can't do under current deadlock-avoidance rules is wait
-					 * for others to arrive at PHJ_BATCH_SCAN, because
-					 * PHJ_BATCH_PROBE emits tuples, but in this case we just
-					 * got here without waiting).  That is not yet done.  For
-					 * now, we just detach and go around again.  We have to
-					 * use ExecHashTableDetachBatch() because there's a small
-					 * chance we'll be the last to detach, and then we're
-					 * responsible for freeing memory.
+					 * Join in with inner scan, if we have not been asked to
+					 * skip it by another process.
 					 */
 					ExecParallelHashTableSetCurrentBatch(hashtable, batchno);
+					if (ExecParallelPrepHashTableForUnmatched(hjstate))
+						return true;
+
+					/*
+					 * Otherwise, we've been detached and we need to go around
+					 * again.
+					 */
 					hashtable->batches[batchno].done = true;
-					ExecHashTableDetachBatch(hashtable);
+					hashtable->curbatch = -1;
 					break;
 
 				case PHJ_BATCH_FREE:
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 8ee59d2c71..44cb85a89a 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -160,6 +160,7 @@ typedef struct ParallelHashJoinBatch
 	size_t		old_ntuples;	/* number of tuples before repartitioning */
 	bool		space_exhausted;
 	bool		skip_unmatched; /* whether to abandon unmatched scan */
+	pg_atomic_uint32 bucket;	/* cursor for unmatched inner scan */
 
 	/*
 	 * Variable-sized SharedTuplestore objects follow this struct in memory.
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index d97f5a8e7d..2529d7a4a6 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2066,6 +2066,7 @@ typedef struct MergeJoinState
  *								(NULL if table not built yet)
  *		hj_CurHashValue			hash value for current outer tuple
  *		hj_CurBucketNo			regular bucket# for current outer tuple
+ *		hj_MaxBucketNo			bucket range allocated to parallel process
  *		hj_CurSkewBucketNo		skew bucket# for current outer tuple
  *		hj_CurTuple				last inner tuple matched to current outer
  *								tuple, or NULL if starting search
@@ -2096,6 +2097,7 @@ typedef struct HashJoinState
 	HashJoinTable hj_HashTable;
 	uint32		hj_CurHashValue;
 	int			hj_CurBucketNo;
+	int			hj_MaxBucketNo;
 	int			hj_CurSkewBucketNo;
 	HashJoinTuple hj_CurTuple;
 	TupleTableSlot *hj_OuterTupleSlot;
-- 
2.40.0

#34Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#33)
Re: Parallel Full Hash Join

Thomas Munro <thomas.munro@gmail.com> writes:

I committed the main patch.

This left the following code in hash_inner_and_outer (joinpath.c):

/*
* If the joinrel is parallel-safe, we may be able to consider a
* partial hash join. However, we can't handle JOIN_UNIQUE_OUTER,
* because the outer path will be partial, and therefore we won't be
* able to properly guarantee uniqueness. Similarly, we can't handle
* JOIN_FULL and JOIN_RIGHT, because they can produce false null
* extended rows. Also, the resulting path must not be parameterized.
*/
if (joinrel->consider_parallel &&
save_jointype != JOIN_UNIQUE_OUTER &&
outerrel->partial_pathlist != NIL &&
bms_is_empty(joinrel->lateral_relids))
{

The comment is no longer in sync with the code: this if-test used to
reject JOIN_FULL and JOIN_RIGHT, and no longer does so, but the comment
still claims it should. Shouldn't we drop the sentence beginning
"Similarly"? (I see that there's now one sub-section that still rejects
such cases, but it no longer seems correct to claim that they're rejected
overall.)

regards, tom lane

#35Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#34)
Re: Parallel Full Hash Join

On Wed, Apr 5, 2023 at 7:37 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

The comment is no longer in sync with the code: this if-test used to
reject JOIN_FULL and JOIN_RIGHT, and no longer does so, but the comment
still claims it should. Shouldn't we drop the sentence beginning
"Similarly"? (I see that there's now one sub-section that still rejects
such cases, but it no longer seems correct to claim that they're rejected
overall.)

Yeah, thanks. Done.

#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#33)
Re: Parallel Full Hash Join

Thomas Munro <thomas.munro@gmail.com> writes:

I committed the main patch.

BTW, it was easy to miss in all the buildfarm noise from
last-possible-minute patches, but chimaera just showed something
that looks like a bug in this code [1]https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=chimaera&amp;dt=2023-04-08%2012%3A07%3A08:

2023-04-08 12:25:28.709 UTC [18027:321] pg_regress/join_hash LOG: statement: savepoint settings;
2023-04-08 12:25:28.709 UTC [18027:322] pg_regress/join_hash LOG: statement: set local max_parallel_workers_per_gather = 2;
2023-04-08 12:25:28.710 UTC [18027:323] pg_regress/join_hash LOG: statement: explain (costs off)
select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
2023-04-08 12:25:28.710 UTC [18027:324] pg_regress/join_hash LOG: statement: select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
TRAP: failed Assert("BarrierParticipants(&batch->batch_barrier) == 1"), File: "nodeHash.c", Line: 2118, PID: 19147
postgres: parallel worker for PID 18027 (ExceptionalCondition+0x84)[0x10ae2bfa4]
postgres: parallel worker for PID 18027 (ExecParallelPrepHashTableForUnmatched+0x224)[0x10aa67544]
postgres: parallel worker for PID 18027 (+0x3db868)[0x10aa6b868]
postgres: parallel worker for PID 18027 (+0x3c4204)[0x10aa54204]
postgres: parallel worker for PID 18027 (+0x3c81b8)[0x10aa581b8]
postgres: parallel worker for PID 18027 (+0x3b3d28)[0x10aa43d28]
postgres: parallel worker for PID 18027 (standard_ExecutorRun+0x208)[0x10aa39768]
postgres: parallel worker for PID 18027 (ParallelQueryMain+0x2bc)[0x10aa4092c]
postgres: parallel worker for PID 18027 (ParallelWorkerMain+0x660)[0x10a874870]
postgres: parallel worker for PID 18027 (StartBackgroundWorker+0x2a8)[0x10ab8abf8]
postgres: parallel worker for PID 18027 (+0x50290c)[0x10ab9290c]
postgres: parallel worker for PID 18027 (+0x5035e4)[0x10ab935e4]
postgres: parallel worker for PID 18027 (PostmasterMain+0x1304)[0x10ab96334]
postgres: parallel worker for PID 18027 (main+0x86c)[0x10a79daec]

regards, tom lane

[1]: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=chimaera&amp;dt=2023-04-08%2012%3A07%3A08

#37Melanie Plageman
melanieplageman@gmail.com
In reply to: Tom Lane (#36)
Re: Parallel Full Hash Join

On Sat, Apr 8, 2023 at 12:33 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I committed the main patch.

BTW, it was easy to miss in all the buildfarm noise from
last-possible-minute patches, but chimaera just showed something
that looks like a bug in this code [1]:

2023-04-08 12:25:28.709 UTC [18027:321] pg_regress/join_hash LOG: statement: savepoint settings;
2023-04-08 12:25:28.709 UTC [18027:322] pg_regress/join_hash LOG: statement: set local max_parallel_workers_per_gather = 2;
2023-04-08 12:25:28.710 UTC [18027:323] pg_regress/join_hash LOG: statement: explain (costs off)
select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
2023-04-08 12:25:28.710 UTC [18027:324] pg_regress/join_hash LOG: statement: select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
TRAP: failed Assert("BarrierParticipants(&batch->batch_barrier) == 1"), File: "nodeHash.c", Line: 2118, PID: 19147
postgres: parallel worker for PID 18027 (ExceptionalCondition+0x84)[0x10ae2bfa4]
postgres: parallel worker for PID 18027 (ExecParallelPrepHashTableForUnmatched+0x224)[0x10aa67544]
postgres: parallel worker for PID 18027 (+0x3db868)[0x10aa6b868]
postgres: parallel worker for PID 18027 (+0x3c4204)[0x10aa54204]
postgres: parallel worker for PID 18027 (+0x3c81b8)[0x10aa581b8]
postgres: parallel worker for PID 18027 (+0x3b3d28)[0x10aa43d28]
postgres: parallel worker for PID 18027 (standard_ExecutorRun+0x208)[0x10aa39768]
postgres: parallel worker for PID 18027 (ParallelQueryMain+0x2bc)[0x10aa4092c]
postgres: parallel worker for PID 18027 (ParallelWorkerMain+0x660)[0x10a874870]
postgres: parallel worker for PID 18027 (StartBackgroundWorker+0x2a8)[0x10ab8abf8]
postgres: parallel worker for PID 18027 (+0x50290c)[0x10ab9290c]
postgres: parallel worker for PID 18027 (+0x5035e4)[0x10ab935e4]
postgres: parallel worker for PID 18027 (PostmasterMain+0x1304)[0x10ab96334]
postgres: parallel worker for PID 18027 (main+0x86c)[0x10a79daec]

Having not done much debugging on buildfarm animals before, I don't
suppose there is any way to get access to the core itself? I'd like to
see how many participants the batch barrier had at the time of the
assertion failure. I assume it was 2, but I just wanted to make sure I
understand the race.

- Melanie

#38Tom Lane
tgl@sss.pgh.pa.us
In reply to: Melanie Plageman (#37)
Re: Parallel Full Hash Join

Melanie Plageman <melanieplageman@gmail.com> writes:

Having not done much debugging on buildfarm animals before, I don't
suppose there is any way to get access to the core itself? I'd like to
see how many participants the batch barrier had at the time of the
assertion failure. I assume it was 2, but I just wanted to make sure I
understand the race.

I don't know about chimaera in particular, but buildfarm animals are
not typically configured to save any build products. They'd run out
of disk space after awhile :-(.

If you think the number of participants would be useful data, I'd
suggest replacing that Assert with an elog() that prints what you
want to know.

regards, tom lane

#39Melanie Plageman
melanieplageman@gmail.com
In reply to: Tom Lane (#38)
Re: Parallel Full Hash Join

On Sat, Apr 8, 2023 at 1:30 PM Melanie Plageman
<melanieplageman@gmail.com> wrote:

On Sat, Apr 8, 2023 at 12:33 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I committed the main patch.

BTW, it was easy to miss in all the buildfarm noise from
last-possible-minute patches, but chimaera just showed something
that looks like a bug in this code [1]:

2023-04-08 12:25:28.709 UTC [18027:321] pg_regress/join_hash LOG: statement: savepoint settings;
2023-04-08 12:25:28.709 UTC [18027:322] pg_regress/join_hash LOG: statement: set local max_parallel_workers_per_gather = 2;
2023-04-08 12:25:28.710 UTC [18027:323] pg_regress/join_hash LOG: statement: explain (costs off)
select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
2023-04-08 12:25:28.710 UTC [18027:324] pg_regress/join_hash LOG: statement: select count(*) from simple r full outer join simple s on (r.id = 0 - s.id);
TRAP: failed Assert("BarrierParticipants(&batch->batch_barrier) == 1"), File: "nodeHash.c", Line: 2118, PID: 19147

So, after staring at this for awhile, I suspect this assertion is just
plain wrong. BarrierArriveAndDetachExceptLast() contains this code:

if (barrier->participants > 1)
{
--barrier->participants;
SpinLockRelease(&barrier->mutex);

return false;
}
Assert(barrier->participants == 1);

So in between this assertion and the one we tripped,

if (!BarrierArriveAndDetachExceptLast(&batch->batch_barrier))
{
...
return false;
}

/* Now we are alone with this batch. */
Assert(BarrierPhase(&batch->batch_barrier) == PHJ_BATCH_SCAN);
Assert(BarrierParticipants(&batch->batch_barrier) == 1);

Another worker attached to the batch barrier, saw that it was in
PHJ_BATCH_SCAN, marked it done and detached. This is fine.
BarrierArriveAndDetachExceptLast() is meant to ensure no one waits
(deadlock hazard) and that at least one worker stays to do the unmatched
scan. It doesn't hurt anything for another worker to join and find out
there is no work to do.

We should simply delete this assertion.

- Melanie

#40Michael Paquier
michael@paquier.xyz
In reply to: Melanie Plageman (#39)
Re: Parallel Full Hash Join

On Sat, Apr 08, 2023 at 02:19:54PM -0400, Melanie Plageman wrote:

Another worker attached to the batch barrier, saw that it was in
PHJ_BATCH_SCAN, marked it done and detached. This is fine.
BarrierArriveAndDetachExceptLast() is meant to ensure no one waits
(deadlock hazard) and that at least one worker stays to do the unmatched
scan. It doesn't hurt anything for another worker to join and find out
there is no work to do.

We should simply delete this assertion.

I have added an open item about that. This had better be tracked.
--
Michael

#41Thomas Munro
thomas.munro@gmail.com
In reply to: Michael Paquier (#40)
Re: Parallel Full Hash Join

On Mon, Apr 10, 2023 at 11:33 AM Michael Paquier <michael@paquier.xyz> wrote:

On Sat, Apr 08, 2023 at 02:19:54PM -0400, Melanie Plageman wrote:

Another worker attached to the batch barrier, saw that it was in
PHJ_BATCH_SCAN, marked it done and detached. This is fine.
BarrierArriveAndDetachExceptLast() is meant to ensure no one waits
(deadlock hazard) and that at least one worker stays to do the unmatched
scan. It doesn't hurt anything for another worker to join and find out
there is no work to do.

We should simply delete this assertion.

Agreed, and pushed. Thanks!

I have added an open item about that. This had better be tracked.

Thanks, will update.