KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jdon > model > query > block > BlockStrategy


1 /*
2  * Copyright 2003-2006 the original author or authors.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  */

16 package com.jdon.model.query.block;
17
18 import java.util.Collection JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.apache.log4j.Logger;
22
23 import com.jdon.model.query.JdbcTemp;
24 import com.jdon.model.query.cache.BlockCacheManager;
25 import com.jdon.model.query.cache.QueryConditonDatakey;
26
27 /**
28  * Block Strategy
29  * to increase the performance for a lot of datas fetching from the database
30  * ervery time read the database, we fetch a block that maye include 200 datas.
31  * note: these datas are the primary keys of the models that save in database.
32  *
33  * @author <a HREF="mailto:banqiao@jdon.com">banq</a>
34  *
35  */

36 public class BlockStrategy {
37     private final static Logger logger = Logger.getLogger(BlockStrategy.class);
38
39     private BlockQueryJDBC blockQueryJDBC;
40
41     private JdbcTemp jdbcTemp;
42
43     private BlockCacheManager blockCacheManager;
44
45     private int blockLength = 200;
46     
47
48     /**
49      * @param blockQueryJDBC
50      * @param jdbcTemp
51      * @param blockCacheManager
52      */

53     public BlockStrategy(BlockQueryJDBC blockQueryJDBC, JdbcTemp jdbcTemp, BlockCacheManager blockCacheManager) {
54         super();
55         this.blockQueryJDBC = blockQueryJDBC;
56         this.jdbcTemp = jdbcTemp;
57         this.blockCacheManager = blockCacheManager;
58     }
59     /**
60      * looking for the primary be equals to locateId in the result
61      * for the sql sentence.
62      * @param sqlquery
63      * @param queryParams
64      * @param locateId
65      * @return if not locate, return null;
66      */

67     public Block locate(String JavaDoc sqlquery, Collection JavaDoc queryParams, Object JavaDoc locateId) {
68         int blockSize = getBlockLength();
69         Block block = null;
70         int index = -1;
71         int prevBlockStart = Integer.MIN_VALUE;
72         int nextBlockStart = Integer.MIN_VALUE;
73         int start = 0;
74
75         logger.debug("[JdonFramework]try to locate a block locateId= " + locateId + " blockSize=" + blockSize);
76         
77         try {
78             while (index == -1) {
79                 block = getBlock(sqlquery, queryParams, start, blockSize);
80                 if (block == null)
81                     break;
82
83                 List JavaDoc list = block.getList();
84                 index = list.indexOf(locateId);
85                 if ((index >= 0) && (index < list.size())) {
86                     logger.debug("[JdonFramework]found the locateId, index= " + index);
87                     if ((index == 0) && (block.getStart() >= blockSize))// if is the first in this block
88
prevBlockStart = start - blockSize;
89                     else if (index == blockSize - 1) //// if is the last in this block
90
nextBlockStart = start + blockSize;
91                     break;
92                 } else {
93                     if (block.getCount() >= blockSize)//there are more block.
94
start = start + blockSize;
95                     else
96                         //there are no more block;
97
break;
98                 }
99             }
100
101             if (index == -1) {
102                 logger.debug("[JdonFramework] not locate the block that have the locateId= " + locateId);
103                 return null; //not found return null
104
}
105
106             if (prevBlockStart != Integer.MIN_VALUE) {
107                 Block prevBlock = getBlock(sqlquery, queryParams, prevBlockStart, blockSize);
108                 prevBlock.getList().addAll(block.getList());
109                 prevBlock.setStart(prevBlock.getStart() + prevBlock.getCount());
110                 prevBlock.setCount(prevBlock.getCount() + block.getCount());
111                 return prevBlock;
112             } else if (nextBlockStart != Integer.MIN_VALUE) { //if nextBlockStart has new value, so we need next block, fetch it.
113
Block nextBlock = getBlock(sqlquery, queryParams, nextBlockStart, blockSize);
114                 if (nextBlock != null) {
115                     block.getList().addAll(nextBlock.getList());
116                     block.setCount(block.getCount() + nextBlock.getCount());
117                 }
118                 return block;
119             } else
120                 return block;
121         } catch (Exception JavaDoc e) {
122             logger.error(" locate Block error" + e);
123         }
124         return block;
125     }
126
127     /**
128      * get a data block by the sql sentence.
129      * @param sqlqueryAllCount
130      * @param sqlquery
131      * @return if not found, return null;
132      */

133     public Block getBlock(String JavaDoc sqlquery, Collection JavaDoc queryParams, int startIndex, int count) {
134         logger.debug("[JdonFramework]enter getBlock .. ");
135         if ((count > this.blockLength) || (count <= 0)) { //every query max length must be little than blockLength
136
count = this.blockLength;
137         }
138         QueryConditonDatakey qcdk = new QueryConditonDatakey(sqlquery, queryParams, startIndex, count, this.blockLength);
139         Block block = getBlock(qcdk);
140         if (block.getCount() > 0) {
141             logger.debug("[JdonFramework]got a Block" + block.getCount());
142             return block;
143         } else {
144             logger.debug("[JdonFramework]not found the block!");
145             return null;
146         }
147     }
148
149     /**
150      * get the current block being avaliable to the query condition
151      * @param qcdk
152      * @return
153      */

154     private Block getBlock(QueryConditonDatakey qcdk) {
155         Block clientBlock = new Block(qcdk.getStart(), qcdk.getCount());
156         if (clientBlock.getCount() > this.blockLength)
157             clientBlock.setCount(this.blockLength);
158
159         //create dataBlock get DataBase or cache;
160
List JavaDoc list = getBlockKeys(qcdk);
161         Block dataBlock = new Block(qcdk.getBlockStart(), list.size());
162
163         int currentStart = clientBlock.getStart() - dataBlock.getStart();
164         Block currentBlock = new Block(currentStart, clientBlock.getCount());
165         currentBlock.setList(list);
166
167         try {
168             //because clientBlock's length maybe not be equals to the dataBlock's length
169
//we need the last length:
170
//1.the last block length is great than the clientBlock's length,the current block's length is the clientBlock's length
171
//2.the last block length is less than the clientBlock's length,under this condition, there are two choice.
172
int lastCount = dataBlock.getCount() + dataBlock.getStart() - clientBlock.getStart();
173             logger.debug("[JdonFramework] lastCount=" + lastCount);
174             //2 happened
175
if (lastCount < clientBlock.getCount()) {
176                 //if 2 , two case:
177
//1. if the dataBlock's length is this.blockLength(200),should have more dataBlocks.
178
if (dataBlock.getCount() == this.blockLength) {
179                     //new datablock, we must support new start and new count
180
//the new start = old datablock's length + old datablock's start.
181
int newStartIndex = dataBlock.getStart() + dataBlock.getCount();
182                     int newCount = clientBlock.getCount() - lastCount;
183                     qcdk.setStart(newStartIndex);
184                     qcdk.setCount(newCount);
185                     logger.debug("[JdonFramework] newStartIndex=" + newStartIndex + " newCount=" + newCount);
186                     Block nextBlock = getBlock(qcdk);
187                     logger.debug("[JdonFramework] nextBlock.getCount()=" + nextBlock.getCount());
188                     currentBlock.setCount(currentBlock.getCount() + nextBlock.getCount());
189                 } else {
190                     //2. if not, all datas just be here, clientBlock's count value maybe not correct.
191
currentBlock.setCount(lastCount);
192                 }
193             }
194         } catch (Exception JavaDoc e) {
195             logger.error(" getBlock error" + e);
196         }
197         return currentBlock;
198     }
199
200     /**
201      * get a Block that begin at the start
202      * @param qcdk QueryConditonDatakey
203      * @return return the collection fit for start value and count value.
204      */

205     private List JavaDoc getBlockKeys(QueryConditonDatakey qcdk) {
206         List JavaDoc keys = blockCacheManager.getBlockKeysFromCache(qcdk);
207         if ((keys == null)) {
208             keys = blockQueryJDBC.fetchDatas(qcdk);
209             blockCacheManager.saveBlockKeys(qcdk, keys);
210         }
211         logger.debug("[JdonFramework] getBlockKeys, size=" + keys.size());
212         return keys;
213     }
214        
215
216     /**
217      * @return Returns the blockLength.
218      */

219     public int getBlockLength() {
220         return blockLength;
221     }
222
223     /**
224      * @param blockLength The blockLength to set.
225      */

226     public void setBlockLength(int blockLength) {
227         this.blockLength = blockLength;
228     }
229
230 }
231
Popular Tags