| 
     
      
      
      From: <aa...@us...> - 2016-03-05 12:28:07
      
     
   | 
Revision: 63096
          http://sourceforge.net/p/firebird/code/63096
Author:   aafemt
Date:     2016-03-05 12:28:04 +0000 (Sat, 05 Mar 2016)
Log Message:
-----------
Optimized hash function for lock manager and hash join
Modified Paths:
--------------
    firebird/trunk/builds/posix/make.rules
    firebird/trunk/builds/posix/prefix.linux
    firebird/trunk/builds/posix/prefix.linux_amd64
    firebird/trunk/builds/win32/msvc10/common.vcxproj
    firebird/trunk/builds/win32/msvc10/common.vcxproj.filters
    firebird/trunk/builds/win32/msvc12/common.vcxproj
    firebird/trunk/builds/win32/msvc12/common.vcxproj.filters
    firebird/trunk/src/common/classes/Hash.h
    firebird/trunk/src/jrd/lck.cpp
    firebird/trunk/src/jrd/recsrc/HashJoin.cpp
    firebird/trunk/src/lock/lock.cpp
    firebird/trunk/src/lock/print.cpp
Added Paths:
-----------
    firebird/trunk/src/common/CRC32C.cpp
    firebird/trunk/src/common/classes/Hash.cpp
Modified: firebird/trunk/builds/posix/make.rules
===================================================================
--- firebird/trunk/builds/posix/make.rules	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/posix/make.rules	2016-03-05 12:28:04 UTC (rev 63096)
@@ -32,16 +32,16 @@
 
 
 # Please don't use compiler/platform specific flags here - nmcc 02-Nov-2002
-WFLAGS:=-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include $(CPPFLAGS)
+WFLAGS =-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include $(CPPFLAGS)
 
 ifeq ($(TARGET),Release)
-  WFLAGS:= $(WFLAGS) $(PROD_FLAGS)
+  WFLAGS += $(PROD_FLAGS)
 else
-  WFLAGS:= $(WFLAGS) $(DEV_FLAGS) -DDEV_BUILD
+  WFLAGS += $(DEV_FLAGS) -DDEV_BUILD
 endif
 
-WCFLAGS:= $(WFLAGS) $(THR_FLAGS) $(CFLAGS) $(GLOB_OPTIONS)
-WCXXFLAGS:= $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
+WCFLAGS = $(WFLAGS) $(THR_FLAGS) $(CFLAGS) $(GLOB_OPTIONS)
+WCXXFLAGS = $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
 
 # Here we have definitions for using the preprocessor.
 
Modified: firebird/trunk/builds/posix/prefix.linux
===================================================================
--- firebird/trunk/builds/posix/prefix.linux	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/posix/prefix.linux	2016-03-05 12:28:04 UTC (rev 63096)
@@ -25,3 +25,6 @@
 PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
 #DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS)
 DEV_FLAGS=-p $(COMMON_FLAGS) $(WARN_FLAGS)
+
+# This file must be compiled with SSE4.2 support
+%/CRC32C.o: COMMON_FLAGS += -msse4
Modified: firebird/trunk/builds/posix/prefix.linux_amd64
===================================================================
--- firebird/trunk/builds/posix/prefix.linux_amd64	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/posix/prefix.linux_amd64	2016-03-05 12:28:04 UTC (rev 63096)
@@ -25,3 +25,6 @@
 PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
 #DEV_FLAGS=-DUSE_VALGRIND $(COMMON_FLAGS) $(WARN_FLAGS)
 DEV_FLAGS=$(COMMON_FLAGS) $(WARN_FLAGS) -fmax-errors=8
+
+# This file must be compiled with SSE4.2 support
+%/CRC32C.o: COMMON_FLAGS += -msse4
Modified: firebird/trunk/builds/win32/msvc10/common.vcxproj
===================================================================
--- firebird/trunk/builds/win32/msvc10/common.vcxproj	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/win32/msvc10/common.vcxproj	2016-03-05 12:28:04 UTC (rev 63096)
@@ -30,6 +30,7 @@
     <ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\DbImplementation.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\fb_string.cpp" />
+    <ClCompile Include="..\..\..\src\common\classes\Hash.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\ImplementHelper.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\init.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\InternalMessageBuffer.cpp" />
@@ -49,6 +50,16 @@
     <ClCompile Include="..\..\..\src\common\config\ConfigCache.cpp" />
     <ClCompile Include="..\..\..\src\common\config\config_file.cpp" />
     <ClCompile Include="..\..\..\src\common\config\dir_list.cpp" />
