From: kim Date: Wed, 7 Jan 2009 03:02:34 +0000 (+0000) Subject: Added the testCase and memory profiler X-Git-Url: http://git.nguyen.vg/gitweb/?a=commitdiff_plain;h=eb04a05de55af8957aea1353d21b5e5b98bd1006;p=SXSI%2FTextCollection.git Added the testCase and memory profiler git-svn-id: svn+ssh://idea.nguyen.vg/svn/sxsi/trunk/TextCollection@27 3cdefd35-fc62-479d-8e8d-bae585ffb9ca --- diff --git a/HeapProfiler.cpp b/HeapProfiler.cpp new file mode 100644 index 0000000..d3c46f8 --- /dev/null +++ b/HeapProfiler.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + * Installs handlers for malloc(), realloc() and free() * + * * + * Copyright (C) 2006 by Niko Välimäki * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "HeapProfiler.h" + +// Static data +unsigned long HeapProfiler::consumption = 0, HeapProfiler::maxConsumption = 0; +AllocatedBlocks HeapProfiler::blocks; + +// Override initialising hook from the C library. +void (*__malloc_initialize_hook) (void) = HeapProfiler::InitHooks; + +// Variables to save original hooks. +void *(*HeapProfiler::old_malloc_hook)(size_t, const void *); +void (*HeapProfiler::old_free_hook)(void *, const void *); +void *(*HeapProfiler::old_realloc_hook)(void *, size_t, const void *); + +unsigned long HeapProfiler::GetMaxHeapConsumption() { + return maxConsumption; +} + +unsigned long HeapProfiler::GetHeapConsumption() { + return consumption; +} + +void HeapProfiler::InitHooks(void) { + old_malloc_hook = __malloc_hook; + old_free_hook = __free_hook; + old_realloc_hook = __realloc_hook; + __malloc_hook = HeapProfiler::MallocHook; + __free_hook = HeapProfiler::FreeHook; + __realloc_hook = HeapProfiler::ReallocHook; +} + + +void *HeapProfiler::MallocHook (size_t size, const void *caller) { + void *result; + + /* Restore all old hooks */ + __malloc_hook = old_malloc_hook; + __free_hook = old_free_hook; + __realloc_hook = old_realloc_hook; + + /* Call recursively */ + result = malloc (size); + + blocks[result] = (unsigned long)size; + + consumption += (unsigned long)size; + if (consumption > maxConsumption) + maxConsumption = consumption; + + #ifdef DEBUG_HEAPPROFILER + std::cout << "malloc(" << size << ") called from " << caller << " returns " << result << " (" << consumption << ", max " << maxConsumption << ")" << std::endl; + #endif + + /* Save underlying hooks */ + old_malloc_hook = __malloc_hook; + old_free_hook = __free_hook; + old_realloc_hook = __realloc_hook; + + /* Restore our own hooks */ + __malloc_hook = HeapProfiler::MallocHook; + __free_hook = HeapProfiler::FreeHook; + __realloc_hook = HeapProfiler::ReallocHook; + + return result; +} + +void HeapProfiler::FreeHook (void *ptr, const void *caller) { + + /* Restore all old hooks */ + __malloc_hook = old_malloc_hook; + __free_hook = old_free_hook; + __realloc_hook = old_realloc_hook; + + /* Call recursively */ + free (ptr); + + AllocatedBlocks::iterator result = blocks.find(ptr); + if (result != blocks.end()) + { + #ifdef DEBUG_HEAPPROFILER + std::cout << "found: " << (*result).second << std::endl; + #endif + consumption -= (*result).second; + blocks.erase(result); + } else { + #ifdef DEBUG_HEAPPROFILER + std::cout << "not found" << std::endl; + #endif + } + + #ifdef DEBUG_HEAPPROFILER + std::cout << "free(" << ptr << ") called from " << caller << " (" << consumption << ", max " << maxConsumption << ")" << std::endl; + #endif + + /* Save underlying hooks */ + old_malloc_hook = __malloc_hook; + old_free_hook = __free_hook; + old_realloc_hook = __realloc_hook; + + /* Restore our own hooks */ + __malloc_hook = HeapProfiler::MallocHook; + __free_hook = HeapProfiler::FreeHook; + __realloc_hook = HeapProfiler::ReallocHook; +} + + +void *HeapProfiler::ReallocHook (void *ptr, size_t size, const void *caller) { + void *newptr; + + /* Restore all old hooks */ + __malloc_hook = old_malloc_hook; + __free_hook = old_free_hook; + __realloc_hook = old_realloc_hook; + + /* Call recursively */ + newptr = realloc(ptr, size); + + AllocatedBlocks::iterator result = blocks.find(ptr); + if (result != blocks.end()) + { + #ifdef DEBUG_HEAPPROFILER + std::cout << "found: " << (*result).second << std::endl; + #endif + consumption -= (*result).second; + blocks.erase(result); + } else { + #ifdef DEBUG_HEAPPROFILER + std::cout << "not found" << std::endl; + #endif + } + + blocks[newptr] = (unsigned long)size; + consumption += (unsigned long)size; + if (consumption > maxConsumption) + maxConsumption = consumption; + + #ifdef DEBUG_HEAPPROFILER + std::cout << "realloc(" << ptr << ", " << size << ") called from " << caller << ", result " << newptr << " (" << consumption << ", max " << maxConsumption << ")" << std::endl; + #endif + + /* Save underlying hooks */ + old_malloc_hook = __malloc_hook; + old_free_hook = __free_hook; + old_realloc_hook = __realloc_hook; + + /* Restore our own hooks */ + __malloc_hook = HeapProfiler::MallocHook; + __free_hook = HeapProfiler::FreeHook; + __realloc_hook = HeapProfiler::ReallocHook; + + return newptr; +} + diff --git a/HeapProfiler.h b/HeapProfiler.h new file mode 100644 index 0000000..e1c0378 --- /dev/null +++ b/HeapProfiler.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Installs handlers for malloc(), realloc() and free() * + * * + * Copyright (C) 2006 by Niko Välimäki * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _HEAPPROFILER_H_ +#define _HEAPPROFILER_H_ + +#include +#include +#include + +//#define DEBUG_HEAPPROFILER + +typedef std::map AllocatedBlocks; + +class HeapProfiler +{ +public: + static unsigned long GetMaxHeapConsumption(); + static unsigned long GetHeapConsumption(); + + // Prototypes for hooks + static void InitHooks(void); + static void *MallocHook(size_t, const void *); + static void FreeHook(void *, const void *); + static void *ReallocHook(void *, size_t, const void *); + +private: + static unsigned long consumption, maxConsumption; + // Variables to save original hooks. + static void *(*old_malloc_hook)(size_t, const void *); + static void (*old_free_hook)(void *, const void *); + static void *(*old_realloc_hook)(void *, size_t, const void *); + static AllocatedBlocks blocks; +}; + + +#endif diff --git a/dependencies.mk b/dependencies.mk index 4e40bc8..29c07af 100644 --- a/dependencies.mk +++ b/dependencies.mk @@ -10,3 +10,4 @@ pos.o: pos.cpp pos.h rbtree.h handle.h rbtree.o: rbtree.cpp rbtree.h testTextCollection.o: testTextCollection.cpp CSA.h BitRank.h Tools.h \ dynFMI.h bittree.h rbtree.h handle.h pos.h TextCollection.h +HeapProfiler.o: HeapProfiler.h HeapProfiler.cpp \ No newline at end of file diff --git a/makefile b/makefile index 0d90342..7c5bf06 100644 --- a/makefile +++ b/makefile @@ -1,10 +1,12 @@ CC = g++ -CPPFLAGS = -Wall -ansi -pedantic -g +CPPFLAGS = -Wall -ansi -pedantic -g -O2 -DNDEBUG -testTextCollection_obs = testTextCollection.o TextCollection.o CSA.o Tools.o BitRank.o bittree.o handle.o pos.o rbtree.o dynFMI.o +testTextCollection_obs = testTextCollection.o TextCollection.o CSA.o Tools.o BitRank.o bittree.o handle.o pos.o rbtree.o dynFMI.o -testTextCollection: $(testTextCollection_obs) - $(CC) -o testTextCollection $(testTextCollection_obs) +all: $(testTextCollection_obs) + +testTextCollection: $(testTextCollection_obs) HeapProfiler.o + $(CC) -o testTextCollection $(testTextCollection_obs) HeapProfiler.o clean: rm -f core *.o *~ testTextCollection diff --git a/testTextCollection.cpp b/testTextCollection.cpp index d89a328..dd37ff1 100644 --- a/testTextCollection.cpp +++ b/testTextCollection.cpp @@ -1,5 +1,7 @@ // Test driver for text collection #include +#include +#include "HeapProfiler.h" using std::cout; using std::endl; @@ -28,47 +30,23 @@ void printFullResult(TextCollection::full_result fr) int main() { - uchar *text = (uchar*) "acabab"; - TextCollection *csa = TextCollection::InitTextCollection(1); - csa->InsertText(text); - text = (uchar*) "abaca"; - csa->InsertText(text); - text = (uchar*) "abacb"; - csa->InsertText(text); - - csa->MakeStatic(); -// FILE *pFile = fopen ( "mysave.txt" , "rb" ); -// csa->Load(pFile); - - text = csa->GetText(0); - cout << "Text 0: \"" << text << "\"" << endl; - delete [] text; - text = csa->GetText(1); - cout << "Text 1: \"" << text << "\"" << endl; - delete [] text; - text = csa->GetText(2); - cout << "Text 2: \"" << text << "\"" << endl; - delete [] text; - - text = csa->GetText(2, 2, 4); - cout << "Substring of Text 3: \"" << text << "\"" << endl; - delete [] text; - - printf("n:o contains: %u\n", csa->CountContains((uchar *)"ac")); - printf("n:o suffix: %u\n", csa->CountSuffix((uchar *)"b")); - printf("n:o equal: %u\n", csa->CountEqual((uchar *)"acabab")); - printf("is equal: %u\n", csa->IsEqual((uchar *)"abacb")); - - TextCollection::document_result dr; - dr = csa->Contains((uchar*)"ab"); - printDocumentResult(dr); - - TextCollection::full_result fr; - fr = csa->FullContains((uchar *)"ab"); - printFullResult(fr); - -// FILE *pFile2 = fopen ( "mysave.txt" , "wb" ); -// csa->Save(pFile2); - - delete csa; + std::string kbd; + uchar * str = (uchar*) ""; + + TextCollection *csa = TextCollection::InitTextCollection(64); + for(int i = 0; i<1000000; i++){ + csa->InsertText(str); + }; + std::cerr << "Before MakeStatic() [press enter]\n"; + std::cin >> kbd; + std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl; + csa->MakeStatic(); + std::cerr << "After MakeStatic() [press enter]\n"; + std::cin >> kbd; + std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl; + delete csa; + std::cerr << "After Delete [press enter]\n"; + std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl; + std::cin >> kbd; + return 0; }