anchor.diff:  [[customSolutionPartitioner]]
   === Custom SolutionPartitioner
   
  -To use a custom partitioner, configure a partitioner on the Partitioned Search phase:
  +To use a custom `SolutionPartitioner`, configure one on the Partitioned Search phase:
   
   [source,xml,options="nowrap"]
   ----
  
positive.code: [[partitionedSearchAlgorithm]]
  == Algorithm Description
  
  For big datasets, usually above 5000 planning entities,
  it is usually worthwhile to partition the datasets into smaller pieces and solve those separately.
  Partition Search is multi-threaded, leading to a performance boost due to more CPU utilization.
  Additionally, it finds an initial solution faster, even if it only uses only 1 CPU,
  because the search space sum of a partitioned Construction Heuristic is far less than its non-partitioned variant.
  
  However, **partitioning does lead to suboptimal results**, even if the pieces are solved optimally, as shown below:
  
  image::Chapter-Partitioned_search/mapReduceIsTerribleForTsp.png[align="center"]
  
  One way to deal with this is to run a non-partitioned Local Search after the Partitioned Search phase.
  
  [NOTE]
  ====
  Not all use cases can be partitioned.
  It only works on use cases for which the planning entities and value ranges can be split into n partition,
  such that none of the constraints cross the boundaries between partitions.
  ====
  
  
  
negative.code: [[runnablePartThreadLimit]]
  == Runnable Part Thread Limit
  
  When running a multi-threaded solver, such as Partitioned Search, CPU power can quickly become a scarce resource,
  which can cause other processes or threads to hang or freeze.
  However, Planner has a system to prevent CPU starving of
  other processes (such as an SSH connection in production or your IDE in development)
  or other threads (such as the servlet threads that handle REST requests).
  
  As explained in <<sizingHardwareAndSoftware, sizing hardware and software>>,
  each solver (including each child solver) does no IO during `solve()` and therefore saturates 1 CPU core completely.
  In Partitioned Search, every partition always has its own thread, called a part thread.
  It is impossible for two partitions to share a thread,
  because of <<asynchronousTermination,asynchronous termination>>: the second thread would never run.
  Every part thread will try to consume one CPU core entirely, so if there are more partitions than CPU cores,
  this will probably hang the system.
  `Thread.setPriority()` is often too weak to solve this hogging problem, so another approach is used.
  
  The `runnablePartThreadLimit` parameter specifies how many part threads are runnable at the same time.
  The other part threads will temporarily block and therefore will not consume any CPU power.
  *This parameter basically specifies how many CPU cores are donated to Planner.*
  All part threads share the CPU cores in a round-robin manner
  to consume (more or less) the same number of CPU cycles:
  
  