From 3b7a445cd78c6b5ab301b5bf44e1ec54a00427f1 Mon Sep 17 00:00:00 2001
From: kwolekr <mirrorisim@gmail.com>
Date: Thu, 14 Feb 2013 18:32:56 -0500
Subject: [PATCH] Add global and per-peer queue limits

---
 src/emerge.cpp | 43 ++++++++++++++++++++++++++++++++++---------
 src/emerge.h   | 32 +++++++++++++++-----------------
 src/mapgen.h   |  1 -
 3 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/emerge.cpp b/src/emerge.cpp
index 728ea7196..82867be50 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -88,7 +88,10 @@ Mapgen *EmergeManager::getMapgen() {
 }
 
 
-bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { ///return false if adding failed, or queue full!
+bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) {
+	std::map<v3s16, BlockEmergeData *>::const_iterator iter;
+	BlockEmergeData *bedata;
+	u16 count;
 	u8 flags = 0;
 	
 	if (allow_generate)
@@ -103,14 +106,30 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
 	{
 		JMutexAutoLock queuelock(queuemutex);
 		
-		std::map<v3s16, u8>::const_iterator iter = blocks_enqueued.find(p);
+		count = blocks_enqueued.size();
+		u16 queuelimit_total = 256;
+		if (count >= queuelimit_total)
+			return false;
+
+		count = peer_queue_count[peer_id];
+		u16 queuelimit_peer = allow_generate ? 1 : 5;
+		if (count >= queuelimit_peer)
+			return false;
+		
+		iter = blocks_enqueued.find(p);
 		if (iter != blocks_enqueued.end()) {
-			flags |= iter->second;
-			blocks_enqueued[p] = flags;
+			bedata = iter->second;
+			bedata->flags |= flags;
 			return true;
 		}
+
+		bedata = new BlockEmergeData;
+		bedata->flags = flags;
+		bedata->peer_requested = peer_id;
+		blocks_enqueued.insert(std::make_pair(p, bedata));
+		
+		peer_queue_count[peer_id] = count + 1;
 		
-		blocks_enqueued.insert(std::make_pair(p, flags));
 		emergethread->blockqueue.push(p);
 	}
 	emergethread->qevent.signal();
@@ -120,6 +139,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
 
 
 bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) {
+	std::map<v3s16, BlockEmergeData *>::iterator iter;
 	JMutexAutoLock queuelock(queuemutex);
 
 	if (emergethread->blockqueue.empty())
@@ -128,12 +148,17 @@ bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) {
 	emergethread->blockqueue.pop();
 	
 	*pos = p;
+	
+	iter = blocks_enqueued.find(p);
+	if (iter == blocks_enqueued.end()) 
+		return false; //uh oh, queue and map out of sync!!
 
-	std::map<v3s16, u8>::iterator iter = blocks_enqueued.find(p);
-	if (iter == blocks_enqueued.end()) //uh oh, this isn't right!!!!!!!!!!!!!!!!!!
-		return false;
+	BlockEmergeData *bedata = iter->second;
+	*flags = bedata->flags;
+	
+	peer_queue_count[bedata->peer_requested]--;
 
-	*flags = iter->second;
+	delete bedata;
 	blocks_enqueued.erase(iter);
 	
 	return true;
diff --git a/src/emerge.h b/src/emerge.h
index 0acc89a6d..5f73dcd86 100644
--- a/src/emerge.h
+++ b/src/emerge.h
@@ -14,8 +14,6 @@ class Biome;
 class BiomeDefManager;
 class EmergeThread;
 class ManualMapVoxelManipulator;
-//class ServerMap;
-//class MapBlock;
 
 #include "server.h"
 
@@ -29,20 +27,19 @@ struct BlockMakeData {
 	UniqueQueue<v3s16> transforming_liquid;
 	INodeDefManager *nodedef;
 
-//	BlockMakeData();
-//	~BlockMakeData();
-	
-BlockMakeData():
-	no_op(false),
-	vmanip(NULL),
-	seed(0),
-	nodedef(NULL)
-{}
-
-~BlockMakeData()
-{
-	delete vmanip;
-}
+	BlockMakeData():
+		no_op(false),
+		vmanip(NULL),
+		seed(0),
+		nodedef(NULL)
+	{}
+
+	~BlockMakeData() { delete vmanip; }
+};
+
+struct BlockEmergeData {
+	u16 peer_requested;
+	u8 flags;
 };
 
 class EmergeManager {
@@ -53,7 +50,8 @@ public:
 	MapgenParams *params;
 
 	JMutex queuemutex;
-	std::map<v3s16, u8> blocks_enqueued; //change to a hashtable later
+	std::map<v3s16, BlockEmergeData *> blocks_enqueued;
+	std::map<u16, u16> peer_queue_count;
 	Mapgen *mapgen;
 	EmergeThread *emergethread;
 
diff --git a/src/mapgen.h b/src/mapgen.h
index c3c209ad1..911e87537 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapnode.h"
 #include "noise.h"
 #include "settings.h"
-//#include "emerge.h"
 #include <map>
 
 /////////////////// Mapgen flags
-- 
2.25.1