| 666 | } |
| 667 | |
| 668 | fdb_status wal_commit(fdb_txn *txn, struct filemgr *file, |
| 669 | wal_commit_mark_func *func, err_log_callback *log_callback) |
| 670 | { |
| 671 | int prev_commit; |
| 672 | wal_item_action prev_action; |
| 673 | struct wal_item *item; |
| 674 | struct wal_item *_item; |
| 675 | struct list_elem *e1, *e2; |
| 676 | fdb_kvs_id_t kv_id; |
| 677 | fdb_status status; |
| 678 | size_t shard_num; |
| 679 | uint64_t mem_overhead = 0; |
| 680 | |
| 681 | e1 = list_begin(txn->items); |
| 682 | while(e1) { |
| 683 | item = _get_entry(e1, struct wal_item, list_elem_txn); |
| 684 | assert(item->txn == txn); |
| 685 | // Grab the WAL key shard lock. |
| 686 | shard_num = get_checksum((uint8_t*)item->header->key, |
| 687 | item->header->keylen) % |
| 688 | file->wal->num_shards; |
| 689 | spin_lock(&file->wal->key_shards[shard_num].lock); |
| 690 | |
| 691 | if (!(item->flag & WAL_ITEM_COMMITTED)) { |
| 692 | // get KVS ID |
| 693 | if (item->flag & WAL_ITEM_MULTI_KV_INS_MODE) { |
| 694 | buf2kvid(item->header->chunksize, item->header->key, &kv_id); |
| 695 | } else { |
| 696 | kv_id = 0; |
| 697 | } |
| 698 | |
| 699 | item->flag |= WAL_ITEM_COMMITTED; |
| 700 | // append commit mark if necessary |
| 701 | if (func) { |
| 702 | status = func(txn->handle, item->offset); |
| 703 | if (status != FDB_RESULT_SUCCESS) { |
| 704 | fdb_log(log_callback, status, |
| 705 | "Error in appending a commit mark at offset %" _F64 " in " |
| 706 | "a database file '%s'", item->offset, file->filename); |
| 707 | spin_unlock(&file->wal->key_shards[shard_num].lock); |
| 708 | atomic_sub_uint64_t(&file->wal->mem_overhead, mem_overhead); |
| 709 | return status; |
| 710 | } |
| 711 | } |
| 712 | // remove previously committed item |
| 713 | prev_commit = 0; |
| 714 | // next item on the wal_item_header's items |
| 715 | e2 = list_next(&item->list_elem); |
| 716 | while(e2) { |
| 717 | _item = _get_entry(e2, struct wal_item, list_elem); |
| 718 | e2 = list_next(e2); |
| 719 | // committed but not flush-ready |
| 720 | // (flush-readied item will be removed by flushing) |
| 721 | if ((_item->flag & WAL_ITEM_COMMITTED) && |
| 722 | !(_item->flag & WAL_ITEM_FLUSH_READY)) { |
| 723 | // remove from list & hash |
| 724 | list_remove(&item->header->items, &_item->list_elem); |
| 725 | if (file->config->seqtree_opt == FDB_SEQTREE_USE) { |
no test coverage detected