+    <ClCompile Include="..\..\..\src\common\CRC32C.cpp">
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IntrinsicFunctions>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IntrinsicFunctions>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IntrinsicFunctions>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IntrinsicFunctions>
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ProgramDatabase</DebugInformationFormat>
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ProgramDatabase</DebugInformationFormat>
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
+      <DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
     <ClCompile Include="..\..\..\src\common\cvt.cpp" />
     <ClCompile Include="..\..\..\src\common\db_alias.cpp" />
     <ClCompile Include="..\..\..\src\common\dllinst.cpp" />
Modified: firebird/trunk/builds/win32/msvc10/common.vcxproj.filters
===================================================================
--- firebird/trunk/builds/win32/msvc10/common.vcxproj.filters	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/win32/msvc10/common.vcxproj.filters	2016-03-05 12:28:04 UTC (rev 63096)
@@ -210,6 +210,12 @@
     <ClCompile Include="..\..\..\src\common\Tokens.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\src\common\classes\Hash.cpp">
+      <Filter>classes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\common\CRC32C.cpp">
+      <Filter>classes</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\src\common\xdr_proto.h">
Modified: firebird/trunk/builds/win32/msvc12/common.vcxproj
===================================================================
--- firebird/trunk/builds/win32/msvc12/common.vcxproj	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/win32/msvc12/common.vcxproj	2016-03-05 12:28:04 UTC (rev 63096)
@@ -30,6 +30,7 @@
     <ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\DbImplementation.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\fb_string.cpp" />
+    <ClCompile Include="..\..\..\src\common\classes\Hash.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\ImplementHelper.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\init.cpp" />
     <ClCompile Include="..\..\..\src\common\classes\InternalMessageBuffer.cpp" />
@@ -49,6 +50,12 @@
     <ClCompile Include="..\..\..\src\common\config\ConfigCache.cpp" />
     <ClCompile Include="..\..\..\src\common\config\config_file.cpp" />
     <ClCompile Include="..\..\..\src\common\config\dir_list.cpp" />
+    <ClCompile Include="..\..\..\src\common\CRC32C.cpp">
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IntrinsicFunctions>
+      <EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IntrinsicFunctions>
+      <EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+    </ClCompile>
     <ClCompile Include="..\..\..\src\common\cvt.cpp" />
     <ClCompile Include="..\..\..\src\common\db_alias.cpp" />
     <ClCompile Include="..\..\..\src\common\dllinst.cpp" />
Modified: firebird/trunk/builds/win32/msvc12/common.vcxproj.filters
===================================================================
--- firebird/trunk/builds/win32/msvc12/common.vcxproj.filters	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/builds/win32/msvc12/common.vcxproj.filters	2016-03-05 12:28:04 UTC (rev 63096)
@@ -210,6 +210,12 @@
     <ClCompile Include="..\..\..\src\common\Tokens.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\src\common\classes\Hash.cpp">
