173d9b18aSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
373d9b18aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
473d9b18aSAndrew Rist * or more contributor license agreements. See the NOTICE file
573d9b18aSAndrew Rist * distributed with this work for additional information
673d9b18aSAndrew Rist * regarding copyright ownership. The ASF licenses this file
773d9b18aSAndrew Rist * to you under the Apache License, Version 2.0 (the
873d9b18aSAndrew Rist * "License"); you may not use this file except in compliance
973d9b18aSAndrew Rist * with the License. You may obtain a copy of the License at
1073d9b18aSAndrew Rist *
1173d9b18aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
1273d9b18aSAndrew Rist *
1373d9b18aSAndrew Rist * Unless required by applicable law or agreed to in writing,
1473d9b18aSAndrew Rist * software distributed under the License is distributed on an
1573d9b18aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1673d9b18aSAndrew Rist * KIND, either express or implied. See the License for the
1773d9b18aSAndrew Rist * specific language governing permissions and limitations
1873d9b18aSAndrew Rist * under the License.
1973d9b18aSAndrew Rist *
2073d9b18aSAndrew Rist *************************************************************/
2173d9b18aSAndrew Rist
2273d9b18aSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_store.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "storcach.hxx"
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "sal/types.h"
30cdf0e10cSrcweir #include "rtl/alloc.h"
31cdf0e10cSrcweir #include "osl/diagnose.h"
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include "store/types.h"
34cdf0e10cSrcweir #include "object.hxx"
35cdf0e10cSrcweir #include "storbase.hxx"
36cdf0e10cSrcweir
37cdf0e10cSrcweir #ifndef INCLUDED_STDDEF_H
38cdf0e10cSrcweir #include <stddef.h>
39cdf0e10cSrcweir #define INCLUDED_STDDEF_H
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir
42cdf0e10cSrcweir using namespace store;
43cdf0e10cSrcweir
44cdf0e10cSrcweir /*========================================================================
45cdf0e10cSrcweir *
46cdf0e10cSrcweir * PageCache (non-virtual interface) implementation.
47cdf0e10cSrcweir *
48cdf0e10cSrcweir *======================================================================*/
49cdf0e10cSrcweir
lookupPageAt(PageHolder & rxPage,sal_uInt32 nOffset)50cdf0e10cSrcweir storeError PageCache::lookupPageAt (PageHolder & rxPage, sal_uInt32 nOffset)
51cdf0e10cSrcweir {
52cdf0e10cSrcweir OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::lookupPageAt(): invalid Offset");
53cdf0e10cSrcweir if (nOffset == STORE_PAGE_NULL)
54cdf0e10cSrcweir return store_E_CantSeek;
55cdf0e10cSrcweir
56cdf0e10cSrcweir return lookupPageAt_Impl (rxPage, nOffset);
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
insertPageAt(PageHolder const & rxPage,sal_uInt32 nOffset)59cdf0e10cSrcweir storeError PageCache::insertPageAt (PageHolder const & rxPage, sal_uInt32 nOffset)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir // [SECURITY:ValInput]
62cdf0e10cSrcweir PageData const * pagedata = rxPage.get();
63cdf0e10cSrcweir OSL_PRECOND(!(pagedata == 0), "store::PageCache::insertPageAt(): invalid Page");
64cdf0e10cSrcweir if (pagedata == 0)
65cdf0e10cSrcweir return store_E_InvalidParameter;
66cdf0e10cSrcweir
67cdf0e10cSrcweir sal_uInt32 const offset = pagedata->location();
68cdf0e10cSrcweir OSL_PRECOND(!(nOffset != offset), "store::PageCache::insertPageAt(): inconsistent Offset");
69cdf0e10cSrcweir if (nOffset != offset)
70cdf0e10cSrcweir return store_E_InvalidParameter;
71cdf0e10cSrcweir
72cdf0e10cSrcweir OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::insertPageAt(): invalid Offset");
73cdf0e10cSrcweir if (nOffset == STORE_PAGE_NULL)
74cdf0e10cSrcweir return store_E_CantSeek;
75cdf0e10cSrcweir
76cdf0e10cSrcweir return insertPageAt_Impl (rxPage, nOffset);
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
updatePageAt(PageHolder const & rxPage,sal_uInt32 nOffset)79cdf0e10cSrcweir storeError PageCache::updatePageAt (PageHolder const & rxPage, sal_uInt32 nOffset)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir // [SECURITY:ValInput]
82cdf0e10cSrcweir PageData const * pagedata = rxPage.get();
83cdf0e10cSrcweir OSL_PRECOND(!(pagedata == 0), "store::PageCache::updatePageAt(): invalid Page");
84cdf0e10cSrcweir if (pagedata == 0)
85cdf0e10cSrcweir return store_E_InvalidParameter;
86cdf0e10cSrcweir
87cdf0e10cSrcweir sal_uInt32 const offset = pagedata->location();
88cdf0e10cSrcweir OSL_PRECOND(!(nOffset != offset), "store::PageCache::updatePageAt(): inconsistent Offset");
89cdf0e10cSrcweir if (nOffset != offset)
90cdf0e10cSrcweir return store_E_InvalidParameter;
91cdf0e10cSrcweir
92cdf0e10cSrcweir OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::updatePageAt(): invalid Offset");
93cdf0e10cSrcweir if (nOffset == STORE_PAGE_NULL)
94cdf0e10cSrcweir return store_E_CantSeek;
95cdf0e10cSrcweir
96cdf0e10cSrcweir return updatePageAt_Impl (rxPage, nOffset);
97cdf0e10cSrcweir }
98cdf0e10cSrcweir
removePageAt(sal_uInt32 nOffset)99cdf0e10cSrcweir storeError PageCache::removePageAt (sal_uInt32 nOffset)
100cdf0e10cSrcweir {
101cdf0e10cSrcweir OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::removePageAt(): invalid Offset");
102cdf0e10cSrcweir if (nOffset == STORE_PAGE_NULL)
103cdf0e10cSrcweir return store_E_CantSeek;
104cdf0e10cSrcweir
105cdf0e10cSrcweir return removePageAt_Impl (nOffset);
106cdf0e10cSrcweir }
107cdf0e10cSrcweir
108cdf0e10cSrcweir /*========================================================================
109cdf0e10cSrcweir *
110cdf0e10cSrcweir * Entry.
111cdf0e10cSrcweir *
112cdf0e10cSrcweir *======================================================================*/
113cdf0e10cSrcweir namespace
114cdf0e10cSrcweir {
115cdf0e10cSrcweir
116cdf0e10cSrcweir struct Entry
117cdf0e10cSrcweir {
118cdf0e10cSrcweir /** Representation.
119cdf0e10cSrcweir */
120cdf0e10cSrcweir PageHolder m_xPage;
121cdf0e10cSrcweir sal_uInt32 m_nOffset;
122cdf0e10cSrcweir Entry * m_pNext;
123cdf0e10cSrcweir
124cdf0e10cSrcweir /** Allocation.
125cdf0e10cSrcweir */
operator new__anonf13d188b0111::Entry126cdf0e10cSrcweir static void * operator new (size_t, void * p) { return p; }
operator delete__anonf13d188b0111::Entry127cdf0e10cSrcweir static void operator delete (void *, void *) {}
128cdf0e10cSrcweir
129cdf0e10cSrcweir /** Construction.
130cdf0e10cSrcweir */
Entry__anonf13d188b0111::Entry131cdf0e10cSrcweir explicit Entry (PageHolder const & rxPage = PageHolder(), sal_uInt32 nOffset = STORE_PAGE_NULL)
132cdf0e10cSrcweir : m_xPage(rxPage), m_nOffset(nOffset), m_pNext(0)
133cdf0e10cSrcweir {}
134cdf0e10cSrcweir
135cdf0e10cSrcweir /** Destruction.
136cdf0e10cSrcweir */
~Entry__anonf13d188b0111::Entry137cdf0e10cSrcweir ~Entry() {}
138cdf0e10cSrcweir };
139cdf0e10cSrcweir
140cdf0e10cSrcweir } // namespace
141cdf0e10cSrcweir
142cdf0e10cSrcweir /*========================================================================
143cdf0e10cSrcweir *
144cdf0e10cSrcweir * EntryCache interface.
145cdf0e10cSrcweir *
146cdf0e10cSrcweir *======================================================================*/
147cdf0e10cSrcweir namespace
148cdf0e10cSrcweir {
149cdf0e10cSrcweir
150cdf0e10cSrcweir class EntryCache
151cdf0e10cSrcweir {
152cdf0e10cSrcweir rtl_cache_type * m_entry_cache;
153cdf0e10cSrcweir
154cdf0e10cSrcweir public:
155cdf0e10cSrcweir static EntryCache & get();
156cdf0e10cSrcweir
157cdf0e10cSrcweir Entry * create (PageHolder const & rxPage, sal_uInt32 nOffset);
158cdf0e10cSrcweir
159cdf0e10cSrcweir void destroy (Entry * entry);
160cdf0e10cSrcweir
161cdf0e10cSrcweir protected:
162cdf0e10cSrcweir EntryCache();
163cdf0e10cSrcweir ~EntryCache();
164cdf0e10cSrcweir };
165cdf0e10cSrcweir
166cdf0e10cSrcweir } // namespace
167cdf0e10cSrcweir
168cdf0e10cSrcweir /*========================================================================
169cdf0e10cSrcweir *
170cdf0e10cSrcweir * EntryCache implementation.
171cdf0e10cSrcweir *
172cdf0e10cSrcweir *======================================================================*/
173cdf0e10cSrcweir
get()174cdf0e10cSrcweir EntryCache & EntryCache::get()
175cdf0e10cSrcweir {
176cdf0e10cSrcweir static EntryCache g_entry_cache;
177cdf0e10cSrcweir return g_entry_cache;
178cdf0e10cSrcweir }
179cdf0e10cSrcweir
EntryCache()180cdf0e10cSrcweir EntryCache::EntryCache()
181cdf0e10cSrcweir {
182cdf0e10cSrcweir m_entry_cache = rtl_cache_create (
183cdf0e10cSrcweir "store_cache_entry_cache",
184cdf0e10cSrcweir sizeof(Entry),
185cdf0e10cSrcweir 0, // objalign
186cdf0e10cSrcweir 0, // constructor
187cdf0e10cSrcweir 0, // destructor
188cdf0e10cSrcweir 0, // reclaim
189cdf0e10cSrcweir 0, // userarg
190cdf0e10cSrcweir 0, // default source
191cdf0e10cSrcweir 0 // flags
192cdf0e10cSrcweir );
193cdf0e10cSrcweir }
194cdf0e10cSrcweir
~EntryCache()195cdf0e10cSrcweir EntryCache::~EntryCache()
196cdf0e10cSrcweir {
197cdf0e10cSrcweir rtl_cache_destroy (m_entry_cache), m_entry_cache = 0;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
create(PageHolder const & rxPage,sal_uInt32 nOffset)200cdf0e10cSrcweir Entry * EntryCache::create (PageHolder const & rxPage, sal_uInt32 nOffset)
201cdf0e10cSrcweir {
202cdf0e10cSrcweir void * pAddr = rtl_cache_alloc (m_entry_cache);
203cdf0e10cSrcweir if (pAddr != 0)
204cdf0e10cSrcweir {
205cdf0e10cSrcweir // construct.
206cdf0e10cSrcweir return new(pAddr) Entry (rxPage, nOffset);
207cdf0e10cSrcweir }
208cdf0e10cSrcweir return 0;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir
destroy(Entry * entry)211cdf0e10cSrcweir void EntryCache::destroy (Entry * entry)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir if (entry != 0)
214cdf0e10cSrcweir {
215cdf0e10cSrcweir // destruct.
216cdf0e10cSrcweir entry->~Entry();
217cdf0e10cSrcweir
218cdf0e10cSrcweir // return to cache.
219cdf0e10cSrcweir rtl_cache_free (m_entry_cache, entry);
220cdf0e10cSrcweir }
221cdf0e10cSrcweir }
222cdf0e10cSrcweir
223cdf0e10cSrcweir /*========================================================================
224cdf0e10cSrcweir *
225cdf0e10cSrcweir * highbit():= log2() + 1 (complexity O(1))
226cdf0e10cSrcweir *
227cdf0e10cSrcweir *======================================================================*/
highbit(sal_Size n)228cdf0e10cSrcweir static int highbit(sal_Size n)
229cdf0e10cSrcweir {
230*c1e8cc3aSDon Lewis int k = 1;
231cdf0e10cSrcweir
232cdf0e10cSrcweir if (n == 0)
233cdf0e10cSrcweir return (0);
234cdf0e10cSrcweir #if SAL_TYPES_SIZEOFLONG == 8
235cdf0e10cSrcweir if (n & 0xffffffff00000000ul)
236cdf0e10cSrcweir k |= 32, n >>= 32;
237cdf0e10cSrcweir #endif
238cdf0e10cSrcweir if (n & 0xffff0000)
239cdf0e10cSrcweir k |= 16, n >>= 16;
240cdf0e10cSrcweir if (n & 0xff00)
241cdf0e10cSrcweir k |= 8, n >>= 8;
242cdf0e10cSrcweir if (n & 0xf0)
243cdf0e10cSrcweir k |= 4, n >>= 4;
244cdf0e10cSrcweir if (n & 0x0c)
245cdf0e10cSrcweir k |= 2, n >>= 2;
246cdf0e10cSrcweir if (n & 0x02)
247cdf0e10cSrcweir k++;
248cdf0e10cSrcweir
249cdf0e10cSrcweir return (k);
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir /*========================================================================
253cdf0e10cSrcweir *
254cdf0e10cSrcweir * PageCache_Impl implementation.
255cdf0e10cSrcweir *
256cdf0e10cSrcweir *======================================================================*/
257cdf0e10cSrcweir namespace store
258cdf0e10cSrcweir {
259cdf0e10cSrcweir
260cdf0e10cSrcweir class PageCache_Impl :
261cdf0e10cSrcweir public store::OStoreObject,
262cdf0e10cSrcweir public store::PageCache
263cdf0e10cSrcweir {
264cdf0e10cSrcweir /** Representation.
265cdf0e10cSrcweir */
266cdf0e10cSrcweir static size_t const theTableSize = 32;
267cdf0e10cSrcweir STORE_STATIC_ASSERT(STORE_IMPL_ISP2(theTableSize));
268cdf0e10cSrcweir
269cdf0e10cSrcweir Entry ** m_hash_table;
270cdf0e10cSrcweir Entry * m_hash_table_0[theTableSize];
271cdf0e10cSrcweir size_t m_hash_size;
272cdf0e10cSrcweir size_t m_hash_shift;
273cdf0e10cSrcweir size_t const m_page_shift;
274cdf0e10cSrcweir
275cdf0e10cSrcweir size_t m_hash_entries; // total number of entries in table.
276cdf0e10cSrcweir size_t m_nHit;
277cdf0e10cSrcweir size_t m_nMissed;
278cdf0e10cSrcweir
hash_Impl(sal_uInt32 a,size_t s,size_t q,size_t m)279cdf0e10cSrcweir inline int hash_Impl(sal_uInt32 a, size_t s, size_t q, size_t m)
280cdf0e10cSrcweir {
281cdf0e10cSrcweir return ((((a) + ((a) >> (s)) + ((a) >> ((s) << 1))) >> (q)) & (m));
282cdf0e10cSrcweir }
hash_index_Impl(sal_uInt32 nOffset)283cdf0e10cSrcweir inline int hash_index_Impl (sal_uInt32 nOffset)
284cdf0e10cSrcweir {
285cdf0e10cSrcweir return hash_Impl(nOffset, m_hash_shift, m_page_shift, m_hash_size - 1);
286cdf0e10cSrcweir }
287cdf0e10cSrcweir
288cdf0e10cSrcweir Entry * lookup_Impl (Entry * entry, sal_uInt32 nOffset);
289cdf0e10cSrcweir void rescale_Impl (sal_Size new_size);
290cdf0e10cSrcweir
291cdf0e10cSrcweir /** PageCache Implementation.
292cdf0e10cSrcweir */
293cdf0e10cSrcweir virtual storeError lookupPageAt_Impl (
294cdf0e10cSrcweir PageHolder & rxPage,
295cdf0e10cSrcweir sal_uInt32 nOffset);
296cdf0e10cSrcweir
297cdf0e10cSrcweir virtual storeError insertPageAt_Impl (
298cdf0e10cSrcweir PageHolder const & rxPage,
299cdf0e10cSrcweir sal_uInt32 nOffset);
300cdf0e10cSrcweir
301cdf0e10cSrcweir virtual storeError updatePageAt_Impl (
302cdf0e10cSrcweir PageHolder const & rxPage,
303cdf0e10cSrcweir sal_uInt32 nOffset);
304cdf0e10cSrcweir
305cdf0e10cSrcweir virtual storeError removePageAt_Impl (
306cdf0e10cSrcweir sal_uInt32 nOffset);
307cdf0e10cSrcweir
308cdf0e10cSrcweir /** Not implemented.
309cdf0e10cSrcweir */
310cdf0e10cSrcweir PageCache_Impl (PageCache_Impl const &);
311cdf0e10cSrcweir PageCache_Impl & operator= (PageCache_Impl const &);
312cdf0e10cSrcweir
313cdf0e10cSrcweir public:
314cdf0e10cSrcweir /** Construction.
315cdf0e10cSrcweir */
316cdf0e10cSrcweir explicit PageCache_Impl (sal_uInt16 nPageSize);
317cdf0e10cSrcweir
318cdf0e10cSrcweir /** Delegate multiple inherited IReference.
319cdf0e10cSrcweir */
320cdf0e10cSrcweir virtual oslInterlockedCount SAL_CALL acquire();
321cdf0e10cSrcweir virtual oslInterlockedCount SAL_CALL release();
322cdf0e10cSrcweir
323cdf0e10cSrcweir protected:
324cdf0e10cSrcweir /** Destruction.
325cdf0e10cSrcweir */
326cdf0e10cSrcweir virtual ~PageCache_Impl (void);
327cdf0e10cSrcweir };
328cdf0e10cSrcweir
329cdf0e10cSrcweir } // namespace store
330cdf0e10cSrcweir
PageCache_Impl(sal_uInt16 nPageSize)331cdf0e10cSrcweir PageCache_Impl::PageCache_Impl (sal_uInt16 nPageSize)
332cdf0e10cSrcweir : m_hash_table (m_hash_table_0),
333cdf0e10cSrcweir m_hash_size (theTableSize),
334cdf0e10cSrcweir m_hash_shift (highbit(m_hash_size) - 1),
335cdf0e10cSrcweir m_page_shift (highbit(nPageSize) - 1),
336cdf0e10cSrcweir m_hash_entries (0),
337cdf0e10cSrcweir m_nHit (0),
338cdf0e10cSrcweir m_nMissed (0)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir static size_t const theSize = sizeof(m_hash_table_0) / sizeof(m_hash_table_0[0]);
341cdf0e10cSrcweir STORE_STATIC_ASSERT(theSize == theTableSize);
342cdf0e10cSrcweir memset(m_hash_table_0, 0, sizeof(m_hash_table_0));
343cdf0e10cSrcweir }
344cdf0e10cSrcweir
~PageCache_Impl()345cdf0e10cSrcweir PageCache_Impl::~PageCache_Impl()
346cdf0e10cSrcweir {
347cdf0e10cSrcweir double s_x = 0.0, s_xx = 0.0;
348cdf0e10cSrcweir sal_Size i, n = m_hash_size;
349cdf0e10cSrcweir for (i = 0; i < n; i++)
350cdf0e10cSrcweir {
351cdf0e10cSrcweir int x = 0;
352cdf0e10cSrcweir Entry * entry = m_hash_table[i];
353cdf0e10cSrcweir while (entry != 0)
354cdf0e10cSrcweir {
355cdf0e10cSrcweir m_hash_table[i] = entry->m_pNext, entry->m_pNext = 0;
356cdf0e10cSrcweir EntryCache::get().destroy (entry);
357cdf0e10cSrcweir entry = m_hash_table[i];
358cdf0e10cSrcweir x += 1;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir s_x += double(x);
361cdf0e10cSrcweir s_xx += double(x) * double(x);
362cdf0e10cSrcweir }
363cdf0e10cSrcweir double ave = s_x / double(n);
364cdf0e10cSrcweir OSL_TRACE("ave hash chain length: %g", ave);
365cdf0e10cSrcweir (void) ave;
366cdf0e10cSrcweir
367cdf0e10cSrcweir if (m_hash_table != m_hash_table_0)
368cdf0e10cSrcweir {
369cdf0e10cSrcweir rtl_freeMemory (m_hash_table);
370cdf0e10cSrcweir m_hash_table = m_hash_table_0;
371cdf0e10cSrcweir m_hash_size = theTableSize;
372cdf0e10cSrcweir m_hash_shift = highbit(m_hash_size) - 1;
373cdf0e10cSrcweir }
374cdf0e10cSrcweir OSL_TRACE("Hits: %u, Misses: %u", m_nHit, m_nMissed);
375cdf0e10cSrcweir }
376cdf0e10cSrcweir
acquire()377cdf0e10cSrcweir oslInterlockedCount PageCache_Impl::acquire()
378cdf0e10cSrcweir {
379cdf0e10cSrcweir return OStoreObject::acquire();
380cdf0e10cSrcweir }
381cdf0e10cSrcweir
release()382cdf0e10cSrcweir oslInterlockedCount PageCache_Impl::release()
383cdf0e10cSrcweir {
384cdf0e10cSrcweir return OStoreObject::release();
385cdf0e10cSrcweir }
386cdf0e10cSrcweir
rescale_Impl(sal_Size new_size)387cdf0e10cSrcweir void PageCache_Impl::rescale_Impl (sal_Size new_size)
388cdf0e10cSrcweir {
389cdf0e10cSrcweir sal_Size new_bytes = new_size * sizeof(Entry*);
390cdf0e10cSrcweir Entry ** new_table = (Entry**)(rtl_allocateMemory(new_bytes));
391cdf0e10cSrcweir
392cdf0e10cSrcweir if (new_table != 0)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir Entry ** old_table = m_hash_table;
395cdf0e10cSrcweir sal_Size old_size = m_hash_size;
396cdf0e10cSrcweir
397cdf0e10cSrcweir OSL_TRACE("ave chain length: %u, total entries: %u [old_size: %u, new_size: %u]",
398cdf0e10cSrcweir m_hash_entries >> m_hash_shift, m_hash_entries, old_size, new_size);
399cdf0e10cSrcweir
400cdf0e10cSrcweir memset (new_table, 0, new_bytes);
401cdf0e10cSrcweir
402cdf0e10cSrcweir m_hash_table = new_table;
403cdf0e10cSrcweir m_hash_size = new_size;
404cdf0e10cSrcweir m_hash_shift = highbit(m_hash_size) - 1;
405cdf0e10cSrcweir
406cdf0e10cSrcweir sal_Size i;
407cdf0e10cSrcweir for (i = 0; i < old_size; i++)
408cdf0e10cSrcweir {
409cdf0e10cSrcweir Entry * curr = old_table[i];
410cdf0e10cSrcweir while (curr != 0)
411cdf0e10cSrcweir {
412cdf0e10cSrcweir Entry * next = curr->m_pNext;
413cdf0e10cSrcweir int index = hash_index_Impl(curr->m_nOffset);
414cdf0e10cSrcweir curr->m_pNext = m_hash_table[index], m_hash_table[index] = curr;
415cdf0e10cSrcweir curr = next;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir old_table[i] = 0;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir if (old_table != m_hash_table_0)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir //
422cdf0e10cSrcweir rtl_freeMemory (old_table);
423cdf0e10cSrcweir }
424cdf0e10cSrcweir }
425cdf0e10cSrcweir }
426cdf0e10cSrcweir
lookup_Impl(Entry * entry,sal_uInt32 nOffset)427cdf0e10cSrcweir Entry * PageCache_Impl::lookup_Impl (Entry * entry, sal_uInt32 nOffset)
428cdf0e10cSrcweir {
429*c1e8cc3aSDon Lewis int lookups = 0;
430cdf0e10cSrcweir while (entry != 0)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir if (entry->m_nOffset == nOffset)
433cdf0e10cSrcweir break;
434cdf0e10cSrcweir
435cdf0e10cSrcweir lookups += 1;
436cdf0e10cSrcweir entry = entry->m_pNext;
437cdf0e10cSrcweir }
438cdf0e10cSrcweir if (lookups > 2)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir sal_Size new_size = m_hash_size, ave = m_hash_entries >> m_hash_shift;
441cdf0e10cSrcweir for (; ave > 4; new_size *= 2, ave /= 2)
442cdf0e10cSrcweir continue;
443cdf0e10cSrcweir if (new_size != m_hash_size)
444cdf0e10cSrcweir rescale_Impl (new_size);
445cdf0e10cSrcweir }
446cdf0e10cSrcweir return entry;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir
lookupPageAt_Impl(PageHolder & rxPage,sal_uInt32 nOffset)449cdf0e10cSrcweir storeError PageCache_Impl::lookupPageAt_Impl (
450cdf0e10cSrcweir PageHolder & rxPage,
451cdf0e10cSrcweir sal_uInt32 nOffset)
452cdf0e10cSrcweir {
453cdf0e10cSrcweir int index = hash_index_Impl(nOffset);
454cdf0e10cSrcweir Entry const * entry = lookup_Impl (m_hash_table[index], nOffset);
455cdf0e10cSrcweir if (entry != 0)
456cdf0e10cSrcweir {
457cdf0e10cSrcweir // Existing entry.
458cdf0e10cSrcweir rxPage = entry->m_xPage;
459cdf0e10cSrcweir
460cdf0e10cSrcweir // Update stats and leave.
461cdf0e10cSrcweir m_nHit += 1;
462cdf0e10cSrcweir return store_E_None;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir
465cdf0e10cSrcweir // Cache miss. Update stats and leave.
466cdf0e10cSrcweir m_nMissed += 1;
467cdf0e10cSrcweir return store_E_NotExists;
468cdf0e10cSrcweir }
469cdf0e10cSrcweir
insertPageAt_Impl(PageHolder const & rxPage,sal_uInt32 nOffset)470cdf0e10cSrcweir storeError PageCache_Impl::insertPageAt_Impl (
471cdf0e10cSrcweir PageHolder const & rxPage,
472cdf0e10cSrcweir sal_uInt32 nOffset)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir Entry * entry = EntryCache::get().create (rxPage, nOffset);
475cdf0e10cSrcweir if (entry != 0)
476cdf0e10cSrcweir {
477cdf0e10cSrcweir // Insert new entry.
478cdf0e10cSrcweir int index = hash_index_Impl(nOffset);
479cdf0e10cSrcweir entry->m_pNext = m_hash_table[index], m_hash_table[index] = entry;
480cdf0e10cSrcweir
481cdf0e10cSrcweir // Update stats and leave.
482cdf0e10cSrcweir m_hash_entries += 1;
483cdf0e10cSrcweir return store_E_None;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir return store_E_OutOfMemory;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir
updatePageAt_Impl(PageHolder const & rxPage,sal_uInt32 nOffset)488cdf0e10cSrcweir storeError PageCache_Impl::updatePageAt_Impl (
489cdf0e10cSrcweir PageHolder const & rxPage,
490cdf0e10cSrcweir sal_uInt32 nOffset)
491cdf0e10cSrcweir {
492cdf0e10cSrcweir int index = hash_index_Impl(nOffset);
493cdf0e10cSrcweir Entry * entry = lookup_Impl (m_hash_table[index], nOffset);
494cdf0e10cSrcweir if (entry != 0)
495cdf0e10cSrcweir {
496cdf0e10cSrcweir // Update existing entry.
497cdf0e10cSrcweir entry->m_xPage = rxPage;
498cdf0e10cSrcweir
499cdf0e10cSrcweir // Update stats and leave. // m_nUpdHit += 1;
500cdf0e10cSrcweir return store_E_None;
501cdf0e10cSrcweir }
502cdf0e10cSrcweir return insertPageAt_Impl (rxPage, nOffset);
503cdf0e10cSrcweir }
504cdf0e10cSrcweir
removePageAt_Impl(sal_uInt32 nOffset)505cdf0e10cSrcweir storeError PageCache_Impl::removePageAt_Impl (
506cdf0e10cSrcweir sal_uInt32 nOffset)
507cdf0e10cSrcweir {
508cdf0e10cSrcweir Entry ** ppEntry = &(m_hash_table[hash_index_Impl(nOffset)]);
509cdf0e10cSrcweir while (*ppEntry != 0)
510cdf0e10cSrcweir {
511cdf0e10cSrcweir if ((*ppEntry)->m_nOffset == nOffset)
512cdf0e10cSrcweir {
513cdf0e10cSrcweir // Existing entry.
514cdf0e10cSrcweir Entry * entry = (*ppEntry);
515cdf0e10cSrcweir
516cdf0e10cSrcweir // Dequeue and destroy entry.
517cdf0e10cSrcweir (*ppEntry) = entry->m_pNext, entry->m_pNext = 0;
518cdf0e10cSrcweir EntryCache::get().destroy (entry);
519cdf0e10cSrcweir
520cdf0e10cSrcweir // Update stats and leave.
521cdf0e10cSrcweir m_hash_entries -= 1;
522cdf0e10cSrcweir return store_E_None;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir ppEntry = &((*ppEntry)->m_pNext);
525cdf0e10cSrcweir }
526cdf0e10cSrcweir return store_E_NotExists;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir
529cdf0e10cSrcweir /*========================================================================
530cdf0e10cSrcweir *
531cdf0e10cSrcweir * Old OStorePageCache implementation.
532cdf0e10cSrcweir *
533cdf0e10cSrcweir * (two-way association (sorted address array, LRU chain)).
534cdf0e10cSrcweir * (external OStorePageData representation).
535cdf0e10cSrcweir *
536cdf0e10cSrcweir *======================================================================*/
537cdf0e10cSrcweir
538cdf0e10cSrcweir /*========================================================================
539cdf0e10cSrcweir *
540cdf0e10cSrcweir * PageCache factory implementation.
541cdf0e10cSrcweir *
542cdf0e10cSrcweir *======================================================================*/
543cdf0e10cSrcweir namespace store {
544cdf0e10cSrcweir
545cdf0e10cSrcweir storeError
PageCache_createInstance(rtl::Reference<store::PageCache> & rxCache,sal_uInt16 nPageSize)546cdf0e10cSrcweir PageCache_createInstance (
547cdf0e10cSrcweir rtl::Reference< store::PageCache > & rxCache,
548cdf0e10cSrcweir sal_uInt16 nPageSize)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir rxCache = new PageCache_Impl (nPageSize);
551cdf0e10cSrcweir if (!rxCache.is())
552cdf0e10cSrcweir return store_E_OutOfMemory;
553cdf0e10cSrcweir
554cdf0e10cSrcweir return store_E_None;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir
557cdf0e10cSrcweir } // namespace store
558