static ha_checksum checksum_format_specifier(const char* msg) { ha_checksum chksum= 0; const uchar* p= (const uchar*) msg; const uchar* start= NULL; uint32 num_format_specifiers= 0; while (*p) { if (*p == '%') { start= p+1; /* Entering format specifier */ num_format_specifiers++; } else if (start) { switch(*p) { case 'd': case 'u': case 'x': case 's': chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start)); start= 0; /* Not in format specifier anymore */ break; default: break; } } p++; } if (start) { /* Still inside a format specifier after end of string */ fprintf(stderr, "Still inside formatspecifier after end of string" " in'%s'\n", msg); DBUG_ASSERT(start==0); } /* Add number of format specifiers to checksum as extra safeguard */ chksum+= num_format_specifiers; return chksum; }
ha_checksum mi_checksum(MI_INFO *info, const uchar *buf) { uint i; ha_checksum crc=0; MI_COLUMNDEF *rec=info->s->rec; for (i=info->s->base.fields ; i-- ; buf+=(rec++)->length) { const uchar *pos; ulong length; switch (rec->type) { case FIELD_BLOB: { length=_mi_calc_blob_length(rec->length- portable_sizeof_char_ptr, buf); memcpy((char*) &pos, buf+rec->length- portable_sizeof_char_ptr, sizeof(char*)); break; } case FIELD_VARCHAR: { uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length-1); if (pack_length == 1) length= (ulong) *(uchar*) buf; else length= uint2korr(buf); pos= buf+pack_length; break; } default: length=rec->length; pos=buf; break; } crc=my_checksum(crc, pos ? pos : (uchar*) "", length); } return crc; }
ha_checksum mi_static_checksum(MI_INFO *info, const uchar *pos) { return my_checksum(0, pos, info->s->base.reclength); }
my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock, int level) { MARIA_SHARE *share= page->info->s; uint block_size= share->block_size; uchar *buff= page->buff; my_bool res; MARIA_PINNED_PAGE page_link; DBUG_ENTER("_ma_write_keypage"); /* The following ensures that for transactional tables we have logged all changes that changes the page size (as the logging code sets page->org_size) */ DBUG_ASSERT(!share->now_transactional || page->size == page->org_size); #ifdef EXTRA_DEBUG /* Safety check */ { uint page_length, nod_flag; page_length= _ma_get_page_used(share, buff); nod_flag= _ma_test_if_nod(share, buff); DBUG_ASSERT(page->size == page_length); DBUG_ASSERT(page->size <= share->max_index_block_size); DBUG_ASSERT(page->flag == _ma_get_keypage_flag(share, buff)); if (page->pos < share->base.keystart || page->pos+block_size > share->state.state.key_file_length || (page->pos & (maria_block_size-1))) { DBUG_PRINT("error",("Trying to write inside key status region: " "key_start: %lu length: %lu page_pos: %lu", (long) share->base.keystart, (long) share->state.state.key_file_length, (long) page->pos)); my_errno=EINVAL; DBUG_ASSERT(0); DBUG_RETURN(1); } DBUG_PRINT("page",("write page at: %lu",(ulong) (page->pos / block_size))); DBUG_DUMP("buff", buff, page_length); DBUG_ASSERT(page_length >= share->keypage_header + nod_flag + page->keyinfo->minlength || maria_in_recovery); } #endif /* Verify that keynr is correct */ DBUG_ASSERT(_ma_get_keynr(share, buff) == page->keyinfo->key_nr); #if defined(EXTRA_DEBUG) && defined(HAVE_valgrind) && defined(NOT_ANYMORE) { /* This is here to catch uninitialized bytes */ uint length= page->size; ulong crc= my_checksum(0, buff, length); int4store(buff + block_size - KEYPAGE_CHECKSUM_SIZE, crc); } #endif page_cleanup(share, page); res= pagecache_write(share->pagecache, &share->kfile, (pgcache_page_no_t) (page->pos / block_size), level, buff, share->page_type, lock, lock == PAGECACHE_LOCK_LEFT_WRITELOCKED ? PAGECACHE_PIN_LEFT_PINNED : (lock == PAGECACHE_LOCK_WRITE_UNLOCK ? PAGECACHE_UNPIN : PAGECACHE_PIN), PAGECACHE_WRITE_DELAY, &page_link.link, LSN_IMPOSSIBLE); if (lock == PAGECACHE_LOCK_WRITE) { /* It was not locked before, we have to unlock it when we unpin pages */ page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK; page_link.changed= 1; push_dynamic(&page->info->pinned_pages, (void*) &page_link); } DBUG_RETURN(res); }