+      <Filter>classes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\common\CRC32C.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\src\common\xdr_proto.h">
Added: firebird/trunk/src/common/CRC32C.cpp
===================================================================
--- firebird/trunk/src/common/CRC32C.cpp	                        (rev 0)
+++ firebird/trunk/src/common/CRC32C.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -0,0 +1,69 @@
+/*
+ *	PROGRAM:	Common Library
+ *	MODULE:		CRC32C.cpp
+ *	DESCRIPTION:	Hardware-accelerated hash calculation
+ *
+ *  The contents of this file are subject to the Initial
+ *  Developer's Public License Version 1.0 (the "License");
+ *  you may not use this file except in compliance with the
+ *  License. You may obtain a copy of the License at
+ *  http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+ *
+ *  Software distributed under the License is distributed AS IS,
+ *  WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing rights
+ *  and limitations under the License.
+ *
+ *  The Original Code was created by Dmitry Sibiryakov
+ *  for the Firebird Open Source RDBMS project.
+ *
+ *  Copyright (c) 2015 Dmitry Sibiryakov
+ *  and all contributors signed below.
+ *
+ *  All Rights Reserved.
+ *  Contributor(s): ______________________________________.
+ *
+ */
+
+#include "firebird.h"
+
+// Can be used only on x86 architectures
+// WARNING: With GCC must be compiled separately with -msse4.2 flag
+#if defined(_M_IX86) || defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
+
+#include <nmmintrin.h>
+#include "../common/classes/Hash.h"
+
+namespace Firebird
+{
+unsigned int CRC32C(const unsigned char* value, unsigned int length)
+{
+	unsigned int hash_value = 0;
+	if (length == 1)
+	{
+		return _mm_crc32_u8(hash_value, *value);
+	}
+	if (length == 2)
+	{
+		return _mm_crc32_u16(hash_value, *(unsigned short*)value);
+	}
+	while (length >= 4)
+	{
+		hash_value = _mm_crc32_u32(hash_value, *(unsigned int*)value);
+		value += 4;
+		length -= 4;
+	}
+	if (length >= 2)
+	{
+		hash_value = _mm_crc32_u16(hash_value, *(unsigned short*)value);
+		length -= 2;
+	}
+	if (length)
+	{
+		value += 2;
+		hash_value = _mm_crc32_u8(hash_value, *value);
+	}
+	return hash_value;
+}
+} // namespace
+#endif // architecture check
Property changes on: firebird/trunk/src/common/CRC32C.cpp
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: firebird/trunk/src/common/classes/Hash.cpp
===================================================================
--- firebird/trunk/src/common/classes/Hash.cpp	                        (rev 0)
+++ firebird/trunk/src/common/classes/Hash.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -0,0 +1,98 @@
+/*
+ *	PROGRAM:	Common Library
+ *	MODULE:		Hash.cpp
+ *	DESCRIPTION:	Hash of data
+ *
+ *  The contents of this file are subject to the Initial
+ *  Developer's Public License Version 1.0 (the "License");
+ *  you may not use this file except in compliance with the
+ *  License. You may obtain a copy of the License at
+ *  http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+ *
+ *  Software distributed under the License is distributed AS IS,
+ *  WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing rights
+ *  and limitations under the License.
+ *
+ *  The Original Code was created by Inprise Corporation
+ *  and its predecessors. Portions created by Inprise Corporation are
+ *  Copyright (C) Inprise Corporation.
+ *
+ *  All Rights Reserved.
+ *  Contributor(s): ______________________________________.
+ *
+ */
+
+#include "firebird.h"
+#include "../common/classes/Hash.h"
+
+namespace Firebird
+{
+
+static unsigned int basicHash(const unsigned char* value, unsigned int length)
+{
+	unsigned int hash_value = 0;
+	unsigned char* p;
+	const unsigned char* q = value;
+	while (length >= 4)
+	{
+		p = (unsigned char*) &hash_value;
+		p[0] += q[0];
+		p[1] += q[1];
+		p[2] += q[2];
+		p[3] += q[3];
+		length -= 4;
+		q += 4;
+	}
+	p = (unsigned char*) &hash_value;
+    if (length >= 2)
+    {
+		p[0] += q[0];
+		p[1] += q[1];
+        length -= 2;
+    }
+    if (length)
+    {
+		q += 2;
+        *p += *q;
+    }
+	return hash_value;
+}
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
+
+#ifdef _MSC_VER
+
+#include <intrin.h>
+#define bit_SSE4_2	(1 << 20)
+// MS VC has its own definition of __cpuid
+static bool SSE4_2Supported()
+{
+	int flags[4];
+	__cpuid(flags, 1);
+	return (flags[2] & bit_SSE4_2) != 0;
+}
+
+#else
+
+#include <cpuid.h>
+// GCC - its own
+static bool SSE4_2Supported()
+{
+	unsigned int eax,ebx,ecx,edx;
+	__cpuid(1, eax, ebx, ecx, edx);
+	return (ecx & bit_SSE4_2) != 0;
+}
+
+#endif
+
+unsigned int CRC32C(const unsigned char* value, unsigned int length);
+
+someHashFunc someHash = SSE4_2Supported()?CRC32C:basicHash;
+#else
+someHashFunc someHash = basicHash;
+#endif // Architecture check
+
+const char* hashName = someHash == CRC32C? "CRC32C": "Basic";
+
+} // namespace
\ No newline at end of file
Property changes on: firebird/trunk/src/common/classes/Hash.cpp
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: firebird/trunk/src/common/classes/Hash.h
===================================================================
--- firebird/trunk/src/common/classes/Hash.h	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/src/common/classes/Hash.h	2016-03-05 12:28:04 UTC (rev 63096)
@@ -331,6 +331,16 @@
 		}; // class iterator
 	}; // class Hash
 
