func (cms *ConcurrentMergeScheduler) worker(id int) {
	atomic.AddInt32(&cms.numMergeRoutines, 1)
	fmt.Printf("CMS Worker %v is started.\n", id)
	var isRunning = true
	var wg *sync.WaitGroup
	for isRunning && id < cms.maxRoutineCount {
		select {
		case job := <-cms.chRequest:
			cms.process(job)
		case wg = <-cms.chSync:
			isRunning = false
			defer wg.Done()
		}
	}
	fmt.Printf("CMS Worker %v is stopped.\n", id)
	atomic.AddInt32(&cms.numMergeRoutines, -1)
}
/*
Daemon worker that accepts and processes merge job.

GoLucene assumes each merge is pre-sorted according to its merge size
before acquired from IndexWriter. It makes use of pre-allocated
go routines, instead of MergeThread to do the real merge work,
witout explicit synchronizations and waitings.

Note, however, change of merge count won't pause/resume workers.
package index
import (
	"fmt"
	"log"
	"sync"
	"sync/atomic"
	"time"
)
type MergeJob struct {
	start  time.Time
	writer *IndexWriter
	merge  *OneMerge
}
const DEFAULT_MAX_ROUTINE_COUNT = 1
const DEFAULT_MAX_MERGE_COUNT = 2
type ConcurrentMergeScheduler struct {
	sync.Locker
	maxRoutineCount int
	maxMergeCount int
	writer *IndexWriter
	mergeThreadCount int32  
	suppressErrors bool
	chRequest            chan *MergeJob
	chSync               chan *sync.WaitGroup
	concurrentMergeCount int32  
	numMergeRoutines     int32  
}
func NewConcurrentMergeScheduler() *ConcurrentMergeScheduler {
	cms := &ConcurrentMergeScheduler{
		Locker:    &sync.Mutex{},
		chRequest: make(chan *MergeJob),
		chSync:    make(chan *sync.WaitGroup),
	}
	cms.SetMaxMergesAndRoutines(DEFAULT_MAX_MERGE_COUNT, DEFAULT_MAX_ROUTINE_COUNT)
	return cms
}