1*73d9b18aSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*73d9b18aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*73d9b18aSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*73d9b18aSAndrew Rist * distributed with this work for additional information 6*73d9b18aSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*73d9b18aSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*73d9b18aSAndrew Rist * "License"); you may not use this file except in compliance 9*73d9b18aSAndrew Rist * with the License. You may obtain a copy of the License at 10*73d9b18aSAndrew Rist * 11*73d9b18aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*73d9b18aSAndrew Rist * 13*73d9b18aSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*73d9b18aSAndrew Rist * software distributed under the License is distributed on an 15*73d9b18aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*73d9b18aSAndrew Rist * KIND, either express or implied. See the License for the 17*73d9b18aSAndrew Rist * specific language governing permissions and limitations 18*73d9b18aSAndrew Rist * under the License. 19*73d9b18aSAndrew Rist * 20*73d9b18aSAndrew Rist *************************************************************/ 21*73d9b18aSAndrew Rist 22*73d9b18aSAndrew 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 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 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 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 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 */ 126cdf0e10cSrcweir static void * operator new (size_t, void * p) { return p; } 127cdf0e10cSrcweir static void operator delete (void *, void *) {} 128cdf0e10cSrcweir 129cdf0e10cSrcweir /** Construction. 130cdf0e10cSrcweir */ 131cdf0e10cSrcweir 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 */ 137cdf0e10cSrcweir ~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 174cdf0e10cSrcweir EntryCache & EntryCache::get() 175cdf0e10cSrcweir { 176cdf0e10cSrcweir static EntryCache g_entry_cache; 177cdf0e10cSrcweir return g_entry_cache; 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 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 195cdf0e10cSrcweir EntryCache::~EntryCache() 196cdf0e10cSrcweir { 197cdf0e10cSrcweir rtl_cache_destroy (m_entry_cache), m_entry_cache = 0; 198cdf0e10cSrcweir } 199cdf0e10cSrcweir 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 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 *======================================================================*/ 228cdf0e10cSrcweir static int highbit(sal_Size n) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir register 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 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 } 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 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 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 377cdf0e10cSrcweir oslInterlockedCount PageCache_Impl::acquire() 378cdf0e10cSrcweir { 379cdf0e10cSrcweir return OStoreObject::acquire(); 380cdf0e10cSrcweir } 381cdf0e10cSrcweir 382cdf0e10cSrcweir oslInterlockedCount PageCache_Impl::release() 383cdf0e10cSrcweir { 384cdf0e10cSrcweir return OStoreObject::release(); 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 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 427cdf0e10cSrcweir Entry * PageCache_Impl::lookup_Impl (Entry * entry, sal_uInt32 nOffset) 428cdf0e10cSrcweir { 429cdf0e10cSrcweir register 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 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 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 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 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 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