+typedef unsigned int (*someHashFunc)(const unsigned char* value, unsigned int length);
+
+extern someHashFunc someHash;
+extern const char* hashName;
+
+inline unsigned int hash(const void* value, unsigned int length, unsigned int hashSize)
+{
+	return someHash((const unsigned char*)value, length) % hashSize;
+}
+
 } // namespace Firebird
 
 #endif // CLASSES_HASH_H
Modified: firebird/trunk/src/jrd/lck.cpp
===================================================================
--- firebird/trunk/src/jrd/lck.cpp	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/src/jrd/lck.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -28,6 +28,7 @@
 
 #include "firebird.h"
 #include <stdio.h>
+#include "../common/classes/Hash.h"
 #include "../jrd/jrd.h"
 #include "../jrd/lck.h"
 #include "gen/iberror.h"
@@ -59,7 +60,6 @@
 static bool compatible(const Lock*, const Lock*, USHORT);
 static void enqueue(thread_db*, CheckStatusWrapper*, Lock*, USHORT, SSHORT);
 static int external_ast(void*);
-static USHORT hash_func(const UCHAR*, USHORT);
 static void hash_allocate(Lock*);
 static Lock* hash_get_lock(Lock*, USHORT*, Lock***);
 static void hash_insert_lock(Lock*);
@@ -954,38 +954,6 @@
 }
 
 
-
-static USHORT hash_func(const UCHAR* value, USHORT length)
-{
-/**************************************
- *
- *	h a s h
- *
- **************************************
- *
- * Functional description
- *	Provide a repeatable hash value based
- *	on the passed key.
- *
- **************************************/
-
-	// Hash the value, preserving its distribution as much as possible
-
-	ULONG hash_value = 0;
-	UCHAR* p = 0;
-	const UCHAR* q = value;
-
-	for (USHORT l = 0; l < length; l++)
-	{
-		if (!(l & 3))
-			p = (UCHAR*) &hash_value;
-		*p++ += *q++;
-	}
-
-	return (USHORT) (hash_value % LOCK_HASH_SIZE);
-}
-
-
 static void hash_allocate(Lock* lock)
 {
 /**************************************
@@ -1036,7 +1004,7 @@
 	if (!att->att_compatibility_table)
 		hash_allocate(lock);
 
-	const USHORT hash_value = hash_func((UCHAR*) &lock->lck_key, lock->lck_length);
+	const USHORT hash_value = hash(&lock->lck_key, lock->lck_length, LOCK_HASH_SIZE);
 
 	if (hash_slot)
 		*hash_slot = hash_value;
Modified: firebird/trunk/src/jrd/recsrc/HashJoin.cpp
===================================================================
--- firebird/trunk/src/jrd/recsrc/HashJoin.cpp	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/src/jrd/recsrc/HashJoin.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -21,6 +21,7 @@
  */
 
 #include "firebird.h"
+#include "../common/classes/Hash.h"
 #include "../jrd/jrd.h"
 #include "../jrd/btr.h"
 #include "../jrd/req.h"
@@ -249,7 +250,7 @@
 	};
 
 public:
-	HashTable(MemoryPool& pool, size_t streamCount, size_t tableSize = HASH_SIZE)
+	HashTable(MemoryPool& pool, size_t streamCount, unsigned int tableSize = HASH_SIZE)
 		: PermanentStorage(pool), m_streamCount(streamCount),
 		  m_tableSize(tableSize), m_slot(0)
 	{
@@ -265,28 +266,11 @@
 		delete[] m_collisions;
 	}
 
