All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datarouter.client.mysql.op.write.MysqlVacuumOp Maven / Gradle / Ivy

There is a newer version: 0.0.125
Show newest version
/*
 * Copyright © 2009 HotPads ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.datarouter.client.mysql.op.write;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.datarouter.client.mysql.op.BaseMysqlOp;
import io.datarouter.client.mysql.sql.MysqlSql;
import io.datarouter.client.mysql.sql.MysqlSqlFactory;
import io.datarouter.model.databean.Databean;
import io.datarouter.model.key.primary.PrimaryKey;
import io.datarouter.model.serialize.fielder.DatabeanFielder;
import io.datarouter.storage.Datarouter;
import io.datarouter.storage.config.Config;
import io.datarouter.storage.serialize.fieldcache.PhysicalDatabeanFieldInfo;
import io.datarouter.util.string.StringTool;

public class MysqlVacuumOp<
		PK extends PrimaryKey,
		D extends Databean,
		F extends DatabeanFielder>
extends BaseMysqlOp{
	private static final Logger logger = LoggerFactory.getLogger(MysqlVacuumOp.class);

	private final MysqlSqlFactory mysqlSqlFactory;
	private final PhysicalDatabeanFieldInfo fieldInfo;
	private final String keyId;
	private final String ttlId;
	private final Config config;

	public MysqlVacuumOp(
			Datarouter datarouter,
			PhysicalDatabeanFieldInfo fieldInfo,
			MysqlSqlFactory mysqlSqlFactory,
			String keyId,
			String ttlId,
			Config config){
		super(datarouter, fieldInfo.getClientId());
		this.mysqlSqlFactory = mysqlSqlFactory;
		this.fieldInfo = fieldInfo;
		this.keyId = keyId;
		this.ttlId = ttlId;
		this.config = config;
	}

	@Override
	public Void runOnce(){
		Connection connection = getConnection();
		String tableName = fieldInfo.getTableName();
		boolean disableIntroducer = fieldInfo.getDisableIntroducer();
		int offset = config.findResponseBatchSize().orElse(10_000);
		Long nowMs = System.currentTimeMillis();
		try{
			MysqlSql endSql = buildSqlSelectKey(null, tableName, disableIntroducer, true, offset);
			PreparedStatement statementEnd = endSql.prepare(connection);
			statementEnd.execute();
			String startId = null;
			String endId = null;
			while(statementEnd.getResultSet().next()){
				endId = statementEnd.getResultSet().getString(keyId);
			}
			while(startId != null || endId != null){
				MysqlSql sqlDelete = buildSqlDeleteRange(tableName, disableIntroducer, nowMs, startId, endId);
				PreparedStatement del = sqlDelete.prepare(connection);
				del.execute();
				startId = endId;
				endSql = buildSqlSelectKey(startId, tableName, disableIntroducer, false, offset);
				endId = null;
				if(endSql == null){
					continue;
				}
				statementEnd = endSql.prepare(connection);
				statementEnd.execute();
				while(statementEnd.getResultSet().next()){
					endId = statementEnd.getResultSet().getString(keyId);
				}
			}
		}catch(SQLException e){
			logger.error("error with vacuum: ", e);
			throw new RuntimeException(e);
		}
		return null;
	}

	private MysqlSql buildSqlSelectKey(
			String startKey,
			String tableName,
			boolean disableIntroducer,
			boolean first,
			int offset){
		MysqlSql sql = mysqlSqlFactory
				.createSql(getClientId(), tableName, disableIntroducer)
				.addSelectFromClause(tableName, fieldInfo.getPrimaryKeyFields());
		if(!first && startKey == null){
			return null;
		}
		if(!first){
			sql.append(" where ");
			sql.append(keyId);
			sql.append(">=");
			sql.append(StringTool.escapeString(startKey));
			sql.addLimitOffsetClause(new Config().setLimit(1).setOffset(offset));
		}else{
			sql.addLimitOffsetClause(new Config().setLimit(1));
		}
		return sql;
	}

	private MysqlSql buildSqlDeleteRange(
			String tableName,
			boolean disableIntroducer,
			Long nowMs,
			String startId,
			String endId){
		MysqlSql sqlDelete = mysqlSqlFactory
				.createSql(getClientId(), tableName, disableIntroducer)
				.addDeleteFromClause(tableName)
				.append(" where ");
		if(startId != null){
			sqlDelete
				.append(keyId)
				.append(" >= ")
				.append(StringTool.escapeString(startId))
				.append(" and ");
		}
		if(endId != null){
			sqlDelete
				.append(keyId)
				.append(" < ")
				.append(StringTool.escapeString(endId))
				.append(" and ");
		}
		sqlDelete
				.append(ttlId)
				.append(" < ")
				.append("" + nowMs);
		return sqlDelete;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy