blockstrategy.java
来自「用jbuilder写的源程序」· Java 代码 · 共 231 行
JAVA
231 行
/*
* Copyright 2003-2006 the original author or authors.
* 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 com.jdon.model.query.block;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import com.jdon.model.query.JdbcTemp;
import com.jdon.model.query.cache.BlockCacheManager;
import com.jdon.model.query.cache.QueryConditonDatakey;
/**
* Block Strategy
* to increase the performance for a lot of datas fetching from the database
* ervery time read the database, we fetch a block that maye include 200 datas.
* note: these datas are the primary keys of the models that save in database.
*
* @author <a href="mailto:banqiao@jdon.com">banq</a>
*
*/
public class BlockStrategy {
private final static Logger logger = Logger.getLogger(BlockStrategy.class);
private BlockQueryJDBC blockQueryJDBC;
private JdbcTemp jdbcTemp;
private BlockCacheManager blockCacheManager;
private int blockLength = 200;
/**
* @param blockQueryJDBC
* @param jdbcTemp
* @param blockCacheManager
*/
public BlockStrategy(BlockQueryJDBC blockQueryJDBC, JdbcTemp jdbcTemp, BlockCacheManager blockCacheManager) {
super();
this.blockQueryJDBC = blockQueryJDBC;
this.jdbcTemp = jdbcTemp;
this.blockCacheManager = blockCacheManager;
}
/**
* looking for the primary be equals to locateId in the result
* for the sql sentence.
* @param sqlquery
* @param queryParams
* @param locateId
* @return if not locate, return null;
*/
public Block locate(String sqlquery, Collection queryParams, Object locateId) {
int blockSize = getBlockLength();
Block block = null;
int index = -1;
int prevBlockStart = Integer.MIN_VALUE;
int nextBlockStart = Integer.MIN_VALUE;
int start = 0;
logger.debug("[JdonFramework]try to locate a block locateId= " + locateId + " blockSize=" + blockSize);
try {
while (index == -1) {
block = getBlock(sqlquery, queryParams, start, blockSize);
if (block == null)
break;
List list = block.getList();
index = list.indexOf(locateId);
if ((index >= 0) && (index < list.size())) {
logger.debug("[JdonFramework]found the locateId, index= " + index);
if ((index == 0) && (block.getStart() >= blockSize))// if is the first in this block
prevBlockStart = start - blockSize;
else if (index == blockSize - 1) //// if is the last in this block
nextBlockStart = start + blockSize;
break;
} else {
if (block.getCount() >= blockSize)//there are more block.
start = start + blockSize;
else
//there are no more block;
break;
}
}
if (index == -1) {
logger.debug("[JdonFramework] not locate the block that have the locateId= " + locateId);
return null; //not found return null
}
if (prevBlockStart != Integer.MIN_VALUE) {
Block prevBlock = getBlock(sqlquery, queryParams, prevBlockStart, blockSize);
prevBlock.getList().addAll(block.getList());
prevBlock.setStart(prevBlock.getStart() + prevBlock.getCount());
prevBlock.setCount(prevBlock.getCount() + block.getCount());
return prevBlock;
} else if (nextBlockStart != Integer.MIN_VALUE) { //if nextBlockStart has new value, so we need next block, fetch it.
Block nextBlock = getBlock(sqlquery, queryParams, nextBlockStart, blockSize);
if (nextBlock != null) {
block.getList().addAll(nextBlock.getList());
block.setCount(block.getCount() + nextBlock.getCount());
}
return block;
} else
return block;
} catch (Exception e) {
logger.error(" locate Block error" + e);
}
return block;
}
/**
* get a data block by the sql sentence.
* @param sqlqueryAllCount
* @param sqlquery
* @return if not found, return null;
*/
public Block getBlock(String sqlquery, Collection queryParams, int startIndex, int count) {
logger.debug("[JdonFramework]enter getBlock .. ");
if ((count > this.blockLength) || (count <= 0)) { //every query max length must be little than blockLength
count = this.blockLength;
}
QueryConditonDatakey qcdk = new QueryConditonDatakey(sqlquery, queryParams, startIndex, count, this.blockLength);
Block block = getBlock(qcdk);
if (block.getCount() > 0) {
logger.debug("[JdonFramework]got a Block" + block.getCount());
return block;
} else {
logger.debug("[JdonFramework]not found the block!");
return null;
}
}
/**
* get the current block being avaliable to the query condition
* @param qcdk
* @return
*/
private Block getBlock(QueryConditonDatakey qcdk) {
Block clientBlock = new Block(qcdk.getStart(), qcdk.getCount());
if (clientBlock.getCount() > this.blockLength)
clientBlock.setCount(this.blockLength);
//create dataBlock get DataBase or cache;
List list = getBlockKeys(qcdk);
Block dataBlock = new Block(qcdk.getBlockStart(), list.size());
int currentStart = clientBlock.getStart() - dataBlock.getStart();
Block currentBlock = new Block(currentStart, clientBlock.getCount());
currentBlock.setList(list);
try {
//because clientBlock's length maybe not be equals to the dataBlock's length
//we need the last length:
//1.the last block length is great than the clientBlock's length,the current block's length is the clientBlock's length
//2.the last block length is less than the clientBlock's length,under this condition, there are two choice.
int lastCount = dataBlock.getCount() + dataBlock.getStart() - clientBlock.getStart();
logger.debug("[JdonFramework] lastCount=" + lastCount);
//2 happened
if (lastCount < clientBlock.getCount()) {
//if 2 , two case:
//1. if the dataBlock's length is this.blockLength(200),should have more dataBlocks.
if (dataBlock.getCount() == this.blockLength) {
//new datablock, we must support new start and new count
//the new start = old datablock's length + old datablock's start.
int newStartIndex = dataBlock.getStart() + dataBlock.getCount();
int newCount = clientBlock.getCount() - lastCount;
qcdk.setStart(newStartIndex);
qcdk.setCount(newCount);
logger.debug("[JdonFramework] newStartIndex=" + newStartIndex + " newCount=" + newCount);
Block nextBlock = getBlock(qcdk);
logger.debug("[JdonFramework] nextBlock.getCount()=" + nextBlock.getCount());
currentBlock.setCount(currentBlock.getCount() + nextBlock.getCount());
} else {
//2. if not, all datas just be here, clientBlock's count value maybe not correct.
currentBlock.setCount(lastCount);
}
}
} catch (Exception e) {
logger.error(" getBlock error" + e);
}
return currentBlock;
}
/**
* get a Block that begin at the start
* @param qcdk QueryConditonDatakey
* @return return the collection fit for start value and count value.
*/
private List getBlockKeys(QueryConditonDatakey qcdk) {
List keys = blockCacheManager.getBlockKeysFromCache(qcdk);
if ((keys == null)) {
keys = blockQueryJDBC.fetchDatas(qcdk);
blockCacheManager.saveBlockKeys(qcdk, keys);
}
logger.debug("[JdonFramework] getBlockKeys, size=" + keys.size());
return keys;
}
/**
* @return Returns the blockLength.
*/
public int getBlockLength() {
return blockLength;
}
/**
* @param blockLength The blockLength to set.
*/
public void setBlockLength(int blockLength) {
this.blockLength = blockLength;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?