xref: /trunk/main/sal/rtl/source/hash.cxx (revision 22076bf1)
1  /**************************************************************
2   *
3   * Licensed to the Apache Software Foundation (ASF) under one
4   * or more contributor license agreements.  See the NOTICE file
5   * distributed with this work for additional information
6   * regarding copyright ownership.  The ASF licenses this file
7   * to you under the Apache License, Version 2.0 (the
8   * "License"); you may not use this file except in compliance
9   * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   *
20   *************************************************************/
21  
22  
23  
24  // MARKER(update_precomp.py): autogen include statement, do not remove
25  #include "precompiled_sal.hxx"
26  
27  #include "hash.h"
28  #include "strimp.h"
29  
30  #include <hash_set>
31  
32  namespace {
33  
34  struct UStringHash
35  {
operator ()__anon642635e30111::UStringHash36      size_t operator()(rtl_uString * const &rString) const
37      { return (size_t)rtl_ustr_hashCode_WithLength( rString->buffer, rString->length ); }
38  };
39  
40  struct UStringEqual
41  {
operator ()__anon642635e30111::UStringEqual42      sal_Bool operator() ( rtl_uString * const &pStringA,
43                            rtl_uString * const &pStringB) const
44      {
45          if (pStringA == pStringB)
46              return true;
47          if (pStringA->length != pStringB->length)
48              return false;
49          return !rtl_ustr_compare_WithLength( pStringA->buffer, pStringA->length,
50                                               pStringB->buffer, pStringB->length);
51      }
52  };
53  
54  typedef std::hash_set< rtl_uString *, UStringHash, UStringEqual > StringHashTable;
55  
56  StringHashTable *
getHashTable()57  getHashTable ()
58  {
59      static StringHashTable *pInternPool = NULL;
60      if (pInternPool == NULL) {
61          static StringHashTable aImpl(1024);
62          pInternPool = &aImpl;
63      }
64      return pInternPool;
65  }
66  
67  }
68  
69  extern "C" {
70  
71  rtl_uString *
rtl_str_hash_intern(rtl_uString * pString,int can_return)72  rtl_str_hash_intern (rtl_uString       *pString,
73                       int                can_return)
74  {
75      StringHashTable *pHash = getHashTable();
76      StringHashTable::iterator aIter;
77      aIter = pHash->find(pString);
78      if (aIter != pHash->end())
79      {
80          rtl_uString *pHashStr = *aIter;
81          rtl_uString_acquire (pHashStr);
82          return pHashStr;
83      }
84      if (!can_return)
85      {
86          rtl_uString *pCopy = NULL;
87          rtl_uString_newFromString( &pCopy, pString );
88          pString = pCopy;
89          if (!pString)
90              return NULL;
91      }
92  
93      if (!SAL_STRING_IS_STATIC (pString))
94          pString->refCount |= SAL_STRING_INTERN_FLAG;
95      pHash->insert(pString);
96  
97      return pString;
98  }
99  
100  void
rtl_str_hash_remove(rtl_uString * pString)101  rtl_str_hash_remove (rtl_uString       *pString)
102  {
103      getHashTable()->erase(pString);
104  }
105  
106  }
107