class UpdateThreadFactory implements ThreadFactory {

		private static int threadInitNumber = 0;

		private static synchronized int nextThreadNum() {
			return threadInitNumber++;
		}

		@Override
		public Thread newThread(Runnable r) {
			return new Thread(r, "Thread-Segment-Update-" + nextThreadNum());
		}

	}

	@Override
	public boolean init() {
		logger.info("Init ...");
		// 确保加载到kv后才初始化成功
		updateCacheFromDb();
		initOk = true;
		updateCacheFromDbAtEveryMinute();
		return initOk;
	}

	private void updateCacheFromDbAtEveryMinute() {
		ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				Thread t = new Thread(r);
				t.setName("check-idCache-thread");
				t.setDaemon(true);
				return t;
			}
		});
		service.scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				updateCacheFromDb();
			}
		}, 60, 60, TimeUnit.SECONDS);
	}

	private void updateCacheFromDb() {
		logger.info("update cache from db");
		try {
			List<String> dbTags = dao.getAllTags();
			if (dbTags == null || dbTags.isEmpty()) {
				return;
			}
			List<String> cacheTags = new ArrayList<String>(cache.keySet());
			Set<String> insertTagsSet = new HashSet<>(dbTags);
			Set<String> removeTagsSet = new HashSet<>(cacheTags);
			// db中新加的tags灌进cache
			for (int i = 0; i < cacheTags.size(); i++) {
				String tmp = cacheTags.get(i);
				insertTagsSet.remove(tmp);
			}
			for (String tag : insertTagsSet) {
				SegmentBuffer buffer = new SegmentBuffer();
				buffer.setKey(tag);
				Segment segment = buffer.getCurrent();
				segment.setValue(new AtomicLong(0));
				segment.setMax(0);
				segment.setStep(0);
				cache.put(tag, buffer);
				logger.info("Add tag {} from db to IdCache, SegmentBuffer {}", tag, buffer);
			}
			// cache中已失效的tags从cache删除
			for (int i = 0; i < dbTags.size(); i++) {
				String tmp = dbTags.get(i);
				removeTagsSet.remove(tmp);
			}
			for (String tag : removeTagsSet) {
				cache.remove(tag);
				logger.info("Remove tag {} from IdCache", tag);
			}
		}
		catch (Exception e) {
			logger.warn("update cache from db exception", e);
		}
	}

	@Override
	public Result get(final String key) {
		if (!initOk) {
			return new Result(EXCEPTION_ID_IDCACHE_INIT_FALSE, Status.EXCEPTION);
		}
		SegmentBuffer buffer = cache.get(key);
		if (buffer != null) {
			if (buffer.isInitOk()) {
				synchronized (buffer) {
					if (buffer.isInitOk()) {
						try {
							updateSegmentFromDb(key, buffer.getCurrent());
							logger.info("Init buffer. Update leafkey {} {} from db", key, buffer.getCurrent());
							buffer.setInitOk(true);
						}
						catch (Exception e) {
							logger.warn("Init buffer {} exception", buffer.getCurrent(), e);
						}
					}
				}
			}
			return getIdFromSegmentBuffer(cache.get(key));
		}
		return new Result(EXCEPTION_ID_KEY_NOT_EXISTS, Status.EXCEPTION);
	}

	public void updateSegmentFromDb(String key, Segment segment) {<FILL_FUNCTION_BODY>

		SegmentBuffer buffer = segment.getBuffer();
		LeafAlloc leafAlloc;
		if (buffer.isInitOk()) {
			leafAlloc = dao.updateMaxIdAndGetLeafAlloc(key);
			buffer.setStep(leafAlloc.getStep());
			// leafAlloc中的step为DB中的step
			buffer.setMinStep(leafAlloc.getStep());
		}
		else if (buffer.getUpdateTimestamp() == 0) {
			leafAlloc = dao.updateMaxIdAndGetLeafAlloc(key);
			buffer.setUpdateTimestamp(System.currentTimeMillis());
			buffer.setStep(leafAlloc.getStep());
			// leafAlloc中的step为DB中的step
			buffer.setMinStep(leafAlloc.getStep());
		}
		else {
			long duration = System.currentTimeMillis() - buffer.getUpdateTimestamp();
			int nextStep = buffer.getStep();
			if (duration < SEGMENT_DURATION) {
				if (nextStep * DEFAULT_LOAD_FACTOR > MAX_STEP) {
					// do nothing
				}
				else {
					nextStep = nextStep * DEFAULT_LOAD_FACTOR;
				}
			}
			else if (duration < SEGMENT_DURATION * DEFAULT_LOAD_FACTOR) {
				// do nothing with nextStep
			}
			else {
				nextStep = nextStep / DEFAULT_LOAD_FACTOR >= buffer.getMinStep() ? nextStep / DEFAULT_LOAD_FACTOR
						: nextStep;
			}
			logger.info("leafKey[{}], step[{}], duration[{}mins], nextStep[{}]", key, buffer.getStep(),
					String.format("%.2f", ((double) duration / (1000 * 60))), nextStep);
			LeafAlloc temp = new LeafAlloc();
			temp.setKey(key);
			temp.setStep(nextStep);
			leafAlloc = dao.updateMaxIdByCustomStepAndGetLeafAlloc(temp);
			buffer.setUpdateTimestamp(System.currentTimeMillis());
			buffer.setStep(nextStep);
			// leafAlloc的step为DB中的step
			buffer.setMinStep(leafAlloc.getStep());
		}
		// must set value before set max
		long value = leafAlloc.getMaxId() - buffer.getStep();
		segment.getValue().set(value);
		segment.setMax(leafAlloc.getMaxId());
		segment.setStep(buffer.getStep());
		segment.setRandomStep(leafAlloc.getRandomStep());
	
<no_super_class>