21 #define DBTUP_PAGE_MAP_CPP
23 #include <RefConvert.hpp>
24 #include <ndb_limits.h>
26 #include <signaldata/RestoreImpl.hpp>
28 #define DBUG_PAGE_MAP 0
95 Uint32 Dbtup::getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId)
97 DynArr256 map(c_page_map_pool, regFragPtr->m_page_map);
98 Uint32 * ptr = map.get(2 * logicalPageId);
108 Dbtup::getRealpidCheck(Fragrecord* regFragPtr, Uint32 logicalPageId)
110 DynArr256 map(c_page_map_pool, regFragPtr->m_page_map);
111 Uint32 * ptr = map.get(2 * logicalPageId);
112 if (likely(ptr != 0))
115 if ((val & FREE_PAGE_BIT) != 0)
123 Uint32 Dbtup::getNoOfPages(Fragrecord*
const regFragPtr)
125 return regFragPtr->noOfPages;
129 Dbtup::init_page(Fragrecord* regFragPtr, PagePtr pagePtr, Uint32 pageId)
131 pagePtr.p->page_state = ~0;
132 pagePtr.p->frag_page_id = pageId;
133 pagePtr.p->physical_page_id = pagePtr.i;
134 pagePtr.p->nextList = RNIL;
135 pagePtr.p->prevList = RNIL;
139 #define do_check_page_map(x) check_page_map(x)
142 Dbtup::find_page_id_in_list(Fragrecord* fragPtrP, Uint32 pageId)
144 DynArr256 map(c_page_map_pool, fragPtrP->m_page_map);
146 Uint32 prev = FREE_PAGE_RNIL;
147 Uint32 curr = fragPtrP->m_free_page_id_list | FREE_PAGE_BIT;
149 while (curr != FREE_PAGE_RNIL)
151 ndbrequire((curr & FREE_PAGE_BIT) != 0);
152 curr &= ~(Uint32)FREE_PAGE_BIT;
153 const Uint32 * prevPtr = map.get(2 * curr + 1);
154 ndbrequire(prevPtr != 0);
155 ndbrequire(prev == *prevPtr);
160 Uint32 * nextPtr = map.get(2 * curr);
161 ndbrequire(nextPtr != 0);
162 prev = curr | FREE_PAGE_BIT;
170 Dbtup::check_page_map(Fragrecord* fragPtrP)
172 Uint32 max = fragPtrP->m_max_page_no;
173 DynArr256 map(c_page_map_pool, fragPtrP->m_page_map);
175 for (Uint32
i = 0;
i<max;
i++)
177 const Uint32 * ptr = map.get(2*
i);
180 ndbrequire(find_page_id_in_list(fragPtrP,
i) ==
false);
184 Uint32 realpid = *ptr;
187 ndbrequire(find_page_id_in_list(fragPtrP,
i) ==
false);
189 else if (realpid & FREE_PAGE_BIT)
191 ndbrequire(find_page_id_in_list(fragPtrP,
i) ==
true);
196 c_page_pool.
getPtr(pagePtr, realpid);
197 ndbrequire(pagePtr.p->frag_page_id ==
i);
198 ndbrequire(pagePtr.p->physical_page_id == realpid);
204 void Dbtup::check_page_map(Fragrecord*) {}
207 #define do_check_page_map(x)
211 Dbtup::allocFragPage(Uint32 * err, Fragrecord* regFragPtr)
214 Uint32 noOfPagesAllocated = 0;
215 Uint32 list = regFragPtr->m_free_page_id_list;
216 Uint32 max = regFragPtr->m_max_page_no;
217 Uint32 cnt = regFragPtr->noOfPages;
219 allocConsPages(1, noOfPagesAllocated, pagePtr.i);
220 if (noOfPagesAllocated == 0)
223 * err = ZMEM_NOMEM_ERROR;
228 DynArr256 map(c_page_map_pool, regFragPtr->m_page_map);
229 if (list == FREE_PAGE_RNIL)
233 Uint32 * ptr = map.set(2 * pageId);
234 if (unlikely(ptr == 0))
237 returnCommonArea(pagePtr.i, noOfPagesAllocated);
238 * err = ZMEM_NOMEM_ERROR;
241 ndbrequire(* ptr == RNIL);
243 regFragPtr->m_max_page_no = max + 1;
249 Uint32 * ptr = map.set(2 * pageId);
250 ndbrequire(ptr != 0);
254 if (next != FREE_PAGE_RNIL)
257 ndbrequire((next & FREE_PAGE_BIT) != 0);
258 next &= ~FREE_PAGE_BIT;
259 Uint32 * nextPrevPtr = map.set(2 * next + 1);
260 ndbrequire(nextPrevPtr != 0);
261 * nextPrevPtr = FREE_PAGE_RNIL;
263 regFragPtr->m_free_page_id_list = next;
266 regFragPtr->noOfPages = cnt + 1;
267 c_page_pool.
getPtr(pagePtr);
268 init_page(regFragPtr, pagePtr, pageId);
271 ndbout_c(
"alloc -> (%u %u max: %u)", pageId, pagePtr.i,
272 regFragPtr->m_max_page_no);
274 do_check_page_map(regFragPtr);
279 Dbtup::allocFragPage(Uint32 * err,
280 Tablerec* tabPtrP, Fragrecord* fragPtrP, Uint32 page_no)
283 DynArr256 map(c_page_map_pool, fragPtrP->m_page_map);
284 Uint32 * ptr = map.set(2 * page_no);
285 if (unlikely(ptr == 0))
288 * err = ZMEM_NOMEM_ERROR;
291 const Uint32 * prevPtr = map.set(2 * page_no + 1);
294 if (likely(pagePtr.i != RNIL && (pagePtr.i & FREE_PAGE_BIT) == 0))
301 Uint32 cnt = fragPtrP->noOfPages;
302 Uint32 max = fragPtrP->m_max_page_no;
303 Uint32 list = fragPtrP->m_free_page_id_list;
304 Uint32 noOfPagesAllocated = 0;
305 Uint32 next = pagePtr.i;
307 allocConsPages(1, noOfPagesAllocated, pagePtr.i);
308 if (unlikely(noOfPagesAllocated == 0))
311 * err = ZMEM_NOMEM_ERROR;
316 ndbout_c(
"alloc(%u %u max: %u)", page_no, pagePtr.i, max);
326 ndbrequire(prevPtr != 0);
327 Uint32 prev = * prevPtr;
329 if (next == FREE_PAGE_RNIL)
333 if (prev == FREE_PAGE_RNIL)
336 ndbrequire(list == page_no);
337 fragPtrP->m_free_page_id_list = FREE_PAGE_RNIL;
342 Uint32 * prevNextPtr = map.set(2 * (prev & ~(Uint32)FREE_PAGE_BIT));
343 ndbrequire(prevNextPtr != 0);
344 Uint32 prevNext = * prevNextPtr;
345 ndbrequire(prevNext == (page_no | FREE_PAGE_BIT));
346 * prevNextPtr = FREE_PAGE_RNIL;
352 next &= ~(Uint32)FREE_PAGE_BIT;
353 Uint32 * nextPrevPtr = map.set(2 * next + 1);
354 ndbrequire(nextPrevPtr != 0);
355 ndbrequire(* nextPrevPtr == (page_no | FREE_PAGE_BIT));
356 * nextPrevPtr = prev;
357 if (prev == FREE_PAGE_RNIL)
360 ndbrequire(list == page_no);
361 fragPtrP->m_free_page_id_list = next;
366 Uint32 * prevNextPtr = map.get(2 * (prev & ~(Uint32)FREE_PAGE_BIT));
367 ndbrequire(prevNextPtr != 0);
368 ndbrequire(* prevNextPtr == (page_no | FREE_PAGE_BIT));
369 * prevNextPtr = next | FREE_PAGE_BIT;
374 fragPtrP->noOfPages = cnt + 1;
375 if (page_no + 1 > max)
378 fragPtrP->m_max_page_no = page_no + 1;
380 ndbout_c(
"new max: %u", fragPtrP->m_max_page_no);
383 c_page_pool.
getPtr(pagePtr);
384 init_page(fragPtrP, pagePtr, page_no);
385 convertThPage((Fix_page*)pagePtr.p, tabPtrP, MM);
386 pagePtr.p->page_state = ZTH_MM_FREE;
387 free_pages.addFirst(pagePtr);
389 do_check_page_map(fragPtrP);
395 Dbtup::releaseFragPage(Fragrecord* fragPtrP,
396 Uint32 logicalPageId, PagePtr pagePtr)
398 Uint32 list = fragPtrP->m_free_page_id_list;
399 Uint32 cnt = fragPtrP->noOfPages;
400 DynArr256 map(c_page_map_pool, fragPtrP->m_page_map);
401 Uint32 * next = map.set(2 * logicalPageId);
402 Uint32 * prev = map.set(2 * logicalPageId + 1);
403 ndbrequire(next != 0 && prev != 0);
405 returnCommonArea(pagePtr.i, 1);
410 const char * where = 0;
411 if (list == FREE_PAGE_RNIL)
414 * next = * prev = FREE_PAGE_RNIL;
415 fragPtrP->m_free_page_id_list = logicalPageId;
421 * next = list | FREE_PAGE_BIT;
422 * prev = FREE_PAGE_RNIL;
423 fragPtrP->m_free_page_id_list = logicalPageId;
424 Uint32 * nextPrevPtr = map.set(2 * list + 1);
425 ndbrequire(nextPrevPtr != 0);
426 ndbrequire(*nextPrevPtr == FREE_PAGE_RNIL);
427 * nextPrevPtr = logicalPageId | FREE_PAGE_BIT;
431 fragPtrP->noOfPages = cnt - 1;
433 ndbout_c(
"release(%u %u)@%s", logicalPageId, pagePtr.i, where);
434 do_check_page_map(fragPtrP);
437 void Dbtup::errorHandler(Uint32 errorCode)
456 Dbtup::rebuild_page_free_list(
Signal* signal)
459 fragOpPtr.i = signal->theData[1];
460 Uint32 pageId = signal->theData[2];
461 Uint32 tail = signal->theData[3];
462 ptrCheckGuard(fragOpPtr, cnoOfFragoprec, fragoperrec);
465 fragPtr.i= fragOpPtr.p->fragPointer;
466 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
468 if (pageId == fragPtr.p->m_max_page_no)
471 conf->senderRef = reference();
472 conf->senderData = fragOpPtr.p->m_senderData;
473 sendSignal(fragOpPtr.p->m_senderRef,
474 GSN_RESTORE_LCP_CONF, signal,
475 RestoreLcpConf::SignalLength, JBB);
477 releaseFragoperrec(fragOpPtr);
481 DynArr256 map(c_page_map_pool, fragPtr.p->m_page_map);
482 Uint32* nextPtr = map.set(2 * pageId);
483 Uint32* prevPtr = map.set(2 * pageId + 1);
486 ndbrequire(nextPtr != 0 && prevPtr != 0);
488 if (* nextPtr == RNIL)
500 ndbrequire(fragPtr.p->m_free_page_id_list == FREE_PAGE_RNIL);
501 fragPtr.p->m_free_page_id_list = pageId;
502 *nextPtr = FREE_PAGE_RNIL;
503 *prevPtr = FREE_PAGE_RNIL;
511 ndbrequire(fragPtr.p->m_free_page_id_list != FREE_PAGE_RNIL);
513 *nextPtr = FREE_PAGE_RNIL;
514 *prevPtr = tail | FREE_PAGE_BIT;
516 Uint32 * prevNextPtr = map.set(2 * tail);
517 ndbrequire(prevNextPtr != 0);
518 ndbrequire(* prevNextPtr == FREE_PAGE_RNIL);
519 * prevNextPtr = pageId | FREE_PAGE_BIT;
526 ndbout_c(
"adding page %u to free list @ %s", pageId, where);
530 signal->theData[0] = ZREBUILD_FREE_PAGE_LIST;
531 signal->theData[1] = fragOpPtr.i;
532 signal->theData[2] = pageId + 1;
533 signal->theData[3] = tail;
534 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);