From 3a57e525009ade2aa039b0bab33e4b10eda36bf4 Mon Sep 17 00:00:00 2001
From: sfan5 <sfan5@live.de>
Date: Mon, 19 Sep 2016 20:06:39 +0200
Subject: [PATCH] Do not serialize empty NodeMetadata

This commit fixes #4516, though note that this will gradually fix MapBlocks
as they are used/modified and thus re-serialized.
---
 src/nodemetadata.cpp | 23 ++++++++++++++++++++---
 src/nodemetadata.h   |  3 +++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp
index 126889ecf..0801a028b 100644
--- a/src/nodemetadata.cpp
+++ b/src/nodemetadata.cpp
@@ -74,6 +74,11 @@ void NodeMetadata::clear()
 	m_inventory->clear();
 }
 
+bool NodeMetadata::empty() const
+{
+	return m_stringvars.size() == 0 && m_inventory->getLists().size() == 0;
+}
+
 /*
 	NodeMetadataList
 */
@@ -84,14 +89,13 @@ void NodeMetadataList::serialize(std::ostream &os) const
 		Version 0 is a placeholder for "nothing to see here; go away."
 	*/
 
-	if(m_data.empty()){
+	u16 count = countNonEmpty();
+	if (count == 0) {
 		writeU8(os, 0); // version
 		return;
 	}
 
 	writeU8(os, 1); // version
-
-	u16 count = m_data.size();
 	writeU16(os, count);
 
 	for(std::map<v3s16, NodeMetadata*>::const_iterator
@@ -100,6 +104,8 @@ void NodeMetadataList::serialize(std::ostream &os) const
 	{
 		v3s16 p = i->first;
 		NodeMetadata *data = i->second;
+		if (data->empty())
+			continue;
 
 		u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X;
 		writeU16(os, p16);
@@ -200,6 +206,17 @@ void NodeMetadataList::clear()
 	m_data.clear();
 }
 
+int NodeMetadataList::countNonEmpty() const
+{
+	int n = 0;
+	std::map<v3s16, NodeMetadata*>::const_iterator it;
+	for (it = m_data.begin(); it != m_data.end(); ++it) {
+		if (!it->second->empty())
+			n++;
+	}
+	return n;
+}
+
 std::string NodeMetadata::getString(const std::string &name,
 	unsigned short recursion) const
 {
diff --git a/src/nodemetadata.h b/src/nodemetadata.h
index 8d1298212..da1bf595d 100644
--- a/src/nodemetadata.h
+++ b/src/nodemetadata.h
@@ -47,6 +47,7 @@ class NodeMetadata
 	void deSerialize(std::istream &is);
 
 	void clear();
+	bool empty() const;
 
 	// Generic key/value store
 	std::string getString(const std::string &name, unsigned short recursion = 0) const;
@@ -94,6 +95,8 @@ class NodeMetadataList
 	void clear();
 
 private:
+	int countNonEmpty() const;
+
 	std::map<v3s16, NodeMetadata *> m_data;
 };
 
-- 
GitLab