-	size_t hash(ULONG length, const UCHAR* buffer) const
-	{
-		ULONG hash_value = 0;
-
-		UCHAR* p = NULL;
-		const UCHAR* q = buffer;
-		for (size_t l = 0; l < length; l++)
-		{
-			if (!(l & 3))
-				p = (UCHAR*) &hash_value;
-
-			*p++ += *q++;
-		}
-
-		return (hash_value % m_tableSize);
-	}
-
 	void put(size_t stream,
 			 ULONG keyLength, const KeyBuffer* keyBuffer,
 			 ULONG offset, ULONG position)
 	{
-		const size_t slot = hash(keyLength, keyBuffer->begin() + offset);
+		const unsigned int slot = hash(keyBuffer->begin() + offset, keyLength, m_tableSize);
 
 		fb_assert(stream < m_streamCount);
 		fb_assert(slot < m_tableSize);
@@ -304,7 +288,7 @@
 
 	bool setup(ULONG length, const UCHAR* data)
 	{
-		const size_t slot = hash(length, data);
+		const unsigned int slot = hash(data, length, m_tableSize);
 
 		for (size_t i = 0; i < m_streamCount; i++)
 		{
@@ -350,7 +334,7 @@
 
 private:
 	const size_t m_streamCount;
-	const size_t m_tableSize;
+	const unsigned int m_tableSize;
 	CollisionList** m_collisions;
 	size_t m_slot;
 };
Modified: firebird/trunk/src/lock/lock.cpp
===================================================================
--- firebird/trunk/src/lock/lock.cpp	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/src/lock/lock.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -51,6 +51,7 @@
 #include "../common/isc_s_proto.h"
 #include "../common/config/config.h"
 #include "../common/classes/array.h"
+#include "../common/classes/Hash.h"
 #include "../common/classes/semaphore.h"
 #include "../common/classes/init.h"
 #include "../common/classes/timestamp.h"
@@ -2087,7 +2088,6 @@
 }
 #endif
 
-
 lbl* LockManager::find_lock(USHORT series,
 							const UCHAR* value,
 							USHORT length,
@@ -2107,23 +2107,9 @@
  *
  **************************************/
 
-	// Hash the value preserving its distribution as much as possible
-
-	ULONG hash_value = 0;
-	{ // scope
-		UCHAR* p = NULL; // silence uninitialized warning
-		const UCHAR* q = value;
-		for (USHORT l = 0; l < length; l++)
-		{
-			if (!(l & 3))
-				p = (UCHAR*) &hash_value;
-			*p++ += *q++;
-		}
-	} // scope
-
 	// See if the lock already exists
 
-	const USHORT hash_slot = *slot = (USHORT) (hash_value % m_sharedMemory->getHeader()->lhb_hash_slots);
+	const USHORT hash_slot = *slot = (USHORT) Firebird::hash(value, length, m_sharedMemory->getHeader()->lhb_hash_slots);
 	ASSERT_ACQUIRED;
 	srq* const hash_header = &m_sharedMemory->getHeader()->lhb_hash[hash_slot];
 
Modified: firebird/trunk/src/lock/print.cpp
===================================================================
--- firebird/trunk/src/lock/print.cpp	2016-03-05 03:39:36 UTC (rev 63095)
+++ firebird/trunk/src/lock/print.cpp	2016-03-05 12:28:04 UTC (rev 63096)
@@ -851,6 +851,7 @@
 	SLONG hash_max_count = 0;
 	SLONG hash_min_count = 10000000;
 	USHORT i = 0;
+	unsigned int distribution[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 	for (const srq* slot = LOCK_header->lhb_hash; i < LOCK_header->lhb_hash_slots; slot++, i++)
 	{
 		SLONG hash_lock_count = 0;
@@ -864,6 +865,9 @@
 			hash_min_count = hash_lock_count;
 		if (hash_lock_count > hash_max_count)
 			hash_max_count = hash_lock_count;
+		if (hash_lock_count > 20)
+			hash_lock_count = 20;
+		++distribution[hash_lock_count];
 	}
 
 	FPRINTF(outfile, "\tHash slots: %4d, ", LOCK_header->lhb_hash_slots);
@@ -872,6 +876,16 @@
 			hash_min_count, (hash_total_count / LOCK_header->lhb_hash_slots),
 			hash_max_count);
 
+	FPRINTF(outfile, "\tHash lengths distribution:\n");
+	if (hash_max_count >= 20)
+		hash_max_count = 19;
+	for (int i = hash_min_count; i<=hash_max_count; ++i)
+	{
+		FPRINTF(outfile, "\t\t%-2d : %8u\t(%d%%)\n", i, distribution[i], distribution[i]*100/LOCK_header->lhb_hash_slots);
+	}
+	if (hash_max_count == 19)
+		FPRINTF(outfile, "\t\t>  : %8u\t(%d%%)\n", distribution[20], distribution[20]*100/LOCK_header->lhb_hash_slots);
+
 	const shb* a_shb = (shb*) SRQ_ABS_PTR(LOCK_header->lhb_secondary);
 	FPRINTF(outfile,
 			"\tRemove node: %6"SLONGFORMAT", Insert queue: %6"SLONGFORMAT
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
 |