//===-- ConstString.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/Mutex.h"
#include "llvm/ADT/StringMap.h"

using namespace lldb_private;


//----------------------------------------------------------------------
// The global string pool is implemented as a hash_map that maps
// std::string objects to a uint32_t reference count.
//
// In debug builds the value that is stored in the ConstString objects is
// a C string that is owned by one of the std::string objects in the
// hash map. This was done for visibility purposes when debugging as
// gcc was often generating insufficient debug info for the
// iterator objects.
//
// In release builds, the value that is stored in the ConstString objects
// is the iterator into the ConstString::HashMap. This is much faster when
// it comes to modifying the reference count, and removing strings from
// the pool.
//----------------------------------------------------------------------
class Pool
{
public:
    //------------------------------------------------------------------
    // Default constructor
    //
    // Initialize the member variables and create the empty string.
    //------------------------------------------------------------------
    Pool () :
        m_mutex (Mutex::eMutexTypeRecursive),
        m_string_map ()
    {
    }

    //------------------------------------------------------------------
    // Destructor
    //------------------------------------------------------------------
    ~Pool ()
    {
    }


    static llvm::StringMapEntry<uint32_t> &
    GetStringMapEntryFromKeyData (const char *keyData)
    {
        char *ptr = const_cast<char*>(keyData) - sizeof (llvm::StringMapEntry<uint32_t>);
        return *reinterpret_cast<llvm::StringMapEntry<uint32_t>*>(ptr);
    }

    size_t
    GetConstCStringLength (const char *ccstr)
    {
        if (ccstr)
        {
            llvm::StringMapEntry<uint32_t>&entry = GetStringMapEntryFromKeyData (ccstr);
            return entry.getKey().size();
        }
        return 0;
    }

    const char *
    GetConstCString (const char *cstr)
    {
        if (cstr)
            return GetConstCStringWithLength (cstr, strlen (cstr));
        return NULL;
    }

    const char *
    GetConstCStringWithLength (const char *cstr, int cstr_len)
    {
        if (cstr)
        {
            Mutex::Locker locker (m_mutex);
            llvm::StringRef string_ref (cstr, cstr_len);
            llvm::StringMapEntry<uint32_t>& entry = m_string_map.GetOrCreateValue (string_ref);
            return entry.getKeyData();
        }
        return NULL;
    }

    const char *
    GetConstTrimmedCStringWithLength (const char *cstr, int cstr_len)
    {
        if (cstr)
        {
            int trimmed_len = std::min<int> (strlen (cstr), cstr_len);
            return GetConstCStringWithLength (cstr, trimmed_len);
        }
        return NULL;
    }

    //------------------------------------------------------------------
    // Return the size in bytes that this object and any items in its
    // collection of uniqued strings + reference count values takes in
    // memory.
    //------------------------------------------------------------------
    size_t
    MemorySize() const
    {
        Mutex::Locker locker (m_mutex);
        size_t mem_size = sizeof(Pool);
        const_iterator end = m_string_map.end();
        for (const_iterator pos = m_string_map.begin(); pos != end; ++pos)
        {
            mem_size += sizeof(llvm::StringMapEntry<uint32_t>) + pos->getKey().size();
        }
        return mem_size;
    }

protected:
    //------------------------------------------------------------------
    // Typedefs
    //------------------------------------------------------------------
    typedef llvm::StringMap<uint32_t, llvm::BumpPtrAllocator> StringPool;
    typedef StringPool::iterator iterator;
    typedef StringPool::const_iterator const_iterator;

    //------------------------------------------------------------------
    // Member variables
    //------------------------------------------------------------------
    mutable Mutex m_mutex;
    StringPool m_string_map;
};

//----------------------------------------------------------------------
// Frameworks and dylibs aren't supposed to have global C++
// initializers so we hide the string pool in a static function so
// that it will get initialized on the first call to this static
// function.
//----------------------------------------------------------------------
static Pool &
StringPool()
{
    static Pool string_pool;
    return string_pool;
}

//----------------------------------------------------------------------
// Default constructor
//
// Initializes the string to an empty string.
//----------------------------------------------------------------------
ConstString::ConstString () :
    m_string (NULL)
{
}

//----------------------------------------------------------------------
// Copy constructor
//
// Copies the string value in "rhs" and retains an extra reference
// to the string value in the string pool.
//----------------------------------------------------------------------
ConstString::ConstString (const ConstString& rhs) :
    m_string (rhs.m_string)
{
}

//----------------------------------------------------------------------
// Construct with C String value
//
// Constructs this object with a C string by looking to see if the
// C string already exists in the global string pool. If it does
// exist, it retains an extra reference to the string in the string
// pool. If it doesn't exist, it is added to the string pool with
// a reference count of 1.
//----------------------------------------------------------------------
ConstString::ConstString (const char *cstr) :
    m_string (StringPool().GetConstCString (cstr))
{
}

