@Override
 public long currentSequenceValue(SequenceKey sequenceKey, long timestamp) throws SQLException {
   SequenceInfo info = sequenceMap.get(sequenceKey);
   if (info == null) {
     throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_CALL_CURRENT_BEFORE_NEXT_VALUE)
         .setSchemaName(sequenceKey.getSchemaName())
         .setTableName(sequenceKey.getSequenceName())
         .build()
         .buildException();
   }
   return info.sequenceValue;
 }
 @Override
 public void incrementSequences(
     List<SequenceAllocation> sequenceAllocations,
     long timestamp,
     long[] values,
     SQLException[] exceptions)
     throws SQLException {
   int i = 0;
   for (SequenceAllocation sequenceAllocation : sequenceAllocations) {
     SequenceKey key = sequenceAllocation.getSequenceKey();
     SequenceInfo info = sequenceMap.get(key);
     if (info == null) {
       exceptions[i] = new SequenceNotFoundException(key.getSchemaName(), key.getSequenceName());
     } else {
       boolean increaseSeq = info.incrementBy > 0;
       if (info.limitReached) {
         SQLExceptionCode code =
             increaseSeq
                 ? SQLExceptionCode.SEQUENCE_VAL_REACHED_MAX_VALUE
                 : SQLExceptionCode.SEQUENCE_VAL_REACHED_MIN_VALUE;
         exceptions[i] = new SQLExceptionInfo.Builder(code).build().buildException();
       } else {
         values[i] = info.sequenceValue;
         info.sequenceValue += info.incrementBy * info.cacheSize;
         info.limitReached = SequenceUtil.checkIfLimitReached(info);
         if (info.limitReached && info.cycle) {
           info.sequenceValue = increaseSeq ? info.minValue : info.maxValue;
           info.limitReached = false;
         }
       }
     }
     i++;
   }
   i = 0;
   for (SQLException e : exceptions) {
     if (e != null) {
       sequenceMap.remove(sequenceAllocations.get(i).getSequenceKey());
     }
     i++;
   }
 }