198 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
| /************************************************************************
 | |
|  *
 | |
|  * Copyright (c) 2017 Alibaba.com, Inc. All Rights Reserved
 | |
|  * $Id:  paxos_log_cache.cc,v 1.0 01/16/2017 07:03:27 PM yingqiang.zyq(yingqiang.zyq@alibaba-inc.com) $
 | |
|  *
 | |
|  ************************************************************************/
 | |
| 
 | |
| /**
 | |
|  * @file paxos_log_cache.cc
 | |
|  * @author yingqiang.zyq(yingqiang.zyq@alibaba-inc.com)
 | |
|  * @date 01/16/2017 07:03:27 PM
 | |
|  * @version 1.0
 | |
|  * @brief paxos log cache
 | |
|  *
 | |
|  **/
 | |
| 
 | |
| #include "paxos_log_cache.h"
 | |
| 
 | |
| namespace alisql {
 | |
| 
 | |
| void PaxosLogCache::put(uint64_t beginIndex, uint64_t endIndex, ::google::protobuf::RepeatedPtrField<LogEntry>& entries)
 | |
| {
 | |
|   put(new PaxosLogCacheNode(beginIndex, endIndex, entries));
 | |
| }
 | |
| 
 | |
| void PaxosLogCache::put(PaxosLogCacheNode *newNode)
 | |
| {
 | |
|   for (auto it= logCache_.begin(); it != logCache_.end();)
 | |
|   {
 | |
|     PaxosLogCacheNode *node= *it;
 | |
|     if (node->endIndex < newNode->beginIndex)
 | |
|     {
 | |
|       if (node->endIndex + 1 != newNode->beginIndex)
 | |
|       {
 | |
|         ++ it;
 | |
|         continue;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // continue append case
 | |
|         byteSize_ -= node->getByteSize();
 | |
|         node->entries.MergeFrom(newNode->entries);
 | |
|         node->endIndex= newNode->endIndex;
 | |
| 
 | |
|         delete newNode;
 | |
|         it= logCache_.erase(it);
 | |
|         newNode= node;
 | |
|         continue;
 | |
|       }
 | |
|     }
 | |
|     else if(node->beginIndex > newNode->endIndex)
 | |
|     {
 | |
|       if (node->beginIndex != newNode->endIndex + 1)
 | |
|       {
 | |
|         byteSize_ += newNode->getByteSize();
 | |
|         logCache_.insert(it, newNode);
 | |
|         return;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // continue preppend case
 | |
|         byteSize_ += newNode->getByteSize();
 | |
|         newNode->entries.MergeFrom(node->entries);
 | |
|         newNode->endIndex= node->endIndex;
 | |
| 
 | |
|         delete node;
 | |
|         *it= newNode;
 | |
|         return;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       //overlap case, need merge.
 | |
|       int bs = (*it)->getByteSize();
 | |
|       PaxosLogCacheNode *leftNode= node, *rightNode= newNode;
 | |
| 
 | |
|       if (node->beginIndex > newNode->beginIndex)
 | |
|       {
 | |
|         /*
 | |
|         uint64_t tmp;
 | |
|         node->entries.Swap(&(newNode->entries));
 | |
|         tmp= newNode->beginIndex;
 | |
|         newNode->beginIndex= node->beginIndex;
 | |
|         node->beginIndex= tmp;
 | |
|         tmp= newNode->endIndex;
 | |
|         newNode->endIndex= node->endIndex;
 | |
|         node->endIndex= tmp;
 | |
|         */
 | |
|         leftNode= newNode;
 | |
|         rightNode= node;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         //node->beginIndex <= newNode->beginIndex
 | |
|       }
 | |
| 
 | |
|       assert(leftNode->beginIndex <= rightNode->beginIndex);
 | |
|       assert(static_cast<uint64_t>(leftNode->entries.size()) == (leftNode->endIndex - leftNode->beginIndex + 1));
 | |
|       assert(static_cast<uint64_t>(rightNode->entries.size()) == (rightNode->endIndex - rightNode->beginIndex + 1));
 | |
| 
 | |
|       if (leftNode->endIndex < rightNode->endIndex)
 | |
|       {
 | |
|         // exclude case
 | |
|         rightNode->entries.DeleteSubrange(0, leftNode->endIndex - rightNode->beginIndex + 1);
 | |
|         leftNode->entries.MergeFrom(rightNode->entries);
 | |
|         leftNode->endIndex= rightNode->endIndex;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // include case
 | |
|         if (node == leftNode)
 | |
|         {
 | |
|           delete rightNode;
 | |
|           return;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       delete rightNode;
 | |
|       byteSize_ -= bs;
 | |
|       it= logCache_.erase(it);
 | |
|       newNode= leftNode;
 | |
|     }
 | |
|   }
 | |
|   byteSize_ += newNode->getByteSize();
 | |
|   logCache_.push_back(newNode);
 | |
| }
 | |
| 
 | |
| PaxosLogCacheNode *PaxosLogCache::get(uint64_t beginIndex)
 | |
| {
 | |
|   for (auto it= logCache_.begin(); it != logCache_.end();)
 | |
|   {
 | |
|     PaxosLogCacheNode *node= *it;
 | |
|     if (node->beginIndex == beginIndex)
 | |
|     {
 | |
|       byteSize_ -= (*it)->getByteSize();
 | |
|       logCache_.erase(it);
 | |
|       return node;
 | |
|     }
 | |
|     else if (node->beginIndex < beginIndex)
 | |
|     {
 | |
|       if (node->endIndex < beginIndex)
 | |
|       {
 | |
|         byteSize_ -= (*it)->getByteSize();
 | |
|         it= logCache_.erase(it);
 | |
|         delete node;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         byteSize_ -= (*it)->getByteSize();
 | |
|         logCache_.erase(it);
 | |
|         node->entries.DeleteSubrange(0, beginIndex - node->beginIndex);
 | |
|         node->beginIndex= beginIndex;
 | |
|         return node;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       //node->beginIndex > beginIndex
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|   }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| void PaxosLogCache::clear()
 | |
| {
 | |
|   for (auto& it : logCache_)
 | |
|     delete it;
 | |
|   byteSize_ = 0;
 | |
|   logCache_.clear();
 | |
| }
 | |
| 
 | |
| PaxosLogCacheNode *PaxosLogCache::debugGet(uint64_t i)
 | |
| {
 | |
|   uint64_t j= 0;
 | |
|   for(auto& it : logCache_)
 | |
|   {
 | |
|     if (j == i)
 | |
|       return it;
 | |
| 
 | |
|     ++j;
 | |
|   }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| int PaxosLogCache::debugGetByteSize()
 | |
| {
 | |
|   int ret = 0;
 | |
|   for (auto& it: logCache_)
 | |
|   {
 | |
|     ret += it->getByteSize();
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| }
 |