//----------------------------------------------------------------------
// Construct with C String value with max length
//
// Constructs this object with a C string with a length. If
// the length of the string is greather than "cstr_len", the
// string length will be truncated. This allows substrings to be
// created without the need to NULL terminate the string as it
// is passed into this function.
//
// If the C string already exists in the global string pool, it
// retains an extra reference to the string in the string
// pool. If it doesn't exist, it is added to the string pool with
// a reference count of 1.
//----------------------------------------------------------------------
ConstString::ConstString (const char *cstr, size_t cstr_len) :
    m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
{
}

//----------------------------------------------------------------------
// Destructor
//
// Decrements the reference count on the contained string, and if
// the resulting reference count is zero, then the string is removed
// from the string pool. If the reference count is still greater
// than zero, the string will remain in the string pool
//----------------------------------------------------------------------
ConstString::~ConstString ()
{
}

bool
ConstString::operator < (const ConstString& rhs) const
{
    if (m_string == rhs.m_string)
        return false;

    llvm::StringRef lhs_string_ref (m_string, StringPool().GetConstCStringLength (m_string));
    llvm::StringRef rhs_string_ref (rhs.m_string, StringPool().GetConstCStringLength (rhs.m_string));

    // If both have valid C strings, then return the comparison
    if (lhs_string_ref.data() && rhs_string_ref.data())
        return lhs_string_ref < rhs_string_ref;

    // Else one of them was NULL, so if LHS is NULL then it is less than
    return lhs_string_ref.data() == NULL;
}

//----------------------------------------------------------------------
// Stream the string value "str" to the stream "s"
//----------------------------------------------------------------------
Stream&
lldb_private::operator << (Stream& s, const ConstString& str)
{
    const char *cstr = str.GetCString();
    if (cstr)
        s << cstr;

    return s;
}

size_t
ConstString::GetLength () const
{
    return StringPool().GetConstCStringLength (m_string);
}

//----------------------------------------------------------------------
// Compare two string objects.
//
// Returns:
//  -1 if a < b
//   0 if a == b
//   1 if a > b
//----------------------------------------------------------------------
int
ConstString::Compare (const ConstString& lhs, const ConstString& rhs)
{
    // If the iterators are the same, this is the same string
    register const char *lhs_cstr = lhs.m_string;
    register const char *rhs_cstr = rhs.m_string;
    if (lhs_cstr == rhs_cstr)
        return 0;
    if (lhs_cstr && rhs_cstr)
    {
        llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
        llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
        return lhs_string_ref.compare(rhs_string_ref);
    }

    if (lhs_cstr)
        return +1;  // LHS isn't NULL but RHS is
    else
        return -1;  // LHS is NULL but RHS isn't
}

//----------------------------------------------------------------------
// Dump the string value to the stream "s". If the contained string
// is empty, print "fail_value" to the stream instead. If
// "fail_value" is NULL, then nothing will be dumped to the
// stream.
//----------------------------------------------------------------------
void
ConstString::Dump(Stream *s, const char *fail_value) const
{
    const char *cstr = AsCString (fail_value);
    if (cstr)
        s->PutCString (cstr);
}

//----------------------------------------------------------------------
// Dump extra debug information to the stream "s".
//----------------------------------------------------------------------
void
ConstString::DumpDebug(Stream *s) const
{
    const char *cstr = GetCString ();
    size_t cstr_len = GetLength();
    // Only print the parens if we have a non-NULL string
    const char *parens = cstr ? "\"" : "";
    s->Printf("%*p: ConstString, string = %s%s%s, length = %zu", (int)sizeof(void*) * 2, this, parens, cstr, parens, cstr_len);
}

//----------------------------------------------------------------------
// Set the string value in the object by uniquing the "cstr" string
// value in our global string pool.
//
// If the C string already exists in the global string pool, it
// retains an extra reference to the string in the string
// pool. If it doesn't exist, it is added to the string pool with
// a reference count of 1.
//----------------------------------------------------------------------
void
ConstString::SetCString (const char *cstr)
{
    m_string = StringPool().GetConstCString (cstr);
}

//----------------------------------------------------------------------
// Set the string value in the object by uniquing "cstr_len" bytes
// starting at the "cstr" string value in our global string pool.
// If trim is true, then "cstr_len" indicates a maximum length of
// the CString and if the actual length of the string is less, then
// it will be trimmed. If trim is false, then this allows strings
// with NULL characters ('\0') to be added to the string pool.
//
// If the C string already exists in the global string pool, it
// retains an extra reference to the string in the string
// pool. If it doesn't exist, it is added to the string pool with
// a reference count of 1.
//----------------------------------------------------------------------
void
ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len)
{
    m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
}

void
ConstString::SetTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
{
    m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len);
}

//----------------------------------------------------------------------
// Return the size in bytes that this object takes in memory. The
// resulting size will not include any of the C string values from
// the global string pool (see StaticMemorySize ()).
//----------------------------------------------------------------------
size_t
ConstString::MemorySize() const
{
    return sizeof(ConstString);
}

//----------------------------------------------------------------------
// Reports the the size in bytes of all shared C string values,
// containers and reference count values as a byte size for the
// entire string pool.
//----------------------------------------------------------------------
size_t
ConstString::StaticMemorySize()
{
    // Get the size of the static string pool
    return StringPool().MemorySize();
}
