From 42cd81b9783d848350ac60b88c11a80ccae2f797 Mon Sep 17 00:00:00 2001 From: Minjune Date: Thu, 16 Dec 2021 15:38:16 +0900 Subject: [PATCH 1/2] module12 --- module12/README.md | 167 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 module12/README.md diff --git a/module12/README.md b/module12/README.md new file mode 100644 index 0000000..2622ae2 --- /dev/null +++ b/module12/README.md @@ -0,0 +1,167 @@ +## dwb_slots_hash_insert () + +```C +/* + * dwb_slots_hash_insert () - Insert entry in slots hash. + * + * return : Error code. + * thread_p (in): The thread entry. + * vpid(in): The page identifier. + * slot(in): The DWB slot. + * inserted (out): 1, if slot inserted in hash. + */ + +STATIC_INLINE int +dwb_slots_hash_insert (THREAD_ENTRY * thread_p, VPID * vpid, DWB_SLOT * slot, bool * inserted) +{ + int error_code = NO_ERROR; + // NO_ERROR : 0 + DWB_SLOTS_HASH_ENTRY *slots_hash_entry = NULL; + + assert (vpid != NULL && slot != NULL && inserted != NULL); + // vpid, slot, inserted == NULL -> crash + + *inserted = dwb_Global.slots_hashmap.find_or_insert (thread_p, *vpid, slots_hash_entry); +/* + * lf_hash_find_or_insert () - find or insert an entry in the hash table + hashmap에서 vpid를 찾으면 위치를 저장하고, 없으면 insert + find -> 0 insert -> 1 + */ + assert (VPID_EQ (&slots_hash_entry->vpid, &slot->vpid)); + /* + * #define VPID_EQ(vpid_ptr1,vpid_ptr2) + * ((vpid_ptr1) == (vpid_ptr2) || ((vpid_ptr1)->pageid == (vpid_ptr2)->pageid && (vpid_ptr1)->volid == (vpid_ptr2)->volid)) + * 같은 주소를 가르키거나, 페이지 아이디가 같거나, volid가 같아야 한다. + */ + assert (slots_hash_entry->vpid.pageid == slot->io_page->prv.pageid + && slots_hash_entry->vpid.volid == slot->io_page->prv.volid); +/* +* prv.page id, prv.volid ? ? +*/ + if (!(*inserted)) // *inserted == 0 인경우, find 한 경우 + { + assert (slots_hash_entry->slot != NULL); + // slot == NULL -> crash + if (LSA_LT (&slot->lsa, &slots_hash_entry->slot->lsa)) + // log 는 순서대로 쌓인다. + // slot의 lsa보다, slots_hash_entry의 lsa가 최신인 경우 + // 같은 정보가 중복으로 들어온 경우? + { + dwb_log ("DWB hash find key (%d, %d), the LSA=(%lld,%d), better than (%lld,%d): \n", + vpid->volid, vpid->pageid, slots_hash_entry->slot->lsa.pageid, + slots_hash_entry->slot->lsa.offset, slot->lsa.pageid, slot->lsa.offset); + // The older slot is better than mine - leave it in hash. + pthread_mutex_unlock (&slots_hash_entry->mutex); // unlock + return NO_ERROR; // NO_ERROR 리턴 + } + else if (LSA_EQ (&slot->lsa, &slots_hash_entry->slot->lsa)) + { + /* + * If LSA's are equals, still replace slot in hash. We are in "flushing to disk without logging" case. + * The page was modified but not logged. We have to flush this version since is the latest one. + */ + // LSA 가 동일하더라도 해쉬의 슬롯을 바꾼다. + // Page는 변경되었지만, 로그가 남지는 않았다. flush해야함. + if (slots_hash_entry->slot->block_no == slot->block_no) + { + /* Invalidate the old slot, if is in the same block. We want to avoid duplicates in block at flush. */ + assert (slots_hash_entry->slot->position_in_block < slot->position_in_block); + // slot->position_in_block이 더 최신임을 assert + VPID_SET_NULL (&slots_hash_entry->slot->vpid); + // hash 테이블에 있는 page id 를 null 로 바꿔줌 + fileio_initialize_res (thread_p, slots_hash_entry->slot->io_page, IO_PAGESIZE); + // 초기화 + dwb_log ("Found same page with same LSA in same block - %d - at positions (%d, %d) \n", + slots_hash_entry->slot->position_in_block, slot->position_in_block); + // 로그 남겨줌 + } + else // LSA 가 동일한데, block_no가 다를 때 + { +#if !defined (NDEBUG) // No Debug? + int old_block_no = ATOMIC_INC_32 (&slots_hash_entry->slot->block_no, 0); + // slot_hash_enty의 block_no 반환 + if (old_block_no > 0) + { + /* Be sure that the block containing old page version is flushed first. */ + DWB_BLOCK *old_block = &dwb_Global.blocks[old_block_no]; + DWB_BLOCK *new_block = &dwb_Global.blocks[slot->block_no]; + + /* Maybe we will check that the slot is still in old block. */ + assert ((old_block->version < new_block->version) + || (old_block->version == new_block->version && old_block->block_no < new_block->block_no)); + // new_block 이 더 최신임을 assert한다. + + dwb_log ("Found same page with same LSA in 2 different blocks old = (%d, %d), new = (%d,%d) \n", + old_block_no, slots_hash_entry->slot->position_in_block, new_block->block_no, + slot->position_in_block); + } +#endif + } + } + + dwb_log ("Replace hash key (%d, %d), the new LSA=(%lld,%d), the old LSA = (%lld,%d)", + vpid->volid, vpid->pageid, slot->lsa.pageid, slot->lsa.offset, + slots_hash_entry->slot->lsa.pageid, slots_hash_entry->slot->lsa.offset); + // 바꿀게라고 로그 표시 + } + else // inserted가 됐을때 + { + dwb_log ("Inserted hash key (%d, %d), LSA=(%lld,%d)", vpid->volid, vpid->pageid, slot->lsa.pageid, + slot->lsa.offset); + } + + slots_hash_entry->slot = slot; // 바꿔줌 + pthread_mutex_unlock (&slots_hash_entry->mutex); // unlock + *inserted = true; + + return NO_ERROR; +} +``` + +### DWB_SLOTS_HASH_ENTRY + +```C +/* Slots hash entry. */ +typedef struct dwb_slots_hash_entry DWB_SLOTS_HASH_ENTRY; +struct dwb_slots_hash_entry +{ + VPID vpid; /* Page VPID. */ + + DWB_SLOTS_HASH_ENTRY *stack; /* Used in freelist. */ + DWB_SLOTS_HASH_ENTRY *next; /* Used in hash table. */ + pthread_mutex_t mutex; /* The mutex. */ + UINT64 del_id; /* Delete transaction ID (for lock free). */ + + DWB_SLOT *slot; /* DWB slot containing a page. */ + + // *INDENT-OFF* + dwb_slots_hash_entry () + { + pthread_mutex_init (&mutex, NULL); + } + ~dwb_slots_hash_entry () + { + pthread_mutex_destroy (&mutex); + } + // *INDENT-ON* +}; +``` +### LSA_LT +``` C +bool +LSA_LT (const log_lsa *plsa1, const log_lsa *plsa2) +{ + assert (plsa1 != NULL && plsa2 != NULL); + return *plsa1 < *plsa2; +} +``` + +### LSA_EQ +```C +bool +LSA_EQ (const log_lsa *plsa1, const log_lsa *plsa2) +{ + assert (plsa1 != NULL && plsa2 != NULL); + return *plsa1 == *plsa2; +} +``` From aa4ef8824b119cf564e503e027f54e772e337b97 Mon Sep 17 00:00:00 2001 From: Minjune Date: Thu, 16 Dec 2021 15:59:58 +0900 Subject: [PATCH 2/2] update README.md --- module12/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module12/README.md b/module12/README.md index 2622ae2..b36a832 100644 --- a/module12/README.md +++ b/module12/README.md @@ -24,8 +24,9 @@ dwb_slots_hash_insert (THREAD_ENTRY * thread_p, VPID * vpid, DWB_SLOT * slot, bo *inserted = dwb_Global.slots_hashmap.find_or_insert (thread_p, *vpid, slots_hash_entry); /* * lf_hash_find_or_insert () - find or insert an entry in the hash table - hashmap에서 vpid를 찾으면 위치를 저장하고, 없으면 insert - find -> 0 insert -> 1 + vpid 를 key 값으로 dwb_global 변수의 slots_hashmap 변수에서 해쉬 함수를 사용해 value 를 가져오고 해쉬맵을 탐색한다. +해쉬맵에서 slots_hash_entry 가 있으면 가져오고 inserted 0, +없으면 thread_p의 freelist에서 받아와 해쉬맵에 추가하고 inserted 1로 설정한다. */ assert (VPID_EQ (&slots_hash_entry->vpid, &slot->vpid)); /*