11 * |
11 * |
12 * Contributors: |
12 * Contributors: |
13 * |
13 * |
14 * Description: |
14 * Description: |
15 * |
15 * |
16 * Version : %version: 7 % |
16 * Version : %version: 10 % |
17 */ |
17 */ |
18 #include "hgbuffermanager.h" |
18 #include "hgbuffermanager.h" |
|
19 #include "hglogger.h" |
19 #include <hgwidgets/hgcacheproxymodel.h> |
20 #include <hgwidgets/hgcacheproxymodel.h> |
20 |
21 |
21 |
22 |
22 HgBufferManager::HgBufferManager( |
23 HgBufferManager::HgBufferManager( |
23 HgBufferManagerObserver* aObserver, |
24 HgBufferManagerObserver* aObserver, |
24 int aBufferSize, |
25 int aBufferSize, |
25 int aBufferTreshold, |
26 int aBufferTreshold, |
26 int aInitialPosition, |
27 int aInitialPosition, |
27 int aTotalCount ) |
28 int aTotalCount) |
28 : |
29 : |
29 mObserver(aObserver), |
30 mObserver(aObserver), |
30 mBufferSize( aBufferSize ), |
31 mBufferSize(aBufferSize), |
31 mBufferTreshold( aBufferTreshold ), |
32 mBufferTreshold(aBufferTreshold), |
32 mBufferPosition( aInitialPosition ), |
33 mBufferPosition(aInitialPosition), |
33 mDiff(0), |
34 mDiff(0), |
34 mTotalCount( aTotalCount ), |
35 mTotalCount(aTotalCount), |
35 mResetOrdered(false), |
36 mResetOrdered(false), |
36 mRequestStart(0), |
37 mRequestStart(0), |
37 mRequestCount(0), |
38 mRequestCount(0), |
38 mReleaseStart(0), |
39 mReleaseStart(0), |
39 mReleaseCount(0) |
40 mReleaseCount(0) |
40 { |
41 { |
41 ASSERT( mObserver != 0 ); |
42 ASSERT(mObserver != 0); |
42 mBufferPosition -= (mBufferSize / 2); |
43 mBufferPosition -= (mBufferSize/2); |
43 |
44 |
44 if( mBufferPosition + mBufferSize > mTotalCount - 1 ){ |
45 if (mBufferPosition + mBufferSize > mTotalCount - 1 ) { |
45 mBufferPosition = (mTotalCount - 1) - mBufferSize; |
46 mBufferPosition = (mTotalCount - 1) - mBufferSize; |
46 } |
47 } |
47 |
48 |
48 if(mBufferPosition < 0 ){ |
49 if (mBufferPosition < 0 ) { |
49 mBufferPosition = 0; |
50 mBufferPosition = 0; |
50 } |
51 } |
51 |
52 |
52 mDiff = 0; |
53 mDiff = 0; |
53 //request Initial Buffer |
54 //request Initial Buffer |
66 { |
67 { |
67 if (newTreshold != mBufferTreshold){ |
68 if (newTreshold != mBufferTreshold){ |
68 mBufferTreshold = newTreshold; |
69 mBufferTreshold = newTreshold; |
69 } |
70 } |
70 |
71 |
71 if (newSize!=mBufferSize){ |
72 if (newSize!=mBufferSize) { |
72 // int pos = mBufferPosition + (mBufferSize / 2); |
|
73 |
|
74 int a = Max(0, mBufferPosition + mBufferSize/2 - newSize/2); |
73 int a = Max(0, mBufferPosition + mBufferSize/2 - newSize/2); |
75 int b = Min(a + newSize, mTotalCount); |
74 int b = Min(a + newSize, mTotalCount); |
76 if ( b == mTotalCount){ |
75 if (b == mTotalCount) { |
77 a = mTotalCount - newSize; |
76 a = mTotalCount - newSize; |
78 } |
77 } |
79 |
78 |
80 int c = Max(0, mBufferPosition); |
79 int c = Max(0, mBufferPosition); |
81 int d = Min(c + mBufferSize, mTotalCount); |
80 int d = Min(c + mBufferSize, mTotalCount); |
82 if ( d == mTotalCount){ |
81 if (d == mTotalCount) { |
83 c = mTotalCount - mBufferSize; |
82 c = mTotalCount - mBufferSize; |
84 } |
83 } |
85 |
84 |
86 if ( newSize>mBufferSize){ |
85 if (newSize>mBufferSize) { |
87 mObserver->request(a, c-1, HgCacheProxyModel::HgRequestOrderAscending); |
86 mObserver->request(a, c-1, HgCacheProxyModel::HgRequestOrderAscending); |
88 mObserver->request(d, b-1, HgCacheProxyModel::HgRequestOrderAscending); |
87 mObserver->request(d, b-1, HgCacheProxyModel::HgRequestOrderAscending); |
89 }else if ( newSize<mBufferSize){ |
88 }else if (newSize<mBufferSize) { |
90 mObserver->release(c, a-1); |
89 mObserver->release(c, a-1); |
91 mObserver->release(b, d); |
90 mObserver->release(b, d); |
92 } |
91 } |
93 mBufferPosition = a; |
92 mBufferPosition = a; |
94 mBufferSize = newSize; |
93 mBufferSize = newSize; |
97 |
96 |
98 void HgBufferManager::calculate() |
97 void HgBufferManager::calculate() |
99 { |
98 { |
100 HgCacheProxyModel::HgRequestOrder direction = HgCacheProxyModel::HgRequestOrderAscending; |
99 HgCacheProxyModel::HgRequestOrder direction = HgCacheProxyModel::HgRequestOrderAscending; |
101 |
100 |
102 if(mResetOrdered){ |
101 if (mResetOrdered) { |
103 mResetOrdered = false; |
102 mResetOrdered = false; |
104 } else { |
103 } else { |
105 if(mDiff < 0){ |
104 if (mDiff < 0) { |
106 mReleaseStart = mBufferPosition; |
105 mReleaseStart = mBufferPosition; |
107 mRequestStart = mBufferPosition + mBufferSize; |
106 mRequestStart = mBufferPosition + mBufferSize; |
108 direction = HgCacheProxyModel::HgRequestOrderAscending; |
107 direction = HgCacheProxyModel::HgRequestOrderAscending; |
109 } else if( mDiff > 0) { |
108 } else if( mDiff > 0) { |
110 mReleaseStart = mBufferPosition + mBufferSize - mDiff; |
109 mReleaseStart = mBufferPosition + mBufferSize - mDiff; |
112 direction = HgCacheProxyModel::HgRequestOrderDescending; |
111 direction = HgCacheProxyModel::HgRequestOrderDescending; |
113 } |
112 } |
114 } |
113 } |
115 |
114 |
116 // Release |
115 // Release |
117 int end = mReleaseStart + mReleaseCount < mTotalCount ? |
116 int end = (mReleaseStart + mReleaseCount < mTotalCount)? |
118 mReleaseStart + mReleaseCount: mTotalCount; |
117 (mReleaseStart + mReleaseCount): mTotalCount; |
119 end--; |
118 end--; |
120 if(end >= mReleaseStart ){ |
119 if (end >= mReleaseStart) { |
121 mObserver->release(mReleaseStart, end); |
120 mObserver->release(mReleaseStart, end); |
122 } |
121 } |
123 |
122 |
124 mReleaseCount = 0; |
123 mReleaseCount = 0; |
125 |
124 |
126 // Request |
125 // Request |
127 end = mRequestStart + mRequestCount < mTotalCount ? |
126 end = (mRequestStart + mRequestCount < mTotalCount)? |
128 mRequestStart + mRequestCount : mTotalCount; |
127 (mRequestStart + mRequestCount): mTotalCount; |
129 |
128 |
130 end--; |
129 end--; |
131 if(end >= mRequestStart ){ |
130 if (end >= mRequestStart) { |
132 mObserver->request(mRequestStart, end, direction); |
131 mObserver->request(mRequestStart, end, direction); |
133 } |
132 } |
134 |
133 |
135 mRequestCount = 0; |
134 mRequestCount = 0; |
136 |
135 |
145 // ----------------------------------------------------------------------------- |
144 // ----------------------------------------------------------------------------- |
146 // |
145 // |
147 void HgBufferManager::setPosition( int aIndex ) |
146 void HgBufferManager::setPosition( int aIndex ) |
148 { |
147 { |
149 // If all the items fit in the buffer no need to move the buffer |
148 // If all the items fit in the buffer no need to move the buffer |
150 if(mTotalCount <= mBufferSize) |
149 if (mTotalCount <= mBufferSize) |
151 return; |
150 return; |
152 |
151 |
153 bool forceUpdate = false; |
152 bool forceUpdate = false; |
154 aIndex -= mBufferSize / 2; // normalize index to Buffer start |
153 int idx = aIndex - mBufferSize / 2; // normalize index to Buffer start |
155 |
154 |
156 if(aIndex < 0){ |
155 if (idx < 0) { |
157 aIndex = 0; |
156 idx = 0; |
158 forceUpdate = true; |
157 forceUpdate = true; |
159 }else if( aIndex > mTotalCount - mBufferSize ){ |
158 }else if (idx > mTotalCount - mBufferSize) { |
160 aIndex = mTotalCount - mBufferSize; |
159 idx = mTotalCount - mBufferSize; |
161 forceUpdate = true; |
160 forceUpdate = true; |
162 } |
161 } |
163 |
162 |
164 mDiff = mBufferPosition - aIndex; |
163 mDiff = mBufferPosition - idx; |
165 |
164 |
166 // Too large change reset whole buffer |
165 // Too large change reset whole buffer |
167 if( mDiff >= mBufferSize || -mDiff >= mBufferSize || mResetOrdered ) { |
166 if (mDiff >= mBufferSize || -mDiff >= mBufferSize || mResetOrdered) { |
168 resetBuffer(aIndex + (mBufferSize/2), mTotalCount); |
167 resetBuffer(aIndex, mTotalCount); |
169 } else if( mDiff >= mBufferTreshold ) { // Move Up |
168 } else if (mDiff >= mBufferTreshold) { // Move Up |
170 mRequestCount = mDiff; |
169 mRequestCount = mDiff; |
171 mReleaseCount = mDiff; |
170 mReleaseCount = mDiff; |
172 calculate(); |
171 calculate(); |
173 } else if ( -mDiff >= mBufferTreshold ) {// Move Down |
172 } else if (-mDiff >= mBufferTreshold) {// Move Down |
174 mRequestCount = -mDiff; |
173 mRequestCount = -mDiff; |
175 mReleaseCount = -mDiff; |
174 mReleaseCount = -mDiff; |
176 calculate(); |
175 calculate(); |
177 } else if( forceUpdate && mDiff ) { // Top or bottom has been reached |
176 } else if (forceUpdate && mDiff) { // Top or bottom has been reached |
178 int diff = mDiff < 0 ? -mDiff : mDiff; |
177 int diff = mDiff < 0 ? -mDiff : mDiff; |
179 mRequestCount = diff; |
178 mRequestCount = diff; |
180 mReleaseCount = diff; |
179 mReleaseCount = diff; |
181 calculate(); |
180 calculate(); |
182 } |
181 } |
184 |
183 |
185 // ----------------------------------------------------------------------------- |
184 // ----------------------------------------------------------------------------- |
186 // BufferManager::ResetBuffer() |
185 // BufferManager::ResetBuffer() |
187 // ----------------------------------------------------------------------------- |
186 // ----------------------------------------------------------------------------- |
188 // |
187 // |
189 void HgBufferManager::resetBuffer( int aPosition, int aTotalCount) |
188 void HgBufferManager::resetBuffer(int aPosition, int aTotalCount) |
190 { |
189 { |
191 if( !mResetOrdered ){ |
190 int oldPos = mBufferPosition; |
|
191 if (!mResetOrdered) { |
192 // release Old buffer |
192 // release Old buffer |
193 mReleaseStart = mBufferPosition; |
193 mReleaseStart = mBufferPosition; |
194 mReleaseCount = mBufferSize; |
194 mReleaseCount = mBufferSize; |
195 } |
195 } |
|
196 |
|
197 mTotalCount = aTotalCount; |
|
198 mDiff = 0; |
196 |
199 |
197 // set position and count |
200 // set position and count |
198 mBufferPosition = aPosition - (mBufferSize / 2); |
201 mBufferPosition = aPosition - (mBufferSize / 2); |
199 mTotalCount = aTotalCount; |
202 |
200 mDiff = 0; |
203 if (aPosition < 0) { |
201 |
204 aPosition = 0; |
202 if( mBufferPosition + mBufferSize > mTotalCount - 1 ){ |
205 } else if (aPosition >= mTotalCount) { |
|
206 aPosition = mTotalCount - 1; |
|
207 } |
|
208 |
|
209 if (mBufferPosition + mBufferSize > mTotalCount - 1) { |
203 mBufferPosition = mTotalCount - mBufferSize; |
210 mBufferPosition = mTotalCount - mBufferSize; |
204 } |
211 } |
205 |
212 if (mBufferPosition < 0) { |
206 if(mBufferPosition < 0 ){ |
|
207 mBufferPosition = 0; |
213 mBufferPosition = 0; |
208 } |
214 } |
209 |
215 |
210 if (mBufferPosition>1){ |
216 mObserver->release(0, mTotalCount); |
211 mObserver->release(0, mBufferPosition-1); |
217 |
212 } |
218 // size size size |
213 |
219 // -------------|---------|---------|---------|------------------ |
214 mObserver->request( mBufferPosition, |
220 // begin middle1 middle2 end |
215 mBufferPosition + mBufferSize -1 ); |
221 int size = mBufferSize/3; |
216 |
222 int begin = mBufferPosition; |
217 if (mBufferPosition + mBufferSize < mTotalCount){ |
223 int middle1 = begin + size; |
218 mObserver->release(mBufferPosition + mBufferSize, mTotalCount); |
224 int middle2 = middle1 + size; |
|
225 int end = mBufferPosition + mBufferSize -1; //Can not be middle2 + size, mBufferSize/3 can be not equal size |
|
226 |
|
227 TX_LOG_ARGS(QString("aPosition:%0 begin:%1 middle1:%2 c:%3 end:%4").arg(aPosition).arg(begin).arg(middle1).arg(c).arg(end) ); |
|
228 |
|
229 if (aPosition >=begin && aPosition < middle1) { //aPosition is in begining, let's load from top |
|
230 mObserver->request(begin, end, HgBufferManagerObserver::HgRequestOrderAscending); |
|
231 } else if (aPosition >= middle1 && aPosition < middle2) {//aPosition is in the middle, let's load from middle |
|
232 HgBufferManagerObserver::HgRequestOrder order = HgBufferManagerObserver::HgRequestOrderAscending; |
|
233 if (oldPos > mBufferPosition) { |
|
234 order = HgBufferManagerObserver::HgRequestOrderDescending; |
|
235 } |
|
236 mObserver->request(middle1, middle2, order); |
|
237 if (order == HgBufferManagerObserver::HgRequestOrderAscending) { |
|
238 mObserver->request(middle2, end, order); |
|
239 mObserver->request(begin, middle1 -1, order); |
|
240 } else { |
|
241 mObserver->request(begin, middle1 -1, order); |
|
242 mObserver->request(middle2, end, order); |
|
243 } |
|
244 } else if (aPosition >= middle2 && aPosition <= end) { //aPosition is in end, let's load from bottom |
|
245 mObserver->request(begin, end, HgBufferManagerObserver::HgRequestOrderDescending); |
219 } |
246 } |
220 |
247 |
221 mDiff = 0; |
248 mDiff = 0; |
222 mResetOrdered = false; |
249 mResetOrdered = false; |
223 mRequestStart = 0; |
250 mRequestStart = 0; |
227 |
254 |
228 } |
255 } |
229 |
256 |
230 void HgBufferManager::aboutToRemoveItem(int pos) |
257 void HgBufferManager::aboutToRemoveItem(int pos) |
231 { |
258 { |
232 if(pos < 0 || pos >= mTotalCount ){ |
259 if (pos < 0 || pos >= mTotalCount) { |
233 return; |
260 return; |
234 } |
261 } |
235 |
262 |
236 if ( pos >= mBufferPosition && pos < mBufferPosition + mBufferSize ){ |
263 if (pos >= mBufferPosition && pos < mBufferPosition + mBufferSize) { |
237 mObserver->release(pos, pos); |
264 mObserver->release(pos, pos); |
238 } |
265 } |
239 } |
266 } |
240 |
267 |
241 void HgBufferManager::removedItem(int pos) |
268 void HgBufferManager::removedItem(int pos) |
242 { |
269 { |
243 if(pos < 0 || pos >= mTotalCount ){ |
270 if (pos < 0 || pos >= mTotalCount) { |
244 return; |
271 return; |
245 } |
272 } |
246 |
273 |
247 mTotalCount--; |
274 mTotalCount--; |
248 if( mTotalCount >= mBufferSize ){ |
275 if (mTotalCount >= mBufferSize) { |
249 if (pos < mBufferPosition){ //before buffer pos is >=0 |
276 if (pos < mBufferPosition) { //before buffer pos is >=0 |
250 mBufferPosition--; |
277 mBufferPosition--; |
251 } else if (pos >= mBufferPosition && pos < mBufferPosition + mBufferSize){ |
278 } else if (pos >= mBufferPosition && pos < mBufferPosition + mBufferSize) { |
252 if( mBufferPosition + mBufferSize <= mTotalCount ){ |
279 if (mBufferPosition + mBufferSize <= mTotalCount) { |
253 // Requested from the end |
280 // Requested from the end |
254 mObserver->request( mBufferPosition + mBufferSize - 1, |
281 mObserver->request(mBufferPosition + mBufferSize - 1, |
255 mBufferPosition + mBufferSize - 1 ); |
282 mBufferPosition + mBufferSize - 1); |
256 }else if( mBufferPosition > 0 ){ |
283 }else if (mBufferPosition > 0) { |
257 // Move buffer and request from the beginning |
284 // Move buffer and request from the beginning |
258 mBufferPosition--; |
285 mBufferPosition--; |
259 mObserver->request( mBufferPosition, |
286 mObserver->request(mBufferPosition, mBufferPosition); |
260 mBufferPosition ); |
|
261 } |
287 } |
262 } |
288 } |
263 } |
289 } |
264 } |
290 } |
265 |
291 |
266 void HgBufferManager::aboutToInsertItem(int pos) |
292 void HgBufferManager::aboutToInsertItem(int pos) |
267 { |
293 { |
268 if(pos < 0 || pos > mTotalCount ){ |
294 if (pos < 0 || pos > mTotalCount) { |
269 return; |
295 return; |
270 } |
296 } |
271 |
297 |
272 if ( pos >= mBufferPosition && pos < mBufferPosition + mBufferSize ){ |
298 if (pos >= mBufferPosition && pos < mBufferPosition + mBufferSize) { |
273 if( mBufferPosition + mBufferSize < mTotalCount ){ |
299 if (mBufferPosition + mBufferSize < mTotalCount) { |
274 // Release from the end of the buffer |
300 // Release from the end of the buffer |
275 mObserver->release(mBufferPosition + mBufferSize - 1, mBufferPosition + mBufferSize - 1); |
301 mObserver->release(mBufferPosition + mBufferSize - 1, mBufferPosition + mBufferSize - 1); |
276 } |
302 } |
277 } |
303 } |
278 } |
304 } |
279 |
305 |
280 void HgBufferManager::insertedItem(int pos) |
306 void HgBufferManager::insertedItem(int pos) |
281 { |
307 { |
282 if(pos < 0 || pos > mTotalCount ){ |
308 if ( pos < 0 || pos > mTotalCount) { |
283 return; |
309 return; |
284 } |
310 } |
285 |
311 |
286 mTotalCount++; |
312 mTotalCount++; |
287 if ( pos >= mBufferPosition && pos < mBufferPosition + mBufferSize ){ |
313 if (pos >= mBufferPosition && pos < mBufferPosition + mBufferSize) { |
288 mObserver->request(pos, pos); |
314 mObserver->request(pos, pos); |
289 }else if (pos<mBufferPosition){ //if we have inserted item before buffer, we should move buffer. |
315 }else if (pos<mBufferPosition) { //if we have inserted item before buffer, we should move buffer. |
290 mBufferPosition++; |
316 mBufferPosition++; |
291 } |
317 } |
292 } |
318 } |
293 |
319 |
294 //eof |
320 //eof |