]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Store API and layout polishing. No functionality changes intended.
authorAlex Rousskov <rousskov@measurement-factory.com>
Thu, 19 Nov 2015 05:51:49 +0000 (22:51 -0700)
committerAlex Rousskov <rousskov@measurement-factory.com>
Thu, 19 Nov 2015 05:51:49 +0000 (22:51 -0700)
Fixes "any Store is a Root" API that forced us to bloat the base
Store class with methods needed only in Store::Root() Controller.
Unblocks bug #7 (cached headers update) fixes.

Class renaming and source file movement map:

  src/SwapDir.h => src/store/Disk.h (and Controller.h)
  src/SwapDir.cc => src/store/Disk.cc
  src/StoreHashIndex.h => src/store/Disks.h (and LocalSearch.h)
  src/store_dir.cc => src/store/Controller.cc (and Disks.cc, LocalSearch.cc)
  src/disk.* => src/fs_io.*

The Store namespace hierarchy now looks like this:

* Storage: Any storage. Similar to the old Store class, but leaner.
* Controller: Combined memory/disks caches and transients. Root API.
* Controlled: Memory cache, disk(s) cache, or transient Storage.
* Disks: All disk caches combined.
* Disk: A single cache_dir Storage.
* Memory: A memory cache.
* Transients: Entries capable of being collapsed for CF.

Please see merged branch commits for details.

88 files changed:
configure.ac
doc/debug-sections.txt
src/DiskIO/AIO/AIODiskFile.cc
src/DiskIO/Blocking/BlockingFile.cc
src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
src/DiskIO/IpcIo/IpcIoFile.cc
src/DiskIO/Mmapped/MmappedFile.cc
src/FileMap.h
src/Makefile.am
src/MemStore.cc
src/MemStore.h
src/SBuf.h
src/SquidConfig.h
src/Store.h
src/StoreFileSystem.h
src/StoreHashIndex.h [deleted file]
src/StoreIOState.h
src/StoreSwapLogData.h
src/SwapDir.h [deleted file]
src/Transients.cc
src/Transients.h
src/base/RefCount.h
src/cache_cf.cc
src/errorpage.cc
src/fatal.cc
src/fs/rock/RockDbCell.h
src/fs/rock/RockRebuild.cc
src/fs/rock/RockSwapDir.cc
src/fs/rock/RockSwapDir.h
src/fs/rock/forward.h
src/fs/ufs/RebuildState.cc
src/fs/ufs/UFSStoreState.cc
src/fs/ufs/UFSSwapDir.cc
src/fs/ufs/UFSSwapDir.h
src/fs_io.cc [moved from src/disk.cc with 93% similarity]
src/fs_io.h [moved from src/disk.h with 76% similarity]
src/icmp/net_db.cc
src/icp_v2.cc
src/ipc/MemMap.h
src/ipc/StoreMap.h
src/ipc/Strand.cc
src/ipc/mem/Pages.cc
src/log/ModStdio.cc
src/log/ModUdp.cc
src/main.cc
src/mem/old_api.cc
src/mime.cc
src/send-announce.cc
src/ssl/helper.cc
src/ssl/stub_libsslutil.cc
src/stat.cc
src/store.cc
src/store/Controlled.h [new file with mode: 0644]
src/store/Controller.cc [new file with mode: 0644]
src/store/Controller.h [new file with mode: 0644]
src/store/Disk.cc [moved from src/SwapDir.cc with 72% similarity]
src/store/Disk.h [new file with mode: 0644]
src/store/Disks.cc [new file with mode: 0644]
src/store/Disks.h [new file with mode: 0644]
src/store/LocalSearch.cc [new file with mode: 0644]
src/store/LocalSearch.h [moved from src/fs/forward.h with 56% similarity]
src/store/Makefile.am [new file with mode: 0644]
src/store/Storage.h [new file with mode: 0644]
src/store/forward.h [new file with mode: 0644]
src/store_digest.cc
src/store_dir.cc [deleted file]
src/store_io.cc
src/store_key_md5.h
src/store_rebuild.cc
src/store_swapout.cc
src/tests/STUB.h
src/tests/TestSwapDir.cc
src/tests/TestSwapDir.h
src/tests/stub_MemStore.cc
src/tests/stub_SwapDir.cc
src/tests/stub_store.cc
src/tests/stub_store_rebuild.cc
src/tests/testDiskIO.cc
src/tests/testPackableStream.cc
src/tests/testRock.cc
src/tests/testStore.cc
src/tests/testStore.h
src/tests/testStoreController.cc
src/tests/testStoreHashIndex.cc
src/tests/testUfs.cc
src/tools.cc
src/unlinkd.cc
src/wccp2.cc

index 131f9974315a3b32d312695a1260248b4f784e81..edc0d554fbe3bbc89e78ae3980dbc50cdad68325 100644 (file)
@@ -3864,6 +3864,7 @@ AC_CONFIG_FILES([
        src/servers/Makefile
        src/snmp/Makefile
        src/ssl/Makefile
+       src/store/Makefile
        test-suite/Makefile
        tools/Makefile
        tools/helper-mux/Makefile
index e444791c9769876f216580534b365edbd22071e1..888c94d15916822eae98564be1e14ec70fc460a1 100644 (file)
@@ -49,6 +49,7 @@ section 20    Storage Manager Swapfile Metadata
 section 20    Storage Manager Swapfile Unpacker
 section 20    Storage Manager Swapin Functions
 section 20    Storage Manager Swapout Functions
+section 20    Store Controller
 section 20    Store Rebuild Routines
 section 20    Swap Dir base object
 section 21    Integer functions
@@ -92,6 +93,7 @@ section 46    Access Log - Squid ICAP Logging
 section 46    Access Log - Squid referer format
 section 46    Access Log - Squid useragent format
 section 47    Store Directory Routines
+section 47    Store Search
 section 48    Persistent Connections
 section 49    SNMP Interface
 section 49    SNMP support
index ca6cad7c7bc6b943ebbf9b008fc20d154a7cb4da..57ae9c83df096df1fc9c03e9e82a32a7eae55542 100644 (file)
 
 #include "squid.h"
 #include "Debug.h"
-#include "disk.h"
 #include "DiskIO/AIO/AIODiskFile.h"
 #include "DiskIO/AIO/AIODiskIOStrategy.h"
 #include "DiskIO/IORequestor.h"
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
+#include "fs_io.h"
 #include "globals.h"
 
 #include <cerrno>
index 997598079caeaecc087479d524f066986167b177..ff6a5accc5c2ebcc052e81b59147da384810559b 100644 (file)
 #include "BlockingFile.h"
 #include "Debug.h"
 #include "defines.h"
-#include "disk.h"
 #include "DiskIO/IORequestor.h"
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
+#include "fs_io.h"
 #include "globals.h"
 
 #include <cerrno>
index a17def9e39d486722fb6aa756cb97fd2768c08eb..e61646b25bab7d13d1bd93b9182658e94fa75632 100644 (file)
@@ -9,12 +9,12 @@
 /* DEBUG: section 79    Disk IO Routines */
 
 #include "squid.h"
-#include "disk.h"
 #include "DiskIO/IORequestor.h"
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
 #include "DiskThreadsDiskFile.h"
 #include "fd.h"
+#include "fs_io.h"
 #include "Generic.h"
 #include "globals.h"
 #include "StatCounters.h"
index 0297e06e63703a62a34f0d21852ddf254637c908..32495a88af5bfd6120f658ad919e85076276da27 100644 (file)
 #include "squid.h"
 #include "base/RunnersRegistry.h"
 #include "base/TextException.h"
-#include "disk.h"
 #include "DiskIO/IORequestor.h"
 #include "DiskIO/IpcIo/IpcIoFile.h"
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
 #include "fd.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "ipc/mem/Pages.h"
 #include "ipc/Messages.h"
index 88f5424102de7c9be8ed9f753ae26fde48e8a8be..2fde2ed773fafa9ab980f86651fa398457ffc7bf 100644 (file)
 
 #include "squid.h"
 #include "Debug.h"
-#include "disk.h"
 #include "DiskIO/IORequestor.h"
 #include "DiskIO/Mmapped/MmappedFile.h"
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
+#include "fs_io.h"
 #include "globals.h"
 
 #include <cerrno>
index 57a7bed75a8d14c1ada5f766ea1c5e9112f729fc..06be0a239f4e4ab6411336ef32860b61137de723 100644 (file)
@@ -11,7 +11,7 @@
 #ifndef FILEMAP_H_
 #define FILEMAP_H_
 
-#include "fs/forward.h"
+#include "store/forward.h"
 
 /** A bitmap used for managing UFS StoreEntry "file numbers".
  *
index 9da154bf39fb840c59d8b10cd2caa388c31b8d54..01e21a38b66fd0dd274305317ab120fa67855afd 100644 (file)
@@ -42,8 +42,8 @@ LOADABLE_MODULES_SOURCES = \
        LoadableModules.h \
        LoadableModules.cc
 
-SUBDIRS        = mem base anyp helper dns ftp parser comm eui acl format clients servers fs repl DiskIO
-DIST_SUBDIRS = mem base anyp helper dns ftp parser comm eui acl format clients servers fs repl DiskIO
+SUBDIRS        = mem base anyp helper dns ftp parser comm eui acl format clients servers fs repl store DiskIO
+DIST_SUBDIRS = mem base anyp helper dns ftp parser comm eui acl format clients servers fs repl store DiskIO
 
 if ENABLE_AUTH
 SUBDIRS += auth
@@ -280,8 +280,8 @@ squid_SOURCES = \
        Debug.h \
        defines.h \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -312,7 +312,6 @@ squid_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        Generic.h \
@@ -448,7 +447,6 @@ squid_SOURCES = \
        Store.h \
        StoreFileSystem.cc \
        StoreFileSystem.h \
-       StoreHashIndex.h \
        store_io.cc \
        StoreIOBuffer.h \
        StoreIOState.cc \
@@ -457,7 +455,6 @@ squid_SOURCES = \
        StoreClient.h \
        store_digest.h \
        store_digest.cc \
-       store_dir.cc \
        store_key_md5.h \
        store_key_md5.cc \
        store_log.h \
@@ -477,8 +474,6 @@ squid_SOURCES = \
        StoreSwapLogData.cc \
        StoreSwapLogData.h \
        swap_log_op.h \
-       SwapDir.cc \
-       SwapDir.h \
        Transients.cc \
        Transients.h \
        MemStore.cc \
@@ -583,6 +578,7 @@ squid_LDADD = \
        $(ESI_LIBS) \
        $(SNMP_LIBS) \
        mem/libmem.la \
+       store/libstore.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -624,12 +620,11 @@ recv_announce_SOURCES = recv-announce.cc
 ## ACLProxyAuth.cc wants ACLUserData
 ## ACLProxyAuth.cc wants ACLRegexData
 ## cache_cf.cc wants $(AUTH_LIBS)
-## cache_cf.cc wants Swapdir
+## cache_cf.cc wants store/libstore.la
 ## cache_cf.cc wants AnyP::PortCfg
 ## client_side wants client_db
 ## client_db wants SNMP_SOURCE
 ## snmp_core wants ACLStringData
-## SwapDir wants ConfigOption
 ## tools.cc wants ip/libip.la
 ## client_side.cc wants ip/libip.la
 ## libbase.la wants cbdata.*
@@ -1119,7 +1114,6 @@ tests_testACLMaxUserIP_SOURCES= \
        SBufDetailedStats.h \
        tests/stub_SBufDetailedStats.cc \
        String.cc \
-       store_dir.cc \
        StoreIOState.cc \
        tests/stub_StoreMeta.cc \
        StoreMetaUnpacker.cc \
@@ -1129,7 +1123,6 @@ tests_testACLMaxUserIP_SOURCES= \
        swap_log_op.cc \
        swap_log_op.h \
        tests/stub_SwapDir.cc \
-       SwapDir.h \
        Transients.cc \
        log/access_log.h \
        tests/stub_access_log.cc \
@@ -1294,8 +1287,8 @@ tests_testCacheManager_SOURCES = \
        CpuAffinitySet.cc \
        CpuAffinitySet.h \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -1313,7 +1306,6 @@ tests_testCacheManager_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -1410,7 +1402,6 @@ tests_testCacheManager_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -1478,6 +1469,7 @@ tests_testCacheManager_LDADD = \
        mgr/libmgr.la \
        $(SNMP_LIBS) \
        mem/libmem.la \
+       store/libstore.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -1504,8 +1496,8 @@ tests_testDiskIO_SOURCES = \
        ConfigOption.cc \
        ConfigParser.cc \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        tests/stub_ETag.cc \
        EventLoop.cc \
        event.cc \
@@ -1517,7 +1509,6 @@ tests_testDiskIO_SOURCES = \
        fde.cc \
        FileMap.h \
        filemap.cc \
-       fs/forward.h \
        HttpBody.h \
        HttpBody.cc \
        HttpHeaderFieldStat.h \
@@ -1568,7 +1559,6 @@ tests_testDiskIO_SOURCES = \
        tests/stub_StoreMeta.cc \
        StoreMetaUnpacker.cc \
        StoreSwapLogData.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -1659,6 +1649,7 @@ tests_testDiskIO_LDADD = \
        dns/libdns.la \
        base/libbase.la \
        mem/libmem.la \
+       store/libstore.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -1727,8 +1718,8 @@ tests_testEvent_SOURCES = \
        CpuAffinitySet.h \
        debug.cc \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -1749,7 +1740,6 @@ tests_testEvent_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -1846,7 +1836,6 @@ tests_testEvent_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -1924,6 +1913,7 @@ tests_testEvent_LDADD = \
        $(top_builddir)/lib/libmiscutil.la \
        ipc/libipc.la \
        mgr/libmgr.la \
+       store/libstore.la \
        $(SNMP_LIBS) \
        $(NETTLELIB) \
        $(REGEXLIB) \
@@ -1973,8 +1963,8 @@ tests_testEventLoop_SOURCES = \
        CpuAffinitySet.h \
        debug.cc \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -1995,7 +1985,6 @@ tests_testEventLoop_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -2089,7 +2078,6 @@ tests_testEventLoop_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -2169,6 +2157,7 @@ tests_testEventLoop_LDADD = \
        $(top_builddir)/lib/libmiscutil.la \
        ipc/libipc.la \
        mgr/libmgr.la \
+       store/libstore.la \
        $(SNMP_LIBS) \
        $(NETTLELIB) \
        $(REGEXLIB) \
@@ -2217,8 +2206,8 @@ tests_test_http_range_SOURCES = \
        CpuAffinitySet.h \
        debug.cc \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -2236,7 +2225,6 @@ tests_test_http_range_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -2330,7 +2318,6 @@ tests_test_http_range_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_key_md5.h \
        store_key_md5.cc \
        store_io.cc \
@@ -2407,6 +2394,7 @@ tests_test_http_range_LDADD = \
        dns/libdns.la \
        base/libbase.la \
        mgr/libmgr.la \
+       store/libstore.la \
        $(SNMP_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
@@ -2550,8 +2538,8 @@ tests_testHttpRequest_SOURCES = \
        CpuAffinitySet.cc \
        CpuAffinitySet.h \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -2566,7 +2554,6 @@ tests_testHttpRequest_SOURCES = \
        fde.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -2658,7 +2645,6 @@ tests_testHttpRequest_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -2723,6 +2709,7 @@ tests_testHttpRequest_LDADD = \
        comm/libcomm.la \
        log/liblog.la \
        format/libformat.la \
+       store/libstore.la \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
@@ -2793,8 +2780,8 @@ tests_testStore_SOURCES= \
        ConfigOption.cc \
        ConfigParser.cc \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        ETag.cc \
        event.cc \
        EventLoop.cc \
@@ -2802,7 +2789,6 @@ tests_testStore_SOURCES= \
        tests/stub_fatal.cc \
        FileMap.h \
        filemap.cc \
-       fs/forward.h \
        HttpHeaderFieldStat.h \
        HttpHdrCc.h \
        HttpHdrCc.cc \
@@ -2841,7 +2827,6 @@ tests_testStore_SOURCES= \
        stmem.cc \
        repl_modules.h \
        store.cc \
-       store_dir.cc \
        store_io.cc \
        store_swapout.cc \
        StoreIOState.cc \
@@ -2858,7 +2843,6 @@ tests_testStore_SOURCES= \
        String.cc \
        StrList.h \
        StrList.cc \
-       SwapDir.cc \
        tests/CapturingStoreEntry.h \
        log/access_log.h \
        tests/stub_access_log.cc \
@@ -2941,6 +2925,7 @@ tests_testStore_LDADD= \
        ipc/libipc.la \
        anyp/libanyp.la \
        mem/libmem.la \
+       store/libstore.la \
        DiskIO/libdiskio.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
@@ -3045,11 +3030,10 @@ tests_testUfs_SOURCES = \
        fde.h \
        fde.cc \
        client_db.h \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        FileMap.h \
        filemap.cc \
-       fs/forward.h \
        HttpBody.h \
        HttpBody.cc \
        HttpReply.cc \
@@ -3083,14 +3067,12 @@ tests_testUfs_SOURCES = \
        EventLoop.cc \
        HttpMsg.cc \
        RemovalPolicy.cc \
-       store_dir.cc \
        repl_modules.h \
        store.cc \
        store_key_md5.h \
        store_key_md5.cc \
        Parsing.cc \
        ConfigOption.cc \
-       SwapDir.cc \
        tests/stub_acl.cc \
        cache_cf.h \
        YesNoNone.h \
@@ -3178,6 +3160,7 @@ tests_testUfs_LDADD = \
        base/libbase.la \
        ip/libip.la \
        mem/libmem.la \
+       store/libstore.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -3214,8 +3197,8 @@ tests_testRock_SOURCES = \
        tests/stub_CacheDigest.cc \
        ConfigOption.cc \
        ConfigParser.cc \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        ETag.cc \
        EventLoop.cc \
        event.cc \
@@ -3227,7 +3210,6 @@ tests_testRock_SOURCES = \
        fde.cc \
        FileMap.h \
        filemap.cc \
-       fs/forward.h \
        HttpHeaderFieldStat.h \
        HttpBody.h \
        HttpBody.cc \
@@ -3271,7 +3253,6 @@ tests_testRock_SOURCES = \
        StoreMetaUnpacker.cc \
        $(STOREMETA_SOURCE) \
        StoreSwapLogData.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -3285,7 +3266,6 @@ tests_testRock_SOURCES = \
        String.cc \
        StrList.h \
        StrList.cc \
-       SwapDir.cc \
        Transients.h \
        Transients.cc \
        tests/testRock.cc \
@@ -3357,6 +3337,7 @@ tests_testRock_LDADD = \
        ipc/libipc.la \
        base/libbase.la \
        mem/libmem.la \
+       store/libstore.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -3405,8 +3386,8 @@ tests_testURL_SOURCES = \
        CpuAffinitySet.cc \
        CpuAffinitySet.h \
        $(DELAY_POOL_SOURCE) \
-       disk.h \
-       disk.cc \
+       fs_io.h \
+       fs_io.cc \
        dlink.h \
        dlink.cc \
        $(DNSSOURCE) \
@@ -3424,7 +3405,6 @@ tests_testURL_SOURCES = \
        filemap.cc \
        fqdncache.h \
        fqdncache.cc \
-       fs/forward.h \
        FwdState.cc \
        FwdState.h \
        gopher.h \
@@ -3518,7 +3498,6 @@ tests_testURL_SOURCES = \
        store_client.cc \
        store_digest.h \
        tests/stub_store_digest.cc \
-       store_dir.cc \
        store_io.cc \
        store_key_md5.h \
        store_key_md5.cc \
@@ -3598,6 +3577,7 @@ tests_testURL_LDADD = \
        comm/libcomm.la \
        log/liblog.la \
        format/libformat.la \
+       store/libstore.la \
        $(REGEXLIB) \
        $(REPL_OBJS) \
        $(ADAPTATION_LIBS) \
index a4a4d4d602c184aa77a830961d11c560bef10fde..a23325005d5090f775305e82a952e5a1c16befac 100644 (file)
@@ -168,25 +168,12 @@ MemStore::reference(StoreEntry &)
 }
 
 bool
-MemStore::dereference(StoreEntry &, bool)
+MemStore::dereference(StoreEntry &)
 {
     // no need to keep e in the global store_table for us; we have our own map
     return false;
 }
 
-int
-MemStore::callback()
-{
-    return 0;
-}
-
-StoreSearch *
-MemStore::search(String const, HttpRequest *)
-{
-    fatal("not implemented");
-    return NULL;
-}
-
 StoreEntry *
 MemStore::get(const cache_key *key)
 {
@@ -220,13 +207,6 @@ MemStore::get(const cache_key *key)
     return NULL;
 }
 
-void
-MemStore::get(String const, STOREGETCLIENT, void *)
-{
-    // XXX: not needed but Store parent forces us to implement this
-    fatal("MemStore::get(key,callback,data) should not be called");
-}
-
 bool
 MemStore::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
 {
index 07d094c615b5ff1f092a00b672f9798ab2fdcb0a..6b0b6b4ba93e9c76d4bd05385abc64ba07bd485a 100644 (file)
@@ -13,6 +13,7 @@
 #include "ipc/mem/PageStack.h"
 #include "ipc/StoreMap.h"
 #include "Store.h"
+#include "store/Controlled.h"
 
 // StoreEntry restoration info not already stored by Ipc::StoreMap
 struct MemStoreMapExtraItem {
@@ -23,7 +24,7 @@ typedef Ipc::StoreMap MemStoreMap;
 
 /// Stores HTTP entities in RAM. Current implementation uses shared memory.
 /// Unlike a disk store (SwapDir), operations are synchronous (and fast).
-class MemStore: public Store, public Ipc::StoreMapCleaner
+class MemStore: public Store::Controlled, public Ipc::StoreMapCleaner
 {
 public:
     MemStore();
@@ -38,31 +39,27 @@ public:
     /// all data has been received; there will be no more write() calls
     void completeWriting(StoreEntry &e);
 
-    /// remove from the cache
-    void unlink(StoreEntry &e);
-
     /// called when the entry is about to forget its association with mem cache
     void disconnect(StoreEntry &e);
 
-    /* Store API */
-    virtual int callback();
-    virtual StoreEntry * get(const cache_key *);
-    virtual void get(String const key , STOREGETCLIENT callback, void *cbdata);
-    virtual void init();
-    virtual uint64_t maxSize() const;
-    virtual uint64_t minSize() const;
-    virtual uint64_t currentSize() const;
-    virtual uint64_t currentCount() const;
-    virtual int64_t maxObjectSize() const;
-    virtual void getStats(StoreInfoStats &stats) const;
-    virtual void stat(StoreEntry &) const;
-    virtual StoreSearch *search(String const url, HttpRequest *);
-    virtual void markForUnlink(StoreEntry &e);
-    virtual void reference(StoreEntry &);
-    virtual bool dereference(StoreEntry &, bool);
-    virtual void maintain();
-    virtual bool anchorCollapsed(StoreEntry &collapsed, bool &inSync);
-    virtual bool updateCollapsed(StoreEntry &collapsed);
+    /* Storage API */
+    virtual void create() override {}
+    virtual void init() override;
+    virtual StoreEntry *get(const cache_key *) override;
+    virtual uint64_t maxSize() const override;
+    virtual uint64_t minSize() const override;
+    virtual uint64_t currentSize() const override;
+    virtual uint64_t currentCount() const override;
+    virtual int64_t maxObjectSize() const override;
+    virtual void getStats(StoreInfoStats &stats) const override;
+    virtual void stat(StoreEntry &e) const override;
+    virtual void reference(StoreEntry &e) override;
+    virtual bool dereference(StoreEntry &e) override;
+    virtual void maintain() override;
+    virtual bool anchorCollapsed(StoreEntry &e, bool &inSync) override;
+    virtual bool updateCollapsed(StoreEntry &e) override;
+    virtual void markForUnlink(StoreEntry &) override;
+    virtual void unlink(StoreEntry &e) override;
 
     static int64_t EntryLimit();
 
@@ -81,7 +78,7 @@ protected:
     sfileno reserveSapForWriting(Ipc::Mem::PageId &page);
 
     // Ipc::StoreMapCleaner API
-    virtual void noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId);
+    virtual void noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId) override;
 
 private:
     // TODO: move freeSlots into map
index 7061070c1a64e029981a1c156851040be16a52c7..f1c110eada9bd074b57731ef130c9317556951dc 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "base/InstanceId.h"
 #include "Debug.h"
+#include "globals.h"
 #include "MemBlob.h"
 #include "SBufExceptions.h"
 #include "SquidString.h"
index 9d5e7e14e219c2f1242163e3bbf2621730b8c82c..cf0840db9459dbc998e503202ad36201e655d6af 100644 (file)
@@ -19,6 +19,7 @@
 #include "Notes.h"
 #include "security/forward.h"
 #include "SquidTime.h"
+#include "store/forward.h"
 #include "YesNoNone.h"
 
 #if USE_OPENSSL
@@ -37,13 +38,24 @@ class external_acl;
 class HeaderManglers;
 class RefreshPattern;
 class RemovalPolicySettings;
-class SwapDir;
 
 namespace AnyP
 {
 class PortCfg;
 }
 
+namespace Store {
+class DiskConfig {
+public:
+    RefCount<SwapDir> *swapDirs;
+    int n_allocated;
+    int n_configured;
+    /// number of disk processes required to support all cache_dirs
+    int n_strands;
+};
+#define INDEXSD(i) (Config.cacheSwap.swapDirs[i].getRaw())
+}
+
 /// the representation of the configuration. POD.
 class SquidConfig
 {
@@ -392,17 +404,7 @@ public:
     } Ftp;
     RefreshPattern *Refresh;
 
-    struct _cacheSwap {
-        RefCount<SwapDir> *swapDirs;
-        int n_allocated;
-        int n_configured;
-        /// number of disk processes required to support all cache_dirs
-        int n_strands;
-    } cacheSwap;
-    /*
-     * I'm sick of having to keep doing this ..
-     */
-#define INDEXSD(i)   (Config.cacheSwap.swapDirs[(i)].getRaw())
+    Store::DiskConfig cacheSwap;
 
     struct {
         char *directory;
index d69134eb85cad2a8b2b4f8cc4ec02fe05169be3f..a8f43f99632fc4bcb41db92be8771a819295b2f0 100644 (file)
@@ -20,6 +20,8 @@
 #include "MemObject.h"
 #include "Range.h"
 #include "RemovalPolicy.h"
+#include "store/Controller.h"
+#include "store/forward.h"
 #include "store_key_md5.h"
 #include "StoreIOBuffer.h"
 #include "StoreStats.h"
 class AsyncCall;
 class HttpRequest;
 class RequestFlags;
-class StoreClient;
-class StoreSearch;
-class SwapDir;
 
 extern StoreIoStats store_io_stats;
 
-/// maximum number of entries per cache_dir
-enum { SwapFilenMax = 0xFFFFFF }; // keep in sync with StoreEntry::swap_filen
-
 class StoreEntry : public hash_link, public Packable
 {
     MEMPROXY_CLASS(StoreEntry);
@@ -87,7 +83,6 @@ public:
     void swapOutDecision(const MemObject::SwapOut::Decision &decision);
 
     void abort();
-    void unlink();
     void makePublic();
     void makePrivate();
     void setPublicKey();
@@ -141,8 +136,8 @@ public:
     /// whether this entry has an ETag; if yes, puts ETag value into parameter
     bool hasEtag(ETag &etag) const;
 
-    /** What store does this entry belong too ? */
-    virtual RefCount<SwapDir> store() const;
+    /// the disk this entry is [being] cached on; asserts for entries w/o a disk
+    Store::Disk &disk() const;
 
     MemObject *mem_obj;
     RemovalPolicyNode repl;
@@ -272,164 +267,12 @@ private:
 /// \ingroup StoreAPI
 typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata);
 
-/**
- \ingroup StoreAPI
- * Abstract base class that will replace the whole store and swapdir interface.
- */
-class Store : public RefCountable
-{
-
-public:
-    /** The root store */
-    static Store &Root() {
-        if (CurrentRoot == NULL)
-            fatal("No Store Root has been set");
-        return *CurrentRoot;
-    }
-    static void Root(Store *);
-    static void Root(RefCount<Store>);
-    static void Stats(StoreEntry * output);
-    static void Maintain(void *unused);
-
-    virtual ~Store() {}
-
-    /** Handle pending callbacks - called by the event loop. */
-    virtual int callback() = 0;
-
-    /** create the resources needed for this store to operate */
-    virtual void create();
-
-    /**
-     * Notify this store that its disk is full.
-     \todo XXX move into a protected api call between store files and their stores, rather than a top level api call
-     */
-    virtual void diskFull();
-
-    /** Retrieve a store entry from the store */
-    virtual StoreEntry * get(const cache_key *) = 0;
-
-    /** \todo imeplement the async version */
-    virtual void get(String const key , STOREGETCLIENT callback, void *cbdata) = 0;
-
-    /* prepare the store for use. The store need not be usable immediately,
-     * it should respond to readable() and writable() with true as soon
-     * as it can provide those services
-     */
-    virtual void init() = 0;
-
-    /**
-     * The maximum size the store will support in normal use. Inaccuracy is permitted,
-     * but may throw estimates for memory etc out of whack.
-     */
-    virtual uint64_t maxSize() const = 0;
-
-    /** The minimum size the store will shrink to via normal housekeeping */
-    virtual uint64_t minSize() const = 0;
-
-    /** current store size */
-    virtual uint64_t currentSize() const = 0;
-
-    /** the total number of objects stored */
-    virtual uint64_t currentCount() const = 0;
-
-    /** the maximum object size that can be stored, -1 if unlimited */
-    virtual int64_t maxObjectSize() const = 0;
-
-    /// collect cache storage-related statistics
-    virtual void getStats(StoreInfoStats &stats) const = 0;
-
-    /**
-     * Output stats to the provided store entry.
-     \todo make these calls asynchronous
-     */
-    virtual void stat(StoreEntry &) const = 0;
-
-    /** Sync the store prior to shutdown */
-    virtual void sync();
-
-    /** remove a Store entry from the store */
-    virtual void unlink (StoreEntry &);
-
-    /* search in the store */
-    virtual StoreSearch *search(String const url, HttpRequest *) = 0;
-
-    /* pulled up from SwapDir for migration.... probably do not belong here */
-    virtual void reference(StoreEntry &) = 0;   /* Reference this object */
-
-    /// Undo reference(), returning false iff idle e should be destroyed
-    virtual bool dereference(StoreEntry &, bool wantsLocalMemory) = 0;
-
-    virtual void maintain() = 0; /* perform regular maintenance should be private and self registered ... */
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// informs stores that this entry will be eventually unlinked
-    virtual void markForUnlink(StoreEntry &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // because test cases use non-StoreController derivatives as Root
-    /// called when the entry is no longer needed by any transaction
-    virtual void handleIdleEntry(StoreEntry &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // because test cases use non-StoreController derivatives as Root
-    /// called to get rid of no longer needed entry data in RAM, if any
-    virtual void memoryOut(StoreEntry &, const bool /*preserveSwappable*/) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// makes the entry available for collapsing future requests
-    virtual void allowCollapsing(StoreEntry *, const RequestFlags &, const HttpRequestMethod &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// marks the entry completed for collapsed requests
-    virtual void transientsCompleteWriting(StoreEntry &) {}
 
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// Update local intransit entry after changes made by appending worker.
-    virtual void syncCollapsed(const sfileno) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// calls Root().transients->abandon() if transients are tracked
-    virtual void transientsAbandon(StoreEntry &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// number of the transient entry readers some time ago
-    virtual int transientReaders(const StoreEntry &) const { return 0; }
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// disassociates the entry from the intransit table
-    virtual void transientsDisconnect(MemObject &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// removes the entry from the memory cache
-    virtual void memoryUnlink(StoreEntry &) {}
-
-    // XXX: This method belongs to Store::Root/StoreController, but it is here
-    // to avoid casting Root() to StoreController until Root() API is fixed.
-    /// disassociates the entry from the memory cache, preserving cached data
-    virtual void memoryDisconnect(StoreEntry &) {}
-
-    /// If the entry is not found, return false. Otherwise, return true after
-    /// tying the entry to this cache and setting inSync to updateCollapsed().
-    virtual bool anchorCollapsed(StoreEntry &, bool &/*inSync*/) { return false; }
-
-    /// update a local collapsed entry with fresh info from this cache (if any)
-    virtual bool updateCollapsed(StoreEntry &) { return false; }
-
-private:
-    static RefCount<Store> CurrentRoot;
+namespace Store {
+    void Stats(StoreEntry *output);
+    void Maintain(void *unused);
 };
 
-/// \ingroup StoreAPI
-typedef RefCount<Store> StorePointer;
-
 /// \ingroup StoreAPI
 size_t storeEntryInUse();
 
@@ -477,7 +320,6 @@ void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
 /// \ingroup StoreAPI
 int storeTooManyDiskFilesOpen(void);
 
-class SwapDir;
 /// \ingroup StoreAPI
 void storeHeapPositionUpdate(StoreEntry *, SwapDir *);
 
index 031eb5c8a180ce387d7193c83e751090ac1d90e8..c33620b6bed33bddcec03a68feb22732d006b5df 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef SQUID_STOREFILESYSTEM_H
 #define SQUID_STOREFILESYSTEM_H
 
+#include "store/forward.h"
 #include <vector>
 
 /* ****** DOCUMENTATION ***** */
@@ -79,8 +80,6 @@
  *    given StoreEntry. A maxobjsize of -1 means 'any size'.
  */
 
-class SwapDir;
-
 /**
  \ingroup FileSystems
  *
diff --git a/src/StoreHashIndex.h b/src/StoreHashIndex.h
deleted file mode 100644 (file)
index 167b37e..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef SQUID_STOREHASHINDEX_H
-#define SQUID_STOREHASHINDEX_H
-
-#include "Store.h"
-#include "StoreSearch.h"
-
-/* A summary store that indexs all its children
- * into a memory hash
- */
-
-class StoreSearch;
-
-class StoreHashIndex : public Store
-{
-
-public:
-    StoreHashIndex();
-    StoreHashIndex(StoreHashIndex const &); /* to cause link failures */
-    virtual ~StoreHashIndex();
-    virtual int callback();
-    virtual void create();
-
-    virtual StoreEntry * get
-    (const cache_key *);
-
-    virtual void get
-    (String const, STOREGETCLIENT, void * cbdata);
-
-    virtual void init();
-
-    virtual void sync();
-
-    virtual uint64_t maxSize() const;
-
-    virtual uint64_t minSize() const;
-
-    virtual uint64_t currentSize() const;
-
-    virtual uint64_t currentCount() const;
-
-    virtual int64_t maxObjectSize() const;
-
-    virtual void getStats(StoreInfoStats &stats) const;
-    virtual void stat(StoreEntry&) const;
-
-    virtual void reference(StoreEntry&);
-
-    virtual bool dereference(StoreEntry&, bool);
-
-    virtual void maintain();
-
-    virtual StoreSearch *search(String const url, HttpRequest *);
-
-private:
-    /* migration logic */
-    StorePointer store(int const x) const;
-    SwapDir &dir(int const idx) const;
-};
-
-class StoreHashIndexEntry : public StoreEntry
-{};
-
-class StoreSearchHashIndex : public StoreSearch
-{
-    CBDATA_CLASS(StoreSearchHashIndex);
-
-public:
-    StoreSearchHashIndex(RefCount<StoreHashIndex> sd);
-    StoreSearchHashIndex(StoreSearchHashIndex const &);
-    virtual ~StoreSearchHashIndex();
-    /* Iterator API - garh, wrong place */
-    /* callback the client when a new StoreEntry is available
-     * or an error occurs
-     */
-    virtual void next(void (callback)(void *cbdata), void *cbdata);
-    /* return true if a new StoreEntry is immediately available */
-    virtual bool next();
-    virtual bool error() const;
-    virtual bool isDone() const;
-    virtual StoreEntry *currentItem();
-
-    RefCount<StoreHashIndex> sd;
-
-private:
-    void copyBucket();
-    void (*callback)(void *cbdata);
-    void *cbdata;
-    bool _done;
-    int bucket;
-    std::vector<StoreEntry *> entries;
-};
-
-#endif /* SQUID_STOREHASHINDEX_H */
-
index a4b6709ccba7a29bbc7623692e7379a612f9aa71..858a30856d8cd40f324008246f7cbc57f6bef50a 100644 (file)
@@ -11,8 +11,8 @@
 
 #include "base/RefCount.h"
 #include "cbdata.h"
-#include "fs/forward.h"
 #include "mem/forward.h"
+#include "store/forward.h"
 
 class StoreIOState : public RefCountable
 {
index edb470a667166673b2562fd07539307c0083afa0..8832fc41da2bcc99e89b887818384edeb9ce165a 100644 (file)
@@ -35,9 +35,9 @@
  *      the value for MemObject->swap_hdr_sz.
  */
 
-#include "fs/forward.h"
 #include "md5.h"
 #include "mem/forward.h"
+#include "store/forward.h"
 
 /// maintains a 24-bit checksum over integer fields
 class SwapChecksum24
diff --git a/src/SwapDir.h b/src/SwapDir.h
deleted file mode 100644 (file)
index 8374b1e..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef SQUID_SWAPDIR_H
-#define SQUID_SWAPDIR_H
-
-#include "mgr/forward.h"
-#include "SquidConfig.h"
-#include "Store.h"
-#include "StoreIOState.h"
-
-/* forward decls */
-class RemovalPolicy;
-class MemStore;
-class Transients;
-class RequestFlags;
-class HttpRequestMethod;
-
-/* Store dir configuration routines */
-/* SwapDir *sd, char *path ( + char *opt later when the strtok mess is gone) */
-
-typedef int STDIRSELECT(const StoreEntry *);
-
-class ConfigOption;
-
-/// hides memory/disk cache distinction from callers
-class StoreController : public Store
-{
-
-public:
-    StoreController();
-    virtual ~StoreController();
-    virtual int callback();
-    virtual void create();
-
-    virtual StoreEntry * get(const cache_key *);
-
-    virtual void get(String const, STOREGETCLIENT, void * cbdata);
-
-    /* Store parent API */
-    virtual void markForUnlink(StoreEntry &e);
-    virtual void handleIdleEntry(StoreEntry &e);
-    virtual void transientsCompleteWriting(StoreEntry &e);
-    virtual void transientsAbandon(StoreEntry &e);
-    virtual int transientReaders(const StoreEntry &e) const;
-    virtual void transientsDisconnect(MemObject &mem_obj);
-    virtual void memoryOut(StoreEntry &e, const bool preserveSwappable);
-    virtual void memoryUnlink(StoreEntry &e);
-    virtual void memoryDisconnect(StoreEntry &e);
-    virtual void allowCollapsing(StoreEntry *e, const RequestFlags &reqFlags, const HttpRequestMethod &reqMethod);
-    virtual void syncCollapsed(const sfileno xitIndex);
-
-    virtual void init();
-
-    virtual void maintain(); /* perform regular maintenance should be private and self registered ... */
-
-    virtual uint64_t maxSize() const;
-
-    virtual uint64_t minSize() const;
-
-    virtual uint64_t currentSize() const;
-
-    virtual uint64_t currentCount() const;
-
-    virtual int64_t maxObjectSize() const;
-
-    virtual void getStats(StoreInfoStats &stats) const;
-    virtual void stat(StoreEntry &) const;
-
-    virtual void sync();    /* Sync the store prior to shutdown */
-
-    virtual StoreSearch *search(String const url, HttpRequest *);
-
-    virtual void reference(StoreEntry &);   /* Reference this object */
-
-    virtual bool dereference(StoreEntry &, bool);   /* Unreference this object */
-
-    /* the number of store dirs being rebuilt. */
-    static int store_dirs_rebuilding;
-
-private:
-    void createOneStore(Store &aStore);
-    StoreEntry *find(const cache_key *key);
-    bool keepForLocalMemoryCache(StoreEntry &e) const;
-    bool anchorCollapsed(StoreEntry &collapsed, bool &inSync);
-    bool anchorCollapsedOnDisk(StoreEntry &collapsed, bool &inSync);
-
-    StorePointer swapDir; ///< summary view of all disk caches
-    MemStore *memStore; ///< memory cache
-
-    /// A shared table of public store entries that do not know whether they
-    /// will belong to a memory cache, a disk cache, or will be uncachable
-    /// when the response header comes. Used for SMP collapsed forwarding.
-    Transients *transients;
-};
-
-/* migrating from the Config based list of swapdirs */
-void allocate_new_swapdir(SquidConfig::_cacheSwap *);
-void free_cachedir(SquidConfig::_cacheSwap * swap);
-extern OBJH storeDirStats;
-char *storeDirSwapLogFile(int, const char *);
-char *storeSwapFullPath(int, char *);
-char *storeSwapSubSubDir(int, char *);
-const char *storeSwapPath(int);
-int storeDirWriteCleanLogs(int reopen);
-extern STDIRSELECT *storeDirSelectSwapDir;
-int storeVerifySwapDirs(void);
-void storeDirCloseSwapLogs(void);
-void storeDirCloseTmpSwapLog(int dirn);
-void storeDirDiskFull(sdirno);
-void storeDirOpenSwapLogs(void);
-void storeDirSwapLog(const StoreEntry *, int op);
-void storeDirLRUDelete(StoreEntry *);
-void storeDirLRUAdd(StoreEntry *);
-int storeDirGetBlkSize(const char *path, int *blksize);
-int storeDirGetUFSStats(const char *, int *, int *, int *, int *);
-
-/// manages a single cache_dir
-class SwapDir : public Store
-{
-
-public:
-    typedef RefCount<SwapDir> Pointer;
-
-    SwapDir(char const *aType);
-    virtual ~SwapDir();
-    virtual void reconfigure() = 0;
-    char const *type() const;
-
-    virtual bool needsDiskStrand() const; ///< needs a dedicated kid process
-    virtual bool active() const; ///< may be used in this strand
-    /// whether stat should be reported by this SwapDir
-    virtual bool doReportStat() const { return active(); }
-    /// whether SwapDir may benefit from unlinkd
-    virtual bool unlinkdUseful() const = 0;
-
-    /* official Store interface functions */
-    virtual void diskFull();
-
-    virtual StoreEntry * get(const cache_key *);
-
-    virtual void get(String const, STOREGETCLIENT, void * cbdata);
-
-    virtual uint64_t maxSize() const { return max_size;}
-
-    virtual uint64_t minSize() const;
-
-    /// The maximum size of object which may be stored here.
-    /// Larger objects will not be added and may be purged.
-    virtual int64_t maxObjectSize() const;
-
-    /// configure the maximum object size for this storage area.
-    /// May be any size up to the total storage area.
-    void maxObjectSize(int64_t newMax);
-
-    virtual void getStats(StoreInfoStats &stats) const;
-    virtual void stat (StoreEntry &anEntry) const;
-    virtual StoreSearch *search(String const url, HttpRequest *) = 0;
-
-    /* migrated from store_dir.cc */
-    bool objectSizeIsAcceptable(int64_t objsize) const;
-
-    /// called when the entry is about to forget its association with cache_dir
-    virtual void disconnect(StoreEntry &) {}
-
-    /// called when entry swap out is complete
-    virtual void swappedOut(const StoreEntry &e) = 0;
-
-protected:
-    void parseOptions(int reconfiguring);
-    void dumpOptions(StoreEntry * e) const;
-    virtual ConfigOption *getOptionTree() const;
-    virtual bool allowOptionReconfigure(const char *const) const { return true; }
-
-    int64_t sizeInBlocks(const int64_t size) const { return (size + fs.blksize - 1) / fs.blksize; }
-
-private:
-    bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
-    void optionReadOnlyDump(StoreEntry * e) const;
-    bool optionObjectSizeParse(char const *option, const char *value, int reconfiguring);
-    void optionObjectSizeDump(StoreEntry * e) const;
-    char const *theType;
-
-protected:
-    uint64_t max_size;        ///< maximum allocatable size of the storage area
-    int64_t min_objsize;      ///< minimum size of any object stored here (-1 for no limit)
-    int64_t max_objsize;      ///< maximum size of any object stored here (-1 for no limit)
-
-public:
-    char *path;
-    int index;          /* This entry's index into the swapDirs array */
-    int disker; ///< disker kid id dedicated to this SwapDir or -1
-    RemovalPolicy *repl;
-    int removals;
-    int scanned;
-
-    struct Flags {
-        Flags() : selected(false), read_only(false) {}
-        bool selected;
-        bool read_only;
-    } flags;
-    virtual void init() = 0;    /* Initialise the fs */
-    virtual void create();  /* Create a new fs */
-    virtual void dump(StoreEntry &)const;   /* Dump fs config snippet */
-    virtual bool doubleCheck(StoreEntry &); /* Double check the obj integrity */
-    virtual void statfs(StoreEntry &) const;    /* Dump fs statistics */
-    virtual void maintain();    /* Replacement maintainence */
-    /// check whether we can store the entry; if we can, report current load
-    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const = 0;
-    /* These two are notifications */
-    virtual void reference(StoreEntry &);   /* Reference this object */
-    virtual bool dereference(StoreEntry &, bool);   /* Unreference this object */
-    virtual int callback(); /* Handle pending callbacks */
-    virtual void sync();    /* Sync the store prior to shutdown */
-    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
-    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
-    virtual void unlink (StoreEntry &);
-    bool canLog(StoreEntry const &e)const;
-    virtual void openLog();
-    virtual void closeLog();
-    virtual void logEntry(const StoreEntry & e, int op) const;
-
-    class CleanLog
-    {
-
-    public:
-        virtual ~CleanLog() {}
-
-        virtual const StoreEntry *nextEntry() = 0;
-        virtual void write(StoreEntry const &) = 0;
-    };
-
-    CleanLog *cleanLog;
-    virtual int writeCleanStart();
-    virtual void writeCleanDone();
-    virtual void parse(int index, char *path) = 0;
-
-    struct {
-        int blksize;
-    } fs;
-};
-
-#endif /* SQUID_SWAPDIR_H */
-
index 6d2aab7c5fea2546f24ec7851ecbbedabe69ab91..2860edc000968491180013af9f79feac926f8d4e 100644 (file)
@@ -137,25 +137,12 @@ Transients::reference(StoreEntry &)
 }
 
 bool
-Transients::dereference(StoreEntry &, bool)
+Transients::dereference(StoreEntry &)
 {
     // no need to keep e in the global store_table for us; we have our own map
     return false;
 }
 
-int
-Transients::callback()
-{
-    return 0;
-}
-
-StoreSearch *
-Transients::search(String const, HttpRequest *)
-{
-    fatal("not implemented");
-    return NULL;
-}
-
 StoreEntry *
 Transients::get(const cache_key *key)
 {
@@ -212,13 +199,6 @@ Transients::copyFromShm(const sfileno index)
     return e;
 }
 
-void
-Transients::get(String const, STOREGETCLIENT, void *)
-{
-    // XXX: not needed but Store parent forces us to implement this
-    fatal("Transients::get(key,callback,data) should not be called");
-}
-
 StoreEntry *
 Transients::findCollapsed(const sfileno index)
 {
@@ -354,6 +334,12 @@ Transients::readers(const StoreEntry &e) const
 
 void
 Transients::markForUnlink(StoreEntry &e)
+{
+    unlink(e);
+}
+
+void
+Transients::unlink(StoreEntry &e)
 {
     if (e.mem_obj && e.mem_obj->xitTable.io == MemObject::ioWriting)
         abandon(e);
index acc262141b48a0de211191dae0a636bd6ce59931..d91241a96a19567fd3774ba71c51b45432393289 100644 (file)
@@ -14,6 +14,7 @@
 #include "ipc/mem/PageStack.h"
 #include "ipc/StoreMap.h"
 #include "Store.h"
+#include "store/Controlled.h"
 #include <vector>
 
 // StoreEntry restoration info not already stored by Ipc::StoreMap
@@ -28,7 +29,7 @@ typedef Ipc::StoreMap TransientsMap;
 /// Keeps track of store entries being delivered to clients that arrived before
 /// those entries were [fully] cached. This shared table is necessary to sync
 /// the entry-writing worker with entry-reading worker(s).
-class Transients: public Store, public Ipc::StoreMapCleaner
+class Transients: public Store::Controlled, public Ipc::StoreMapCleaner
 {
 public:
     Transients();
@@ -56,22 +57,21 @@ public:
     void disconnect(MemObject &mem_obj);
 
     /* Store API */
-    virtual int callback();
-    virtual StoreEntry * get(const cache_key *);
-    virtual void get(String const key , STOREGETCLIENT callback, void *cbdata);
-    virtual void init();
-    virtual uint64_t maxSize() const;
-    virtual uint64_t minSize() const;
-    virtual uint64_t currentSize() const;
-    virtual uint64_t currentCount() const;
-    virtual int64_t maxObjectSize() const;
-    virtual void getStats(StoreInfoStats &stats) const;
-    virtual void stat(StoreEntry &) const;
-    virtual StoreSearch *search(String const url, HttpRequest *);
-    virtual void reference(StoreEntry &);
-    virtual bool dereference(StoreEntry &, bool);
-    virtual void markForUnlink(StoreEntry &e);
-    virtual void maintain();
+    virtual StoreEntry *get(const cache_key *) override;
+    virtual void create() override {}
+    virtual void init() override;
+    virtual uint64_t maxSize() const override;
+    virtual uint64_t minSize() const override;
+    virtual uint64_t currentSize() const override;
+    virtual uint64_t currentCount() const override;
+    virtual int64_t maxObjectSize() const override;
+    virtual void getStats(StoreInfoStats &stats) const override;
+    virtual void stat(StoreEntry &e) const override;
+    virtual void reference(StoreEntry &e) override;
+    virtual bool dereference(StoreEntry &e) override;
+    virtual void markForUnlink(StoreEntry &e) override;
+    virtual void unlink(StoreEntry &e) override;
+    virtual void maintain() override;
 
     static int64_t EntryLimit();
 
@@ -82,7 +82,7 @@ protected:
     bool abandonedAt(const sfileno index) const;
 
     // Ipc::StoreMapCleaner API
-    virtual void noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId);
+    virtual void noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId) override;
 
 private:
     /// shared packed info indexed by Store keys, for creating new StoreEntries
index ec2a98c9d7dfb958a6a121b8e15caed0cfc7486f..85a5477249901e016548870a5c696e00fb7e2384 100644 (file)
@@ -64,6 +64,8 @@ public:
     }
 #endif
 
+    explicit operator bool() const { return p_; }
+
     bool operator !() const { return !p_; }
 
     C * operator-> () const {return const_cast<C *>(p_); }
index 1bce018cb59d6aa5f6652b71ee64e0609ebfb6fd..ae5d880e541635da3e0a354f1c7fa5f8a22c7de3 100644 (file)
@@ -57,8 +57,9 @@
 #include "SquidString.h"
 #include "ssl/ProxyCerts.h"
 #include "Store.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
 #include "StoreFileSystem.h"
-#include "SwapDir.h"
 #include "tools.h"
 #include "util.h"
 #include "wordlist.h"
@@ -1727,7 +1728,7 @@ parse_http_header_replace(HeaderManglers **pm)
 #endif
 
 static void
-dump_cachedir(StoreEntry * entry, const char *name, SquidConfig::_cacheSwap swap)
+dump_cachedir(StoreEntry * entry, const char *name, const Store::DiskConfig &swap)
 {
     SwapDir *s;
     int i;
@@ -1816,7 +1817,7 @@ find_fstype(char *type)
 }
 
 static void
-parse_cachedir(SquidConfig::_cacheSwap * swap)
+parse_cachedir(Store::DiskConfig *swap)
 {
     char *type_str;
     char *path_str;
index b6da58c00b1db6bc6f3b536981879f627b624412..6587619e99e04b556b23a1dc6ca2a464516a3f0d 100644 (file)
 #include "clients/forward.h"
 #include "comm/Connection.h"
 #include "comm/Write.h"
-#include "disk.h"
 #include "err_detail_type.h"
 #include "errorpage.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "html_quote.h"
 #include "HttpHeaderTools.h"
 #include "HttpReply.h"
index 5f3485eac5dc5cd419770ccc38d026a4b7e39b35..105d9309eb69dff9cf825513a997eedaabd7c1fd 100644 (file)
@@ -10,7 +10,7 @@
 #include "Debug.h"
 #include "fatal.h"
 #include "globals.h"
-#include "SwapDir.h"
+#include "store/Disks.h"
 #include "tools.h"
 
 static void
@@ -42,9 +42,6 @@ fatal(const char *message)
     shutting_down = 1;
 
     releaseServerSockets();
-    /* check for store_dirs_rebuilding because fatal() is often
-     * used in early initialization phases, long before we ever
-     * get to the store log. */
 
     /* XXX: this should be turned into a callback-on-fatal, or
      * a mandatory-shutdown-event or something like that.
@@ -61,8 +58,7 @@ fatal(const char *message)
      */
     leave_suid();
 
-    if (0 == StoreController::store_dirs_rebuilding)
-        storeDirWriteCleanLogs(0);
+    storeDirWriteCleanLogs(0);
 
     fatal_common(message);
 
index 576eb409b3eec62fafe24ace33820b8fde0cfa00..cc483ff3aa701075e16c3a930745e6754220036e 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef SQUID_FS_ROCK_DB_CELL_H
 #define SQUID_FS_ROCK_DB_CELL_H
 
-#include "fs/forward.h"
+#include "store/forward.h"
 
 namespace Rock
 {
index 2a8682f2d98dfecfc8d87e70e3c0347c2ff78861..58689868da548bf012fc6d2279977225a4fbdc19 100644 (file)
@@ -9,14 +9,16 @@
 /* DEBUG: section 79    Disk IO Routines */
 
 #include "squid.h"
-#include "disk.h"
+#include "base/AsyncJobCalls.h"
 #include "fs/rock/RockDbCell.h"
 #include "fs/rock/RockRebuild.h"
 #include "fs/rock/RockSwapDir.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "ipc/StoreMap.h"
 #include "md5.h"
 #include "SquidTime.h"
+#include "Store.h"
 #include "store_rebuild.h"
 #include "tools.h"
 
index 14ad992754fa2a63c3d23778a64cb9b1a6320545..65004291aaf251d5fd383640a796b86f12de258a 100644 (file)
@@ -51,19 +51,6 @@ Rock::SwapDir::~SwapDir()
     safe_free(filePath);
 }
 
-StoreSearch *
-Rock::SwapDir::search(String const, HttpRequest *)
-{
-    assert(false);
-    return NULL; // XXX: implement
-}
-
-void
-Rock::SwapDir::get(String const key, STOREGETCLIENT cb, void *data)
-{
-    ::SwapDir::get(key, cb, data);
-}
-
 // called when Squid core needs a StoreEntry with a given key
 StoreEntry *
 Rock::SwapDir::get(const cache_key *key)
@@ -924,7 +911,7 @@ Rock::SwapDir::reference(StoreEntry &e)
 }
 
 bool
-Rock::SwapDir::dereference(StoreEntry &e, bool)
+Rock::SwapDir::dereference(StoreEntry &e)
 {
     debugs(47, 5, HERE << &e << ' ' << e.swap_dirn << ' ' << e.swap_filen);
     if (repl && repl->Dereferenced)
index 153cfcc34e0fab92ce5676b890e207d85f456290..1c73c6c812dfa7a99cfe8adfd31917731ff0985e 100644 (file)
@@ -16,7 +16,7 @@
 #include "ipc/mem/Page.h"
 #include "ipc/mem/PageStack.h"
 #include "ipc/StoreMap.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
 
 class DiskIOStrategy;
 class ReadRequest;
@@ -37,9 +37,7 @@ public:
 
     /* public ::SwapDir API */
     virtual void reconfigure();
-    virtual StoreSearch *search(String const url, HttpRequest *);
     virtual StoreEntry *get(const cache_key *key);
-    virtual void get(String const, STOREGETCLIENT, void * cbdata);
     virtual void markForUnlink(StoreEntry &e);
     virtual void disconnect(StoreEntry &e);
     virtual uint64_t currentSize() const;
@@ -91,7 +89,7 @@ protected:
     virtual void maintain();
     virtual void diskFull();
     virtual void reference(StoreEntry &e);
-    virtual bool dereference(StoreEntry &e, bool);
+    virtual bool dereference(StoreEntry &e);
     virtual bool unlinkdUseful() const;
     virtual void unlink(StoreEntry &e);
     virtual void statfs(StoreEntry &e) const;
index eff5e4550cd22b2fd26ca5e89d00e9bf41c77662..da85c2b38dcc5f25b00a097308e2f190d6435217 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef SQUID_FS_ROCK_FORWARD_H
 #define SQUID_FS_ROCK_FORWARD_H
 
-#include "fs/forward.h"
+#include "store/forward.h"
 
 namespace Ipc
 {
index b5d1b75951a086bcd626fd9d0b9f67fd0dc262a1..ce4e9eac7f6716acdc1669f6fc866257f51358eb 100644 (file)
@@ -9,11 +9,12 @@
 /* DEBUG: section 47    Store Directory Routines */
 
 #include "squid.h"
-#include "disk.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "RebuildState.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
+#include "store/Disks.h"
 #include "store_key_md5.h"
 #include "store_rebuild.h"
 #include "StoreSwapLogData.h"
@@ -345,7 +346,7 @@ Fs::Ufs::RebuildState::rebuildFromSwapLog()
             currentEntry()->lastmod = swapData.lastmod;
             currentEntry()->flags = swapData.flags;
             currentEntry()->refcount += swapData.refcount;
-            sd->dereference(*currentEntry(), false);
+            sd->dereference(*currentEntry());
         } else {
             debug_trap("commonUfsDirRebuildFromSwapLog: bad condition");
             debugs(47, DBG_IMPORTANT, HERE << "bad condition");
index 76ef4d9be2e948beb049d21c49976b504484c6fd..5be2a46e01c5205ba18c6489214cfe9f50a77c9d 100644 (file)
@@ -16,7 +16,7 @@
 #include "Generic.h"
 #include "SquidList.h"
 #include "Store.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
 #include "UFSStoreState.h"
 #include "UFSStrategy.h"
 
index 371e7fdfd2041d7e7a81c2af87a38850db70ae32..5c5a15398292f66db9007590aa72be2e9406c693 100644 (file)
 #include "squid.h"
 #include "cache_cf.h"
 #include "ConfigOption.h"
-#include "disk.h"
 #include "DiskIO/DiskIOModule.h"
 #include "DiskIO/DiskIOStrategy.h"
 #include "fde.h"
 #include "FileMap.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "Parsing.h"
 #include "RebuildState.h"
@@ -293,7 +293,7 @@ Fs::Ufs::UFSSwapDir::init()
         started_clean_event = 1;
     }
 
-    (void) storeDirGetBlkSize(path, &fs.blksize);
+    (void) fsBlockSize(path, &fs.blksize);
 }
 
 void
@@ -383,7 +383,7 @@ Fs::Ufs::UFSSwapDir::statfs(StoreEntry & sentry) const
     storeAppendPrintf(&sentry, "Filemap bits in use: %d of %d (%d%%)\n",
                       map->numFilesInMap(), map->capacity(),
                       Math::intPercent(map->numFilesInMap(), map->capacity()));
-    x = storeDirGetUFSStats(path, &totl_kb, &free_kb, &totl_in, &free_in);
+    x = fsStats(path, &totl_kb, &free_kb, &totl_in, &free_in);
 
     if (0 == x) {
         storeAppendPrintf(&sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n",
@@ -530,7 +530,7 @@ Fs::Ufs::UFSSwapDir::reference(StoreEntry &e)
 }
 
 bool
-Fs::Ufs::UFSSwapDir::dereference(StoreEntry & e, bool)
+Fs::Ufs::UFSSwapDir::dereference(StoreEntry & e)
 {
     debugs(47, 3, HERE << "dereferencing " << &e << " " <<
            e.swap_dirn << "/" << e.swap_filen);
@@ -1200,6 +1200,9 @@ Fs::Ufs::UFSSwapDir::unlink(StoreEntry & e)
     replacementRemove(&e);
     mapBitReset(e.swap_filen);
     UFSSwapDir::unlinkFile(e.swap_filen);
+    e.swap_filen = -1;
+    e.swap_dirn = -1;
+    e.swap_status = SWAPOUT_NONE;
 }
 
 void
@@ -1212,12 +1215,10 @@ Fs::Ufs::UFSSwapDir::replacementAdd(StoreEntry * e)
 void
 Fs::Ufs::UFSSwapDir::replacementRemove(StoreEntry * e)
 {
-    StorePointer SD;
-
     if (e->swap_dirn < 0)
         return;
 
-    SD = INDEXSD(e->swap_dirn);
+    SwapDirPointer SD = INDEXSD(e->swap_dirn);
 
     assert (dynamic_cast<UFSSwapDir *>(SD.getRaw()) == this);
 
@@ -1273,15 +1274,6 @@ Fs::Ufs::UFSSwapDir::swappedOut(const StoreEntry &e)
     ++n_disk_objects;
 }
 
-StoreSearch *
-Fs::Ufs::UFSSwapDir::search(String const url, HttpRequest *)
-{
-    if (url.size())
-        fatal ("Cannot search by url yet\n");
-
-    return new Fs::Ufs::StoreSearchUFS (this);
-}
-
 void
 Fs::Ufs::UFSSwapDir::logEntry(const StoreEntry & e, int op) const
 {
index 4fa45a4327b0c699b4a0859e71857ccf559a4f33..49ac3a4f364e932e436a06195848599f0aa22188 100644 (file)
 
 #include "SquidString.h"
 #include "Store.h"
+#include "store/Disk.h"
 #include "StoreIOState.h"
 #include "StoreSearch.h"
 #include "swap_log_op.h"
-#include "SwapDir.h"
 #include "UFSStrategy.h"
 
 class HttpRequest;
@@ -41,55 +41,36 @@ public:
     static bool FilenoBelongsHere(int fn, int cachedir, int level1dir, int level2dir);
 
     UFSSwapDir(char const *aType, const char *aModuleType);
-    /** Initial setup / end destruction */
-    virtual void init();
-    /** Create a new SwapDir (-z command-line option) */
-    virtual void create();
-    virtual void dump(StoreEntry &) const;
-    ~UFSSwapDir();
-    virtual StoreSearch *search(String const url, HttpRequest *);
-    /** double-check swap during rebuild (-S command-line option)
-     *
-     * called by storeCleanup if needed
-     */
-    virtual bool doubleCheck(StoreEntry &);
-    virtual bool unlinkdUseful() const;
-    /** unlink a file, and remove its entry from the filemap */
-    virtual void unlink(StoreEntry &);
-    virtual void statfs(StoreEntry &)const;
-    virtual void maintain();
-    /** check whether this filesystem can store the given object
-     *
-     * UFS filesystems will happily store anything as long as
-     * the LRU time isn't too small
-     */
-    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
-    /** reference an object
-     *
-     * This routine is called whenever an object is referenced, so we can
-     * maintain replacement information within the storage fs.
-     */
-    virtual void reference(StoreEntry &);
-    /** de-reference an object
-     *
-     * This routine is called whenever the last reference to an object is
-     * removed, to maintain replacement information within the storage fs.
-     */
-    virtual bool dereference(StoreEntry &, bool);
-    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
-    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
-    virtual void openLog();
-    virtual void closeLog();
-    virtual int writeCleanStart();
-    virtual void writeCleanDone();
-    virtual void logEntry(const StoreEntry & e, int op) const;
-    virtual void parse(int index, char *path); ///parse configuration and setup new SwapDir
-    virtual void reconfigure(); ///reconfigure the SwapDir
-    virtual int callback();
-    virtual void sync();
-    virtual void swappedOut(const StoreEntry &e);
-    virtual uint64_t currentSize() const { return cur_size; }
-    virtual uint64_t currentCount() const { return n_disk_objects; }
+    virtual ~UFSSwapDir();
+
+    /* Store::Disk API */
+    virtual void create() override;
+    virtual void init() override;
+    virtual void dump(StoreEntry &) const override;
+    virtual bool doubleCheck(StoreEntry &) override;
+    virtual bool unlinkdUseful() const override;
+    virtual void unlink(StoreEntry &) override;
+    virtual void statfs(StoreEntry &) const override;
+    virtual void maintain() override;
+    virtual void markForUnlink(StoreEntry &) override {}
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const override;
+    virtual void reference(StoreEntry &) override;
+    virtual bool dereference(StoreEntry &) override;
+    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) override;
+    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) override;
+    virtual void openLog() override;
+    virtual void closeLog() override;
+    virtual int writeCleanStart() override;
+    virtual void writeCleanDone() override;
+    virtual void logEntry(const StoreEntry & e, int op) const override;
+    virtual void parse(int index, char *path) override;
+    virtual void reconfigure() override;
+    virtual int callback() override;
+    virtual void sync() override;
+    virtual void swappedOut(const StoreEntry &e) override;
+    virtual uint64_t currentSize() const override { return cur_size; }
+    virtual uint64_t currentCount() const override { return n_disk_objects; }
+    virtual ConfigOption *getOptionTree() const override;
 
     void unlinkFile(sfileno f);
     // move down when unlink is a virtual method
@@ -121,7 +102,6 @@ public:
     void undoAddDiskRestore(StoreEntry *e);
     int validFileno(sfileno filn, int flag) const;
     int mapBitAllocate();
-    virtual ConfigOption *getOptionTree() const;
 
     void *fsdata;
 
similarity index 93%
rename from src/disk.cc
rename to src/fs_io.cc
index 67dec9c45d73d5c039a9231bb8db178a5534ccea..327e12c239475cf04af1eb360a2618a5526c2b23 100644 (file)
@@ -10,9 +10,9 @@
 
 #include "squid.h"
 #include "comm/Loops.h"
-#include "disk.h"
 #include "fd.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "MemBuf.h"
 #include "profiler/Profiler.h"
@@ -32,12 +32,6 @@ diskWriteIsComplete(int fd)
 
 #endif
 
-void
-disk_init(void)
-{
-    (void) 0;
-}
-
 /* hack needed on SunStudio to avoid linkage convention mismatch */
 static void cxx_xfree(void *ptr)
 {
@@ -522,3 +516,42 @@ xrename(const char *from, const char *to)
     return -1;
 }
 
+int
+fsBlockSize(const char *path, int *blksize)
+{
+    struct statvfs sfs;
+
+    if (xstatvfs(path, &sfs)) {
+        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
+        *blksize = 2048;
+        return 1;
+    }
+
+    *blksize = (int) sfs.f_frsize;
+
+    // Sanity check; make sure we have a meaningful value.
+    if (*blksize < 512)
+        *blksize = 2048;
+
+    return 0;
+}
+
+#define fsbtoblk(num, fsbs, bs) \
+    (((fsbs) != 0 && (fsbs) < (bs)) ? \
+            (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+int
+fsStats(const char *path, int *totl_kb, int *free_kb, int *totl_in, int *free_in)
+{
+    struct statvfs sfs;
+
+    if (xstatvfs(path, &sfs)) {
+        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
+        return 1;
+    }
+
+    *totl_kb = (int) fsbtoblk(sfs.f_blocks, sfs.f_frsize, 1024);
+    *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_frsize, 1024);
+    *totl_in = (int) sfs.f_files;
+    *free_in = (int) sfs.f_ffree;
+    return 0;
+}
similarity index 76%
rename from src/disk.h
rename to src/fs_io.h
index 1ea7f1debb156952c166a5190259a99ddea5b2b5..3de2d6510e8467976807dcd31687059ee035683c 100644 (file)
@@ -8,8 +8,8 @@
 
 /* DEBUG: section 06    Disk I/O Routines */
 
-#ifndef SQUID_DISK_H_
-#define SQUID_DISK_H_
+#ifndef SQUID_FS_IO_H_
+#define SQUID_FS_IO_H_
 
 #include "mem/forward.h"
 #include "typedefs.h" //DRCB, DWCB
@@ -43,22 +43,14 @@ public:
 
 int file_open(const char *path, int mode);
 void file_close(int fd);
-
-/* Adapter file_write for object callbacks */
-template <class O>
-void
-FreeObject(void *address)
-{
-    O *anObject = static_cast <O *>(address);
-    delete anObject;
-}
-
 void file_write(int, off_t, void const *, int len, DWCB *, void *, FREE *);
 void file_write_mbuf(int fd, off_t, MemBuf mb, DWCB * handler, void *handler_data);
 void file_read(int, char *, int, off_t, DRCB *, void *);
-void disk_init(void);
 void safeunlink(const char *path, int quiet);
-int xrename(const char *from, const char *to); //disk.cc
+int xrename(const char *from, const char *to);
+
+int fsBlockSize(const char *path, int *blksize);
+int fsStats(const char *, int *, int *, int *, int *);
 
-#endif /* SQUID_DISK_H_ */
+#endif /* SQUID_FS_IO_H_ */
 
index a188fe97ec436cf96fc77105107048ed7b779723..f042a8d176abeb5c0b82582e7282ef4425fb3fd6 100644 (file)
@@ -19,9 +19,9 @@
 #include "squid.h"
 #include "CachePeer.h"
 #include "cbdata.h"
-#include "disk.h"
 #include "event.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "FwdState.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "mgr/Registration.h"
 #include "mime_header.h"
 #include "neighbors.h"
+#include "SquidConfig.h"
 #include "SquidTime.h"
 #include "Store.h"
 #include "StoreClient.h"
-#include "SwapDir.h"
 #include "tools.h"
 #include "URL.h"
 #include "wordlist.h"
index 65cc8b8676f1faef81aaddde9d93568b25f98cb3..5026da412fe4a73ba5a4bbb8133bae3c430eb3e6 100644 (file)
@@ -39,7 +39,6 @@
 #include "StatCounters.h"
 #include "Store.h"
 #include "store_key_md5.h"
-#include "SwapDir.h"
 #include "tools.h"
 #include "wordlist.h"
 
index f1f7c40fae7f3491ba562e0e55cb15e7f372e4ae..b1a0d4bcf5a2402f1c5be3fd82d2d587650df0d0 100644 (file)
 #define SQUID_IPC_STORE_MAP_H
 
 #include "Debug.h"
-#include "fs/forward.h"
 #include "ipc/mem/FlexibleArray.h"
 #include "ipc/mem/Pointer.h"
 #include "ipc/ReadWriteLock.h"
 #include "SBuf.h"
+#include "store/forward.h"
 #include "store_key_md5.h"
 #include "tools.h"
 
index 9e9bf791b72afc69326eb176940f98e72cdfd945..1b074a9a92823ff3c071ec817edd48be423eb420 100644 (file)
@@ -9,11 +9,11 @@
 #ifndef SQUID_IPC_STORE_MAP_H
 #define SQUID_IPC_STORE_MAP_H
 
-#include "fs/forward.h"
 #include "ipc/mem/FlexibleArray.h"
 #include "ipc/mem/Pointer.h"
 #include "ipc/ReadWriteLock.h"
 #include "SBuf.h"
+#include "store/forward.h"
 #include "store_key_md5.h"
 
 namespace Ipc
index 793499c6941a3d5686eb7b6b3b80d20dd20c6ebe..91e93bb209fe71eb25e435a85dd54e52e9a3aa9a 100644 (file)
@@ -14,6 +14,7 @@
 #include "CacheManager.h"
 #include "CollapsedForwarding.h"
 #include "comm/Connection.h"
+#include "fatal.h"
 #include "globals.h"
 #include "ipc/Kids.h"
 #include "ipc/Messages.h"
@@ -24,7 +25,6 @@
 #include "mgr/Forwarder.h"
 #include "mgr/Request.h"
 #include "mgr/Response.h"
-#include "SwapDir.h" /* XXX: scope boundary violation */
 #if HAVE_DISKIO_MODULE_IPCIO
 #include "DiskIO/IpcIo/IpcIoFile.h" /* XXX: scope boundary violation */
 #endif
index 032065cad6f6b126f5f28994488937ed6d696b6c..35e6cc4831514eb5f3b336ddf26448668eb1c3ad 100644 (file)
@@ -13,7 +13,6 @@
 #include "base/TextException.h"
 #include "ipc/mem/PagePool.h"
 #include "ipc/mem/Pages.h"
-#include "SwapDir.h"
 #include "tools.h"
 
 // Uses a single PagePool instance, for now.
index bcf9b552f49f08493bea6496773625c8d805f410..f14f01a5794dbc35d5ce7c2b97bcad7d1bc5d25e 100644 (file)
@@ -9,10 +9,10 @@
 /* DEBUG: section 50    Log file handling */
 
 #include "squid.h"
-#include "disk.h"
 #include "fatal.h"
 #include "fd.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "log/File.h"
 #include "log/ModStdio.h"
index eaaccbc947b641a87fb0e462f2d46500b6a15e07..fa4048cd5d6bdf6f95518d01b83dd96e006b6643 100644 (file)
@@ -11,9 +11,9 @@
 #include "squid.h"
 #include "comm.h"
 #include "comm/Connection.h"
-#include "disk.h"
 #include "fatal.h"
 #include "fd.h"
+#include "fs_io.h"
 #include "log/File.h"
 #include "log/ModUdp.h"
 #include "Parsing.h"
index 5470024097a8ad6445de2ed3c1942845cfbc9b22..e7179d61352044c9928f010c85d79b54e2a9524f 100644 (file)
@@ -23,7 +23,6 @@
 #include "comm.h"
 #include "ConfigParser.h"
 #include "CpuAffinity.h"
-#include "disk.h"
 #include "DiskIO/DiskIOModule.h"
 #include "dns/forward.h"
 #include "errorpage.h"
@@ -34,6 +33,7 @@
 #include "format/Token.h"
 #include "fqdncache.h"
 #include "fs/Module.h"
+#include "fs_io.h"
 #include "FwdState.h"
 #include "globals.h"
 #include "htcp.h"
@@ -65,9 +65,9 @@
 #include "stat.h"
 #include "StatCounters.h"
 #include "Store.h"
+#include "store/Disks.h"
 #include "store_log.h"
 #include "StoreFileSystem.h"
-#include "SwapDir.h"
 #include "tools.h"
 #include "unlinkd.h"
 #include "URL.h"
@@ -1141,9 +1141,6 @@ mainInitialize(void)
 
 #endif
 
-    if (!configured_once)
-        disk_init();        /* disk_init must go before ipcache_init() */
-
     ipcache_init();
 
     fqdncache_init();
@@ -1501,7 +1498,7 @@ SquidMain(int argc, char **argv)
         StoreFileSystem::SetupAllFs();
 
         /* we may want the parsing process to set this up in the future */
-        Store::Root(new StoreController);
+        Store::Init();
         Auth::Init();      /* required for config parsing. NOP if !USE_AUTH */
         Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
 
@@ -2052,8 +2049,7 @@ SquidShutdown()
     mimeFreeMemory();
     errorClean();
 #endif
-    // clear StoreController
-    Store::Root(NULL);
+    Store::FreeMemory();
 
     fdDumpOpen();
 
index 56dcbc679fd8abe10e6b70b410db2494e49eba07..6e2b93d38abf42703bd4e209ab434c9cafd3faac 100644 (file)
@@ -13,9 +13,9 @@
 #include "acl/AclNameList.h"
 #include "base/PackableStream.h"
 #include "ClientInfo.h"
-#include "disk.h"
 #include "dlink.h"
 #include "event.h"
+#include "fs_io.h"
 #include "icmp/net_db.h"
 #include "md5.h"
 #include "mem/forward.h"
index 0179f14cef1954ead5b7faad39788fab596a24b7..983e2206b24089e1fd32f300ed1985e8837a0465 100644 (file)
@@ -9,8 +9,8 @@
 /* DEBUG: section 25    MIME Parsing and Internal Icons */
 
 #include "squid.h"
-#include "disk.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "HttpHdrCc.h"
 #include "HttpReply.h"
index 0b2b7d51e76c4f1b3f2d2c519ea7f018c24c7e47..272c6883ee1d2faa0969dd181adb0a2bc0fae91e 100644 (file)
 #include "squid.h"
 #include "anyp/PortCfg.h"
 #include "comm/Connection.h"
-#include "disk.h"
 #include "event.h"
 #include "fd.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "ICP.h"
 #include "ipcache.h"
index a88a855b17ad8a97208ae7b527234721d7e2287e..e141018a7ec1243d1fb5f8440efd1829c0acf474 100644 (file)
@@ -9,6 +9,7 @@
 #include "squid.h"
 #include "../helper.h"
 #include "anyp/PortCfg.h"
+#include "fs_io.h"
 #include "helper/Reply.h"
 #include "SquidConfig.h"
 #include "SquidString.h"
@@ -16,7 +17,6 @@
 #include "ssl/cert_validate_message.h"
 #include "ssl/Config.h"
 #include "ssl/helper.h"
-#include "SwapDir.h"
 #include "wordlist.h"
 
 LruMap<Ssl::CertValidationResponse> *Ssl::CertValidationHelper::HelperCache = NULL;
@@ -72,7 +72,7 @@ void Ssl::Helper::Init()
             } else if (db_path_was_found) {
                 db_path_was_found = false;
                 int fs_block_size = 0;
-                storeDirGetBlkSize(token, &fs_block_size);
+                fsBlockSize(token, &fs_block_size);
                 snprintf(buffer, sizeof(buffer), "%i", fs_block_size);
             }
         }
index 76fee86074757ca5bb3aebdc82a913add98d2ff1..e44f46a15eefd60fd19f648ab23207633d34200d 100644 (file)
@@ -9,14 +9,10 @@
 #include "squid.h"
 #include "fatal.h"
 
-/* Stub File for the ssl/libsslutil.la convenience library */
+/* Unused (XXX) Stub File for the ssl/libsslutil.la convenience library */
 
-#define STUB_BASE "ssl/libsslutil.la"
-
-#define STUB { fatal(STUB_BASE " required."); }
-#define STUB_RETVAL(x) { fatal(STUB_BASE " required."); return (x); }
-#define STUB_RETREF(x) { fatal(STUB_BASE " required."); static x v; return v; }
-#define STUB_RETREF2(x,y) { fatal(STUB_BASE " required."); static x v((y)); return v; }
+#define STUB_API "ssl/libsslutil.la"
+#include "tests/STUB.h"
 
 #include "ssl/crtd_message.h"
 Ssl::CrtdMessage::CrtdMessage() STUB
@@ -25,7 +21,7 @@ std::string const & Ssl::CrtdMessage::getBody() const STUB_RETREF(std::string)
 std::string const & Ssl::CrtdMessage::getCode() const STUB_RETREF(std::string)
 void Ssl::CrtdMessage::setBody(std::string const & aBody) STUB
 void Ssl::CrtdMessage::setCode(std::string const & aCode) STUB
-std::string Ssl::CrtdMessage::compose() const STUB_RETREF(std::string)
+std::string Ssl::CrtdMessage::compose() const STUB_RETVAL(std::string())
 void Ssl::CrtdMessage::clear() STUB
 void Ssl::CrtdMessage::parseBody(BodyParams & map, std::string & other_part) const STUB
 void Ssl::CrtdMessage::composeBody(BodyParams const & map, std::string const & other_part) STUB
index 50fe433c6ffa134bd697ef156e627ff0fe28c96b..707bb763048d59cbf5da6b4afa8b33c02cf936c5 100644 (file)
@@ -409,7 +409,7 @@ statObjectsStart(StoreEntry * sentry, STOBJFLT * filter)
     state->filter = filter;
 
     sentry->lock("statObjects");
-    state->theSearch = Store::Root().search(NULL, NULL);
+    state->theSearch = Store::Root().search();
 
     eventAdd("statObjects", statObjects, state, 0.0, 1);
 }
index 837cd57ff28190815a78cec258175a102f0cf867..3b22edaab9f318731a60fdaf349fc88872817e79 100644 (file)
@@ -32,6 +32,9 @@
 #include "StatCounters.h"
 #include "stmem.h"
 #include "Store.h"
+#include "store/Controller.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
 #include "store_digest.h"
 #include "store_key_md5.h"
 #include "store_key_md5.h"
@@ -42,7 +45,6 @@
 #include "StoreMeta.h"
 #include "StrList.h"
 #include "swap_log_op.h"
-#include "SwapDir.h"
 #include "tools.h"
 #if USE_DELAY_POOLS
 #include "DelayPools.h"
@@ -110,20 +112,6 @@ static EVH storeLateRelease;
 static std::stack<StoreEntry*> LateReleaseStack;
 MemAllocator *StoreEntry::pool = NULL;
 
-StorePointer Store::CurrentRoot = NULL;
-
-void
-Store::Root(Store * aRoot)
-{
-    CurrentRoot = aRoot;
-}
-
-void
-Store::Root(StorePointer aRoot)
-{
-    Root(aRoot.getRaw());
-}
-
 void
 Store::Stats(StoreEntry * output)
 {
@@ -131,24 +119,6 @@ Store::Stats(StoreEntry * output)
     Root().stat(*output);
 }
 
-void
-Store::create()
-{}
-
-void
-Store::diskFull()
-{}
-
-void
-Store::sync()
-{}
-
-void
-Store::unlink(StoreEntry &)
-{
-    fatal("Store::unlink on invalid Store\n");
-}
-
 void
 StoreEntry::makePublic()
 {
@@ -413,10 +383,8 @@ destroyStoreEntry(void *data)
         return;
 
     // Store::Root() is FATALly missing during shutdown
-    if (e->swap_filen >= 0 && !shutting_down) {
-        SwapDir &sd = dynamic_cast<SwapDir&>(*e->store());
-        sd.disconnect(*e);
-    }
+    if (e->swap_filen >= 0 && !shutting_down)
+        e->disk().disconnect(*e);
 
     e->destroyMemObject();
 
@@ -475,7 +443,6 @@ void
 StoreEntry::touch()
 {
     lastref = squid_curtime;
-    Store::Root().reference(*this);
 }
 
 void
@@ -1233,34 +1200,6 @@ Store::Maintain(void *)
 #define MAINTAIN_MAX_SCAN       1024
 #define MAINTAIN_MAX_REMOVE     64
 
-/*
- * This routine is to be called by main loop in main.c.
- * It removes expired objects on only one bucket for each time called.
- *
- * This should get called 1/s from main().
- */
-void
-StoreController::maintain()
-{
-    static time_t last_warn_time = 0;
-
-    PROF_start(storeMaintainSwapSpace);
-    swapDir->maintain();
-
-    /* this should be emitted by the oversize dir, not globally */
-
-    if (Store::Root().currentSize() > Store::Root().maxSize()) {
-        if (squid_curtime - last_warn_time > 10) {
-            debugs(20, DBG_CRITICAL, "WARNING: Disk space over limit: "
-                   << Store::Root().currentSize() / 1024.0 << " KB > "
-                   << (Store::Root().maxSize() >> 10) << " KB");
-            last_warn_time = squid_curtime;
-        }
-    }
-
-    PROF_stop(storeMaintainSwapSpace);
-}
-
 /* release an object from a cache */
 void
 StoreEntry::release()
@@ -1278,35 +1217,27 @@ StoreEntry::release()
         return;
     }
 
-    Store::Root().memoryUnlink(*this);
+    if (Store::Controller::store_dirs_rebuilding && swap_filen > -1) {
+        /* TODO: Teach disk stores to handle releases during rebuild instead. */
 
-    if (StoreController::store_dirs_rebuilding && swap_filen > -1) {
-        setPrivateKey();
+        Store::Root().memoryUnlink(*this);
 
-        if (swap_filen > -1) {
-            // lock the entry until rebuilding is done
-            lock("storeLateRelease");
-            setReleaseFlag();
-            LateReleaseStack.push(this);
-        } else {
-            destroyStoreEntry(static_cast<hash_link *>(this));
-            // "this" is no longer valid
-        }
+        setPrivateKey();
 
-        PROF_stop(storeRelease);
+        // lock the entry until rebuilding is done
+        lock("storeLateRelease");
+        setReleaseFlag();
+        LateReleaseStack.push(this);
         return;
     }
 
     storeLog(STORE_LOG_RELEASE, this);
-
-    if (swap_filen > -1) {
+    if (swap_filen > -1 && !EBIT_TEST(flags, KEY_PRIVATE)) {
         // log before unlink() below clears swap_filen
-        if (!EBIT_TEST(flags, KEY_PRIVATE))
-            storeDirSwapLog(this, SWAP_LOG_DEL);
-
-        unlink();
+        storeDirSwapLog(this, SWAP_LOG_DEL);
     }
 
+    Store::Root().unlink(*this);
     destroyStoreEntry(static_cast<hash_link *>(this));
     PROF_stop(storeRelease);
 }
@@ -1317,7 +1248,7 @@ storeLateRelease(void *)
     StoreEntry *e;
     static int n = 0;
 
-    if (StoreController::store_dirs_rebuilding) {
+    if (Store::Controller::store_dirs_rebuilding) {
         eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
         return;
     }
@@ -1519,7 +1450,7 @@ StoreEntry::negativeCache()
 void
 storeFreeMemory(void)
 {
-    Store::Root(NULL);
+    Store::FreeMemory();
 #if USE_CACHE_DIGESTS
     delete store_digest;
 #endif
@@ -2091,20 +2022,13 @@ StoreEntry::hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) con
     return matched;
 }
 
-SwapDir::Pointer
-StoreEntry::store() const
+Store::Disk &
+StoreEntry::disk() const
 {
     assert(0 <= swap_dirn && swap_dirn < Config.cacheSwap.n_configured);
-    return INDEXSD(swap_dirn);
-}
-
-void
-StoreEntry::unlink()
-{
-    store()->unlink(*this); // implies disconnect()
-    swap_filen = -1;
-    swap_dirn = -1;
-    swap_status = SWAPOUT_NONE;
+    const RefCount<Store::Disk> &sd = INDEXSD(swap_dirn);
+    assert(sd);
+    return *sd;
 }
 
 /*
@@ -2198,4 +2122,3 @@ NullStoreEntry::getSerialisedMetaData()
 {
     return NULL;
 }
-
diff --git a/src/store/Controlled.h b/src/store/Controlled.h
new file mode 100644 (file)
index 0000000..e48d94c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_CONTROLLED_H
+#define SQUID_STORE_CONTROLLED_H
+
+#include "store/Storage.h"
+
+namespace Store {
+
+/// Storage controlled by a Controller.
+/// This API is shared among Disks, Disk, Memory caches and Transients.
+class Controlled: public Storage
+{
+public:
+    /// somebody needs this entry (many cache replacement policies need to know)
+    virtual void reference(StoreEntry &e) = 0;
+
+    /// somebody no longer needs this entry (usually after calling reference())
+    /// return false iff the idle entry should be destroyed
+    virtual bool dereference(StoreEntry &e) = 0;
+
+    /// If this storage cannot cache collapsed entries, return false.
+    /// If the entry is not found, return false. Otherwise, return true after
+    /// tying the entry to this cache and setting inSync to updateCollapsed().
+    virtual bool anchorCollapsed(StoreEntry &, bool &/*inSync*/) { return false; }
+
+    /// Update a local collapsed entry with fresh info from this cache (if any).
+    /// Return true iff the cache supports collapsed entries and
+    /// the given local collapsed entry is now in sync with this storage.
+    virtual bool updateCollapsed(StoreEntry &) { return false; }
+};
+
+} // namespace Store
+
+#endif /* SQUID_STORE_CONTROLLED_H */
diff --git a/src/store/Controller.cc b/src/store/Controller.cc
new file mode 100644 (file)
index 0000000..930f621
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 20    Store Controller */
+
+#include "squid.h"
+#include "mem_node.h"
+#include "MemStore.h"
+#include "profiler/Profiler.h"
+#include "SquidConfig.h"
+#include "SquidMath.h"
+#include "store/Controller.h"
+#include "store/Disks.h"
+#include "store/LocalSearch.h"
+#include "tools.h"
+#include "Transients.h"
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+/*
+ * store_dirs_rebuilding is initialized to _1_ as a hack so that
+ * storeDirWriteCleanLogs() doesn't try to do anything unless _all_
+ * cache_dirs have been read.  For example, without this hack, Squid
+ * will try to write clean log files if -kparse fails (becasue it
+ * calls fatal()).
+ */
+int Store::Controller::store_dirs_rebuilding = 1;
+
+Store::Controller::Controller() :
+    swapDir(new Disks),
+    memStore(NULL),
+    transients(NULL)
+{
+    assert(!store_table);
+}
+
+Store::Controller::~Controller()
+{
+    delete memStore;
+    delete transients;
+    delete swapDir;
+
+    if (store_table) {
+        hashFreeItems(store_table, destroyStoreEntry);
+        hashFreeMemory(store_table);
+        store_table = nullptr;
+    }
+}
+
+void
+Store::Controller::init()
+{
+    if (Config.memShared && IamWorkerProcess()) {
+        memStore = new MemStore;
+        memStore->init();
+    }
+
+    swapDir->init();
+
+    if (UsingSmp() && IamWorkerProcess() && Config.onoff.collapsed_forwarding) {
+        transients = new Transients;
+        transients->init();
+    }
+}
+
+void
+Store::Controller::create()
+{
+    swapDir->create();
+
+#if !_SQUID_WINDOWS_
+
+    pid_t pid;
+
+    do {
+        int status;
+#if _SQUID_NEXT_
+
+        pid = wait3(&status, WNOHANG, NULL);
+#else
+
+        pid = waitpid(-1, &status, 0);
+#endif
+
+    } while (pid > 0 || (pid < 0 && errno == EINTR));
+
+#endif
+}
+
+void
+Store::Controller::maintain()
+{
+    static time_t last_warn_time = 0;
+
+    PROF_start(storeMaintainSwapSpace);
+    swapDir->maintain();
+
+    /* this should be emitted by the oversize dir, not globally */
+
+    if (Root().currentSize() > Store::Root().maxSize()) {
+        if (squid_curtime - last_warn_time > 10) {
+            debugs(20, DBG_CRITICAL, "WARNING: Disk space over limit: "
+                   << Store::Root().currentSize() / 1024.0 << " KB > "
+                   << (Store::Root().maxSize() >> 10) << " KB");
+            last_warn_time = squid_curtime;
+        }
+    }
+
+    PROF_stop(storeMaintainSwapSpace);
+}
+
+void
+Store::Controller::getStats(StoreInfoStats &stats) const
+{
+    if (memStore)
+        memStore->getStats(stats);
+    else {
+        // move this code to a non-shared memory cache class when we have it
+        stats.mem.shared = false;
+        stats.mem.capacity = Config.memMaxSize;
+        stats.mem.size = mem_node::StoreMemSize();
+        stats.mem.count = hot_obj_count;
+    }
+
+    swapDir->getStats(stats);
+
+    // low-level info not specific to memory or disk cache
+    stats.store_entry_count = StoreEntry::inUseCount();
+    stats.mem_object_count = MemObject::inUseCount();
+}
+
+void
+Store::Controller::stat(StoreEntry &output) const
+{
+    storeAppendPrintf(&output, "Store Directory Statistics:\n");
+    storeAppendPrintf(&output, "Store Entries          : %lu\n",
+                      (unsigned long int)StoreEntry::inUseCount());
+    storeAppendPrintf(&output, "Maximum Swap Size      : %" PRIu64 " KB\n",
+                      maxSize() >> 10);
+    storeAppendPrintf(&output, "Current Store Swap Size: %.2f KB\n",
+                      currentSize() / 1024.0);
+    storeAppendPrintf(&output, "Current Capacity       : %.2f%% used, %.2f%% free\n",
+                      Math::doublePercent(currentSize(), maxSize()),
+                      Math::doublePercent((maxSize() - currentSize()), maxSize()));
+
+    if (memStore)
+        memStore->stat(output);
+
+    /* now the swapDir */
+    swapDir->stat(output);
+}
+
+/* if needed, this could be taught to cache the result */
+uint64_t
+Store::Controller::maxSize() const
+{
+    /* TODO: include memory cache ? */
+    return swapDir->maxSize();
+}
+
+uint64_t
+Store::Controller::minSize() const
+{
+    /* TODO: include memory cache ? */
+    return swapDir->minSize();
+}
+
+uint64_t
+Store::Controller::currentSize() const
+{
+    /* TODO: include memory cache ? */
+    return swapDir->currentSize();
+}
+
+uint64_t
+Store::Controller::currentCount() const
+{
+    /* TODO: include memory cache ? */
+    return swapDir->currentCount();
+}
+
+int64_t
+Store::Controller::maxObjectSize() const
+{
+    /* TODO: include memory cache ? */
+    return swapDir->maxObjectSize();
+}
+
+StoreSearch *
+Store::Controller::search()
+{
+    // this is the only kind of search we currently support
+    return NewLocalSearch();
+}
+
+void
+Store::Controller::sync(void)
+{
+    if (memStore)
+        memStore->sync();
+    swapDir->sync();
+}
+
+/*
+ * handle callbacks all avaliable fs'es
+ */
+int
+Store::Controller::callback()
+{
+    /* This will likely double count. Thats ok. */
+    PROF_start(storeDirCallback);
+
+    /* mem cache callbacks ? */
+    int result = swapDir->callback();
+
+    PROF_stop(storeDirCallback);
+
+    return result;
+}
+
+void
+Store::Controller::referenceBusy(StoreEntry &e)
+{
+    // special entries do not belong to any specific Store, but are IN_MEMORY
+    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
+        return;
+
+    /* Notify the fs that we're referencing this object again */
+
+    if (e.swap_dirn > -1)
+        swapDir->reference(e);
+
+    // Notify the memory cache that we're referencing this object again
+    if (memStore && e.mem_status == IN_MEMORY)
+        memStore->reference(e);
+
+    // TODO: move this code to a non-shared memory cache class when we have it
+    if (e.mem_obj) {
+        if (mem_policy->Referenced)
+            mem_policy->Referenced(mem_policy, &e, &e.mem_obj->repl);
+    }
+}
+
+bool
+Store::Controller::dereferenceIdle(StoreEntry &e, bool wantsLocalMemory)
+{
+    // special entries do not belong to any specific Store, but are IN_MEMORY
+    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
+        return true;
+
+    bool keepInStoreTable = false; // keep only if somebody needs it there
+
+    /* Notify the fs that we're not referencing this object any more */
+
+    if (e.swap_filen > -1)
+        keepInStoreTable = swapDir->dereference(e) || keepInStoreTable;
+
+    // Notify the memory cache that we're not referencing this object any more
+    if (memStore && e.mem_status == IN_MEMORY)
+        keepInStoreTable = memStore->dereference(e) || keepInStoreTable;
+
+    // TODO: move this code to a non-shared memory cache class when we have it
+    if (e.mem_obj) {
+        if (mem_policy->Dereferenced)
+            mem_policy->Dereferenced(mem_policy, &e, &e.mem_obj->repl);
+        // non-shared memory cache relies on store_table
+        if (!memStore)
+            keepInStoreTable = wantsLocalMemory || keepInStoreTable;
+    }
+
+    return keepInStoreTable;
+}
+
+StoreEntry *
+Store::Controller::get(const cache_key *key)
+{
+    if (StoreEntry *e = find(key)) {
+        // this is not very precise: some get()s are not initiated by clients
+        e->touch();
+        referenceBusy(*e);
+        return e;
+    }
+    return NULL;
+}
+
+/// Internal method to implements the guts of the Store::get() API:
+/// returns an in-transit or cached object with a given key, if any.
+StoreEntry *
+Store::Controller::find(const cache_key *key)
+{
+    debugs(20, 3, storeKeyText(key));
+
+    if (StoreEntry *e = static_cast<StoreEntry*>(hash_lookup(store_table, key))) {
+        // TODO: ignore and maybe handleIdleEntry() unlocked intransit entries
+        // because their backing store slot may be gone already.
+        debugs(20, 3, HERE << "got in-transit entry: " << *e);
+        return e;
+    }
+
+    // Must search transients before caches because we must sync those we find.
+    if (transients) {
+        if (StoreEntry *e = transients->get(key)) {
+            debugs(20, 3, "got shared in-transit entry: " << *e);
+            bool inSync = false;
+            const bool found = anchorCollapsed(*e, inSync);
+            if (!found || inSync)
+                return e;
+            assert(!e->locked()); // ensure release will destroyStoreEntry()
+            e->release(); // do not let others into the same trap
+            return NULL;
+        }
+    }
+
+    if (memStore) {
+        if (StoreEntry *e = memStore->get(key)) {
+            debugs(20, 3, HERE << "got mem-cached entry: " << *e);
+            return e;
+        }
+    }
+
+    if (swapDir) {
+        if (StoreEntry *e = swapDir->get(key)) {
+            debugs(20, 3, "got disk-cached entry: " << *e);
+            return e;
+        }
+    }
+
+    debugs(20, 4, "cannot locate " << storeKeyText(key));
+    return nullptr;
+}
+
+void
+Store::Controller::markForUnlink(StoreEntry &e)
+{
+    if (transients && e.mem_obj && e.mem_obj->xitTable.index >= 0)
+        transients->markForUnlink(e);
+    if (memStore && e.mem_obj && e.mem_obj->memCache.index >= 0)
+        memStore->markForUnlink(e);
+    if (swapDir && e.swap_filen >= 0)
+        swapDir->markForUnlink(e);
+}
+
+void
+Store::Controller::unlink(StoreEntry &e)
+{
+    memoryUnlink(e);
+    if (swapDir && e.swap_filen >= 0)
+        swapDir->unlink(e);
+}
+
+// move this into [non-shared] memory cache class when we have one
+/// whether e should be kept in local RAM for possible future caching
+bool
+Store::Controller::keepForLocalMemoryCache(StoreEntry &e) const
+{
+    if (!e.memoryCachable())
+        return false;
+
+    // does the current and expected size obey memory caching limits?
+    assert(e.mem_obj);
+    const int64_t loadedSize = e.mem_obj->endOffset();
+    const int64_t expectedSize = e.mem_obj->expectedReplySize(); // may be < 0
+    const int64_t ramSize = max(loadedSize, expectedSize);
+    const int64_t ramLimit = min(
+                                 static_cast<int64_t>(Config.memMaxSize),
+                                 static_cast<int64_t>(Config.Store.maxInMemObjSize));
+    return ramSize <= ramLimit;
+}
+
+void
+Store::Controller::memoryOut(StoreEntry &e, const bool preserveSwappable)
+{
+    bool keepInLocalMemory = false;
+    if (memStore)
+        memStore->write(e); // leave keepInLocalMemory false
+    else
+        keepInLocalMemory = keepForLocalMemoryCache(e);
+
+    debugs(20, 7, HERE << "keepInLocalMemory: " << keepInLocalMemory);
+
+    if (!keepInLocalMemory)
+        e.trimMemory(preserveSwappable);
+}
+
+void
+Store::Controller::memoryUnlink(StoreEntry &e)
+{
+    if (memStore)
+        memStore->unlink(e);
+    else // TODO: move into [non-shared] memory cache class when we have one
+        e.destroyMemObject();
+}
+
+void
+Store::Controller::memoryDisconnect(StoreEntry &e)
+{
+    if (memStore)
+        memStore->disconnect(e);
+    // else nothing to do for non-shared memory cache
+}
+
+void
+Store::Controller::transientsAbandon(StoreEntry &e)
+{
+    if (transients) {
+        assert(e.mem_obj);
+        if (e.mem_obj->xitTable.index >= 0)
+            transients->abandon(e);
+    }
+}
+
+void
+Store::Controller::transientsCompleteWriting(StoreEntry &e)
+{
+    if (transients) {
+        assert(e.mem_obj);
+        if (e.mem_obj->xitTable.index >= 0)
+            transients->completeWriting(e);
+    }
+}
+
+int
+Store::Controller::transientReaders(const StoreEntry &e) const
+{
+    return (transients && e.mem_obj && e.mem_obj->xitTable.index >= 0) ?
+           transients->readers(e) : 0;
+}
+
+void
+Store::Controller::transientsDisconnect(MemObject &mem_obj)
+{
+    if (transients)
+        transients->disconnect(mem_obj);
+}
+
+void
+Store::Controller::handleIdleEntry(StoreEntry &e)
+{
+    bool keepInLocalMemory = false;
+
+    if (EBIT_TEST(e.flags, ENTRY_SPECIAL)) {
+        // Icons (and cache digests?) should stay in store_table until we
+        // have a dedicated storage for them (that would not purge them).
+        // They are not managed [well] by any specific Store handled below.
+        keepInLocalMemory = true;
+    } else if (memStore) {
+        // leave keepInLocalMemory false; memStore maintains its own cache
+    } else {
+        keepInLocalMemory = keepForLocalMemoryCache(e) && // in good shape and
+                            // the local memory cache is not overflowing
+                            (mem_node::InUseCount() <= store_pages_max);
+    }
+
+    // An idle, unlocked entry that only belongs to a SwapDir which controls
+    // its own index, should not stay in the global store_table.
+    if (!dereferenceIdle(e, keepInLocalMemory)) {
+        debugs(20, 5, HERE << "destroying unlocked entry: " << &e << ' ' << e);
+        destroyStoreEntry(static_cast<hash_link*>(&e));
+        return;
+    }
+
+    debugs(20, 5, HERE << "keepInLocalMemory: " << keepInLocalMemory);
+
+    // TODO: move this into [non-shared] memory cache class when we have one
+    if (keepInLocalMemory) {
+        e.setMemStatus(IN_MEMORY);
+        e.mem_obj->unlinkRequest();
+    } else {
+        e.purgeMem(); // may free e
+    }
+}
+
+void
+Store::Controller::allowCollapsing(StoreEntry *e, const RequestFlags &reqFlags,
+                                 const HttpRequestMethod &reqMethod)
+{
+    e->makePublic(); // this is needed for both local and SMP collapsing
+    if (transients)
+        transients->startWriting(e, reqFlags, reqMethod);
+    debugs(20, 3, "may " << (transients && e->mem_obj->xitTable.index >= 0 ?
+                             "SMP-" : "locally-") << "collapse " << *e);
+}
+
+void
+Store::Controller::syncCollapsed(const sfileno xitIndex)
+{
+    assert(transients);
+
+    StoreEntry *collapsed = transients->findCollapsed(xitIndex);
+    if (!collapsed) { // the entry is no longer locally active, ignore update
+        debugs(20, 7, "not SMP-syncing not-transient " << xitIndex);
+        return;
+    }
+    assert(collapsed->mem_obj);
+    assert(collapsed->mem_obj->smpCollapsed);
+
+    debugs(20, 7, "syncing " << *collapsed);
+
+    bool abandoned = transients->abandoned(*collapsed);
+    bool found = false;
+    bool inSync = false;
+    if (memStore && collapsed->mem_obj->memCache.io == MemObject::ioDone) {
+        found = true;
+        inSync = true;
+        debugs(20, 7, "fully mem-loaded " << *collapsed);
+    } else if (memStore && collapsed->mem_obj->memCache.index >= 0) {
+        found = true;
+        inSync = memStore->updateCollapsed(*collapsed);
+    } else if (swapDir && collapsed->swap_filen >= 0) {
+        found = true;
+        inSync = swapDir->updateCollapsed(*collapsed);
+    } else {
+        found = anchorCollapsed(*collapsed, inSync);
+    }
+
+    if (abandoned && collapsed->store_status == STORE_PENDING) {
+        debugs(20, 3, "aborting abandoned but STORE_PENDING " << *collapsed);
+        collapsed->abort();
+        return;
+    }
+
+    if (inSync) {
+        debugs(20, 5, "synced " << *collapsed);
+        collapsed->invokeHandlers();
+    } else if (found) { // unrecoverable problem syncing this entry
+        debugs(20, 3, "aborting unsyncable " << *collapsed);
+        collapsed->abort();
+    } else { // the entry is still not in one of the caches
+        debugs(20, 7, "waiting " << *collapsed);
+    }
+}
+
+/// Called for in-transit entries that are not yet anchored to a cache.
+/// For cached entries, return true after synchronizing them with their cache
+/// (making inSync true on success). For not-yet-cached entries, return false.
+bool
+Store::Controller::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
+{
+    // this method is designed to work with collapsed transients only
+    assert(collapsed.mem_obj);
+    assert(collapsed.mem_obj->xitTable.index >= 0);
+    assert(collapsed.mem_obj->smpCollapsed);
+
+    debugs(20, 7, "anchoring " << collapsed);
+
+    bool found = false;
+    if (memStore)
+        found = memStore->anchorCollapsed(collapsed, inSync);
+    if (!found && swapDir)
+        found = swapDir->anchorCollapsed(collapsed, inSync);
+
+    if (found) {
+        if (inSync)
+            debugs(20, 7, "anchored " << collapsed);
+        else
+            debugs(20, 5, "failed to anchor " << collapsed);
+    } else {
+        debugs(20, 7, "skipping not yet cached " << collapsed);
+    }
+
+    return found;
+}
+
+namespace Store {
+    static RefCount<Controller> TheRoot;
+}
+
+Store::Controller&
+Store::Root()
+{
+    assert(TheRoot);
+    return *TheRoot;
+}
+
+void
+Store::Init(Controller *root)
+{
+    TheRoot = root ? root : new Controller;
+}
+
+void
+Store::FreeMemory()
+{
+    TheRoot = nullptr;
+}
diff --git a/src/store/Controller.h b/src/store/Controller.h
new file mode 100644 (file)
index 0000000..ff43095
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_CONTROLLER_H
+#define SQUID_STORE_CONTROLLER_H
+
+#include "store/Storage.h"
+
+class MemObject;
+class RequestFlags;
+class HttpRequestMethod;
+
+namespace Store {
+
+/// Public Store interface. Coordinates the work of memory/disk/transient stores
+/// and hides their individual existence/differences from the callers.
+class Controller: public Storage
+{
+public:
+    Controller();
+    virtual ~Controller() override;
+
+    /* Storage API */
+    virtual void create() override;
+    virtual void init() override;
+    virtual StoreEntry *get(const cache_key *) override;
+    virtual uint64_t maxSize() const override;
+    virtual uint64_t minSize() const override;
+    virtual uint64_t currentSize() const override;
+    virtual uint64_t currentCount() const override;
+    virtual int64_t maxObjectSize() const override;
+    virtual void getStats(StoreInfoStats &stats) const override;
+    virtual void stat(StoreEntry &) const override;
+    virtual void sync() override;
+    virtual void maintain() override;
+    virtual void markForUnlink(StoreEntry &) override;
+    virtual void unlink(StoreEntry &) override;
+    virtual int callback() override;
+
+    /// called when the entry is no longer needed by any transaction
+    void handleIdleEntry(StoreEntry &);
+
+    /// called to get rid of no longer needed entry data in RAM, if any
+    void memoryOut(StoreEntry &, const bool preserveSwappable);
+
+    /// makes the entry available for collapsing future requests
+    void allowCollapsing(StoreEntry *, const RequestFlags &, const HttpRequestMethod &);
+
+    /// marks the entry completed for collapsed requests
+    void transientsCompleteWriting(StoreEntry &);
+
+    /// Update local intransit entry after changes made by appending worker.
+    void syncCollapsed(const sfileno);
+
+    /// calls Root().transients->abandon() if transients are tracked
+    void transientsAbandon(StoreEntry &);
+
+    /// number of the transient entry readers some time ago
+    int transientReaders(const StoreEntry &) const;
+
+    /// disassociates the entry from the intransit table
+    void transientsDisconnect(MemObject &);
+
+    /// removes the entry from the memory cache
+    void memoryUnlink(StoreEntry &);
+
+    /// disassociates the entry from the memory cache, preserving cached data
+    void memoryDisconnect(StoreEntry &);
+
+    /// \returns an iterator for all Store entries
+    StoreSearch *search();
+
+    /// the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
+    static int store_dirs_rebuilding;
+
+private:
+    /// update reference counters of the recently touched entry
+    void referenceBusy(StoreEntry &e);
+    /// dereference() an idle entry and return true if the entry should be deleted
+    bool dereferenceIdle(StoreEntry &, bool wantsLocalMemory);
+
+    StoreEntry *find(const cache_key *key);
+    bool keepForLocalMemoryCache(StoreEntry &e) const;
+    bool anchorCollapsed(StoreEntry &, bool &inSync);
+
+    Disks *swapDir; ///< summary view of all disk caches
+    Memory *memStore; ///< memory cache
+
+    /// A shared table of public store entries that do not know whether they
+    /// will belong to a memory cache, a disk cache, or will be uncachable
+    /// when the response header comes. Used for SMP collapsed forwarding.
+    Transients *transients;
+};
+
+/// safely access controller singleton
+extern Controller &Root();
+
+/// initialize the storage module; a custom root is used by unit tests only
+extern void Init(Controller *root = nullptr);
+
+/// undo Init()
+extern void FreeMemory();
+
+} // namespace Store
+
+#endif /* SQUID_STORE_CONTROLLER_H */
similarity index 72%
rename from src/SwapDir.cc
rename to src/store/Disk.cc
index 84b436c7b8224ca68ed7bd064e144df5f6a20542..b745ec64f0f37444476ed4dfdcbb503728525fd4 100644 (file)
 #include "globals.h"
 #include "Parsing.h"
 #include "SquidConfig.h"
+#include "Store.h"
+#include "store/Disk.h"
 #include "StoreFileSystem.h"
-#include "SwapDir.h"
 #include "tools.h"
 
-SwapDir::SwapDir(char const *aType): theType(aType),
+Store::Disk::Disk(char const *aType): theType(aType),
     max_size(0), min_objsize(0), max_objsize (-1),
     path(NULL), index(-1), disker(-1),
     repl(NULL), removals(0), scanned(0),
@@ -29,29 +30,26 @@ SwapDir::SwapDir(char const *aType): theType(aType),
     fs.blksize = 1024;
 }
 
-SwapDir::~SwapDir()
+Store::Disk::~Disk()
 {
     // TODO: should we delete repl?
     xfree(path);
 }
 
 void
-SwapDir::create() {}
+Store::Disk::create() {}
 
 void
-SwapDir::dump(StoreEntry &)const {}
+Store::Disk::dump(StoreEntry &)const {}
 
 bool
-SwapDir::doubleCheck(StoreEntry &)
+Store::Disk::doubleCheck(StoreEntry &)
 {
     return false;
 }
 
 void
-SwapDir::unlink(StoreEntry &) {}
-
-void
-SwapDir::getStats(StoreInfoStats &stats) const
+Store::Disk::getStats(StoreInfoStats &stats) const
 {
     if (!doReportStat())
         return;
@@ -62,7 +60,7 @@ SwapDir::getStats(StoreInfoStats &stats) const
 }
 
 void
-SwapDir::stat(StoreEntry &output) const
+Store::Disk::stat(StoreEntry &output) const
 {
     if (!doReportStat())
         return;
@@ -82,19 +80,20 @@ SwapDir::stat(StoreEntry &output) const
 }
 
 void
-SwapDir::statfs(StoreEntry &)const {}
+Store::Disk::statfs(StoreEntry &)const {}
 
 void
-SwapDir::maintain() {}
+Store::Disk::maintain() {}
 
 uint64_t
-SwapDir::minSize() const
+Store::Disk::minSize() const
 {
+    // XXX: Not all disk stores use Config.Swap.lowWaterMark
     return ((maxSize() * Config.Swap.lowWaterMark) / 100);
 }
 
 int64_t
-SwapDir::maxObjectSize() const
+Store::Disk::maxObjectSize() const
 {
     // per-store max-size=N value is authoritative
     if (max_objsize > -1)
@@ -106,7 +105,7 @@ SwapDir::maxObjectSize() const
 }
 
 void
-SwapDir::maxObjectSize(int64_t newMax)
+Store::Disk::maxObjectSize(int64_t newMax)
 {
     // negative values mean no limit (-1)
     if (newMax < 0) {
@@ -127,22 +126,45 @@ SwapDir::maxObjectSize(int64_t newMax)
 }
 
 void
-SwapDir::reference(StoreEntry &) {}
+Store::Disk::reference(StoreEntry &) {}
 
 bool
-SwapDir::dereference(StoreEntry &, bool)
+Store::Disk::dereference(StoreEntry &)
 {
     return true; // keep in global store_table
 }
 
-int
-SwapDir::callback()
+void
+Store::Disk::diskFull()
 {
-    return 0;
+    if (currentSize() >= maxSize())
+        return;
+
+    max_size = currentSize();
+
+    debugs(20, DBG_IMPORTANT, "WARNING: Shrinking cache_dir #" << index << " to " << currentSize() / 1024.0 << " KB");
+}
+
+bool
+Store::Disk::objectSizeIsAcceptable(int64_t objsize) const
+{
+    // without limits, all object sizes are acceptable, including unknown ones
+    if (min_objsize <= 0 && max_objsize == -1)
+        return true;
+
+    // with limits, objects with unknown sizes are not acceptable
+    if (objsize == -1)
+        return false;
+
+    // without the upper limit, just check the lower limit
+    if (max_objsize == -1)
+        return  min_objsize <= objsize;
+
+    return min_objsize <= objsize && objsize < max_objsize;
 }
 
 bool
-SwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
+Store::Disk::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
 {
     debugs(47,8, HERE << "cache_dir[" << index << "]: needs " <<
            diskSpaceNeeded << " <? " << max_objsize);
@@ -164,12 +186,9 @@ SwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
     return true; // kids may provide more tests and should report true load
 }
 
-void
-SwapDir::sync() {}
-
 /* Move to StoreEntry ? */
 bool
-SwapDir::canLog(StoreEntry const &e)const
+Store::Disk::canLog(StoreEntry const &e)const
 {
     if (e.swap_filen < 0)
         return false;
@@ -193,31 +212,31 @@ SwapDir::canLog(StoreEntry const &e)const
 }
 
 void
-SwapDir::openLog() {}
+Store::Disk::openLog() {}
 
 void
-SwapDir::closeLog() {}
+Store::Disk::closeLog() {}
 
 int
-SwapDir::writeCleanStart()
+Store::Disk::writeCleanStart()
 {
     return 0;
 }
 
 void
-SwapDir::writeCleanDone() {}
+Store::Disk::writeCleanDone() {}
 
 void
-SwapDir::logEntry(const StoreEntry &, int) const {}
+Store::Disk::logEntry(const StoreEntry &, int) const {}
 
 char const *
-SwapDir::type() const
+Store::Disk::type() const
 {
     return theType;
 }
 
 bool
-SwapDir::active() const
+Store::Disk::active() const
 {
     if (IamWorkerProcess())
         return true;
@@ -230,7 +249,7 @@ SwapDir::active() const
 }
 
 bool
-SwapDir::needsDiskStrand() const
+Store::Disk::needsDiskStrand() const
 {
     return false;
 }
@@ -239,16 +258,16 @@ SwapDir::needsDiskStrand() const
  * - RBC 20030718
  */
 ConfigOption *
-SwapDir::getOptionTree() const
+Store::Disk::getOptionTree() const
 {
     ConfigOptionVector *result = new ConfigOptionVector;
-    result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionReadOnlyParse, &SwapDir::optionReadOnlyDump));
-    result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionObjectSizeParse, &SwapDir::optionObjectSizeDump));
+    result->options.push_back(new ConfigOptionAdapter<Disk>(*const_cast<Disk*>(this), &Store::Disk::optionReadOnlyParse, &Store::Disk::optionReadOnlyDump));
+    result->options.push_back(new ConfigOptionAdapter<Disk>(*const_cast<Disk*>(this), &Store::Disk::optionObjectSizeParse, &Store::Disk::optionObjectSizeDump));
     return result;
 }
 
 void
-SwapDir::parseOptions(int isaReconfig)
+Store::Disk::parseOptions(int isaReconfig)
 {
     const bool old_read_only = flags.read_only;
     char *name, *value;
@@ -263,7 +282,7 @@ SwapDir::parseOptions(int isaReconfig)
             ++value;
         }
 
-        debugs(3,2, "SwapDir::parseOptions: parsing store option '" << name << "'='" << (value ? value : "") << "'");
+        debugs(3,2, "cache_dir " << name << '=' << (value ? value : ""));
 
         if (newOption)
             if (!newOption->parse(name, value, isaReconfig))
@@ -286,7 +305,7 @@ SwapDir::parseOptions(int isaReconfig)
 }
 
 void
-SwapDir::dumpOptions(StoreEntry * entry) const
+Store::Disk::dumpOptions(StoreEntry * entry) const
 {
     ConfigOption *newOption = getOptionTree();
 
@@ -297,7 +316,7 @@ SwapDir::dumpOptions(StoreEntry * entry) const
 }
 
 bool
-SwapDir::optionReadOnlyParse(char const *option, const char *value, int)
+Store::Disk::optionReadOnlyParse(char const *option, const char *value, int)
 {
     if (strcmp(option, "no-store") != 0 && strcmp(option, "read-only") != 0)
         return false;
@@ -319,14 +338,14 @@ SwapDir::optionReadOnlyParse(char const *option, const char *value, int)
 }
 
 void
-SwapDir::optionReadOnlyDump(StoreEntry * e) const
+Store::Disk::optionReadOnlyDump(StoreEntry * e) const
 {
     if (flags.read_only)
         storeAppendPrintf(e, " no-store");
 }
 
 bool
-SwapDir::optionObjectSizeParse(char const *option, const char *value, int isaReconfig)
+Store::Disk::optionObjectSizeParse(char const *option, const char *value, int isaReconfig)
 {
     int64_t *val;
     if (strcmp(option, "max-size") == 0) {
@@ -359,7 +378,7 @@ SwapDir::optionObjectSizeParse(char const *option, const char *value, int isaRec
 }
 
 void
-SwapDir::optionObjectSizeDump(StoreEntry * e) const
+Store::Disk::optionObjectSizeDump(StoreEntry * e) const
 {
     if (min_objsize != 0)
         storeAppendPrintf(e, " min-size=%" PRId64, min_objsize);
@@ -370,14 +389,7 @@ SwapDir::optionObjectSizeDump(StoreEntry * e) const
 
 // some SwapDirs may maintain their indexes and be able to lookup an entry key
 StoreEntry *
-SwapDir::get(const cache_key *)
+Store::Disk::get(const cache_key *)
 {
     return NULL;
 }
-
-void
-SwapDir::get(String const, STOREGETCLIENT, void *)
-{
-    fatal("not implemented");
-}
-
diff --git a/src/store/Disk.h b/src/store/Disk.h
new file mode 100644 (file)
index 0000000..8445418
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_DISK_H
+#define SQUID_STORE_DISK_H
+
+#include "store/Controlled.h"
+#include "StoreIOState.h"
+
+
+class ConfigOption;
+class RemovalPolicy;
+
+namespace Store {
+
+/// manages a single cache_dir
+class Disk: public Controlled
+{
+
+public:
+    typedef RefCount<Disk> Pointer;
+
+    explicit Disk(char const *aType);
+    virtual ~Disk();
+    virtual void reconfigure() = 0;
+    char const *type() const;
+
+    virtual bool needsDiskStrand() const; ///< needs a dedicated kid process
+    virtual bool active() const; ///< may be used in this strand
+    /// whether stat should be reported by this SwapDir
+    virtual bool doReportStat() const { return active(); }
+    /// whether SwapDir may benefit from unlinkd
+    virtual bool unlinkdUseful() const = 0;
+
+    /**
+     * Notify this disk that it is full.
+     \todo XXX move into a protected api call between store files and their stores, rather than a top level api call
+     */
+    virtual void diskFull();
+
+    /* Controlled API */
+    virtual void create() override;
+    virtual StoreEntry *get(const cache_key *) override;
+    virtual uint64_t maxSize() const override { return max_size; }
+    virtual uint64_t minSize() const override;
+    virtual int64_t maxObjectSize() const override;
+    virtual void getStats(StoreInfoStats &stats) const override;
+    virtual void stat(StoreEntry &) const override;
+    virtual void reference(StoreEntry &e) override;
+    virtual bool dereference(StoreEntry &e) override;
+    virtual void maintain() override;
+
+    /// configure the maximum object size for this storage area.
+    /// May be any size up to the total storage area.
+    void maxObjectSize(int64_t newMax);
+
+    /// whether we can store an object of the given size
+    /// negative objSize means the object size is currently unknown
+    bool objectSizeIsAcceptable(int64_t objSize) const;
+
+    /// called when the entry is about to forget its association with cache_dir
+    virtual void disconnect(StoreEntry &) {}
+
+    /// called when entry swap out is complete
+    virtual void swappedOut(const StoreEntry &e) = 0;
+
+protected:
+    void parseOptions(int reconfiguring);
+    void dumpOptions(StoreEntry * e) const;
+    virtual ConfigOption *getOptionTree() const;
+    virtual bool allowOptionReconfigure(const char *const) const { return true; }
+
+    int64_t sizeInBlocks(const int64_t size) const { return (size + fs.blksize - 1) / fs.blksize; }
+
+private:
+    bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
+    void optionReadOnlyDump(StoreEntry * e) const;
+    bool optionObjectSizeParse(char const *option, const char *value, int reconfiguring);
+    void optionObjectSizeDump(StoreEntry * e) const;
+    char const *theType;
+
+protected:
+    uint64_t max_size;        ///< maximum allocatable size of the storage area
+    int64_t min_objsize;      ///< minimum size of any object stored here (-1 for no limit)
+    int64_t max_objsize;      ///< maximum size of any object stored here (-1 for no limit)
+
+public:
+    char *path;
+    int index;          /* This entry's index into the swapDirs array */
+    int disker; ///< disker kid id dedicated to this SwapDir or -1
+    RemovalPolicy *repl;
+    int removals;
+    int scanned;
+
+    struct Flags {
+        Flags() : selected(false), read_only(false) {}
+        bool selected;
+        bool read_only;
+    } flags;
+
+    virtual void dump(StoreEntry &)const;   /* Dump fs config snippet */
+    virtual bool doubleCheck(StoreEntry &); /* Double check the obj integrity */
+    virtual void statfs(StoreEntry &) const;    /* Dump fs statistics */
+
+    /// check whether we can store the entry; if we can, report current load
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const = 0;
+
+    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
+    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
+
+    bool canLog(StoreEntry const &e)const;
+    virtual void openLog();
+    virtual void closeLog();
+    virtual void logEntry(const StoreEntry & e, int op) const;
+
+    class CleanLog
+    {
+
+    public:
+        virtual ~CleanLog() {}
+
+        virtual const StoreEntry *nextEntry() = 0;
+        virtual void write(StoreEntry const &) = 0;
+    };
+
+    CleanLog *cleanLog;
+    virtual int writeCleanStart();
+    virtual void writeCleanDone();
+    virtual void parse(int index, char *path) = 0;
+
+    struct {
+        int blksize;
+    } fs;
+};
+
+} // namespace Store
+
+#endif /* SQUID_STORE_DISK_H */
+
diff --git a/src/store/Disks.cc b/src/store/Disks.cc
new file mode 100644 (file)
index 0000000..340f68e
--- /dev/null
@@ -0,0 +1,639 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 47    Store Directory Routines */
+
+#include "squid.h"
+#include "Debug.h"
+#include "globals.h"
+#include "profiler/Profiler.h"
+#include "SquidConfig.h"
+#include "Store.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
+#include "swap_log_op.h"
+#include "util.h" // for tvSubDsec() which should be in SquidTime.h
+
+static STDIRSELECT storeDirSelectSwapDirRoundRobin;
+static STDIRSELECT storeDirSelectSwapDirLeastLoad;
+/**
+ * This function pointer is set according to 'store_dir_select_algorithm'
+ * in squid.conf.
+ */
+STDIRSELECT *storeDirSelectSwapDir = storeDirSelectSwapDirLeastLoad;
+
+/**
+ * This new selection scheme simply does round-robin on all SwapDirs.
+ * A SwapDir is skipped if it is over the max_size (100%) limit, or
+ * overloaded.
+ */
+static int
+storeDirSelectSwapDirRoundRobin(const StoreEntry * e)
+{
+    // e->objectLen() is negative at this point when we are still STORE_PENDING
+    ssize_t objsize = e->mem_obj->expectedReplySize();
+    if (objsize != -1)
+        objsize += e->mem_obj->swap_hdr_sz;
+
+    // Increment the first candidate once per selection (not once per
+    // iteration) to reduce bias when some disk(s) attract more entries.
+    static int firstCandidate = 0;
+    if (++firstCandidate >= Config.cacheSwap.n_configured)
+        firstCandidate = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        const int dirn = (firstCandidate + i) % Config.cacheSwap.n_configured;
+        const SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(dirn));
+
+        int load = 0;
+        if (!sd->canStore(*e, objsize, load))
+            continue;
+
+        if (load < 0 || load > 1000) {
+            continue;
+        }
+
+        return dirn;
+    }
+
+    return -1;
+}
+
+/**
+ * Spread load across all of the store directories
+ *
+ * Note: We should modify this later on to prefer sticking objects
+ * in the *tightest fit* swapdir to conserve space, along with the
+ * actual swapdir usage. But for now, this hack will do while
+ * testing, so you should order your swapdirs in the config file
+ * from smallest max-size= to largest max-size=.
+ *
+ * We also have to choose nleast == nconf since we need to consider
+ * ALL swapdirs, regardless of state. Again, this is a hack while
+ * we sort out the real usefulness of this algorithm.
+ */
+static int
+storeDirSelectSwapDirLeastLoad(const StoreEntry * e)
+{
+    int64_t most_free = 0;
+    ssize_t least_objsize = -1;
+    int least_load = INT_MAX;
+    int load;
+    int dirn = -1;
+    int i;
+    RefCount<SwapDir> SD;
+
+    // e->objectLen() is negative at this point when we are still STORE_PENDING
+    ssize_t objsize = e->mem_obj->expectedReplySize();
+
+    if (objsize != -1)
+        objsize += e->mem_obj->swap_hdr_sz;
+
+    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        SD = dynamic_cast<SwapDir *>(INDEXSD(i));
+        SD->flags.selected = false;
+
+        if (!SD->canStore(*e, objsize, load))
+            continue;
+
+        if (load < 0 || load > 1000)
+            continue;
+
+        if (load > least_load)
+            continue;
+
+        const int64_t cur_free = SD->maxSize() - SD->currentSize();
+
+        /* If the load is equal, then look in more details */
+        if (load == least_load) {
+            /* closest max-size fit */
+
+            if (least_objsize != -1)
+                if (SD->maxObjectSize() > least_objsize)
+                    continue;
+
+            /* most free */
+            if (cur_free < most_free)
+                continue;
+        }
+
+        least_load = load;
+        least_objsize = SD->maxObjectSize();
+        most_free = cur_free;
+        dirn = i;
+    }
+
+    if (dirn >= 0)
+        dynamic_cast<SwapDir *>(INDEXSD(dirn))->flags.selected = true;
+
+    return dirn;
+}
+
+SwapDir *
+Store::Disks::store(int const x) const
+{
+    return INDEXSD(x);
+}
+
+SwapDir &
+Store::Disks::dir(const int i) const
+{
+    SwapDir *sd = INDEXSD(i);
+    assert(sd);
+    return *sd;
+}
+
+int
+Store::Disks::callback()
+{
+    int result = 0;
+    int j;
+    static int ndir = 0;
+
+    do {
+        j = 0;
+
+        for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+            if (ndir >= Config.cacheSwap.n_configured)
+                ndir = ndir % Config.cacheSwap.n_configured;
+
+            int temp_result = store(ndir)->callback();
+
+            ++ndir;
+
+            j += temp_result;
+
+            result += temp_result;
+
+            if (j > 100)
+                fatal ("too much io\n");
+        }
+    } while (j > 0);
+
+    ++ndir;
+
+    return result;
+}
+
+void
+Store::Disks::create()
+{
+    if (Config.cacheSwap.n_configured == 0) {
+        debugs(0, DBG_PARSE_NOTE(DBG_CRITICAL), "No cache_dir stores are configured.");
+    }
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).active())
+            store(i)->create();
+    }
+}
+
+StoreEntry *
+Store::Disks::get(const cache_key *key)
+{
+    if (const int cacheDirs = Config.cacheSwap.n_configured) {
+        // ask each cache_dir until the entry is found; use static starting
+        // point to avoid asking the same subset of disks more often
+        // TODO: coordinate with put() to be able to guess the right disk often
+        static int idx = 0;
+        for (int n = 0; n < cacheDirs; ++n) {
+            idx = (idx + 1) % cacheDirs;
+            SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
+            if (!sd->active())
+                continue;
+
+            if (StoreEntry *e = sd->get(key)) {
+                debugs(20, 7, "cache_dir " << idx << " has: " << *e);
+                return e;
+            }
+        }
+    }
+
+    debugs(20, 6, "none of " << Config.cacheSwap.n_configured <<
+           " cache_dirs have " << storeKeyText(key));
+    return nullptr;
+}
+
+void
+Store::Disks::init()
+{
+    if (Config.Store.objectsPerBucket <= 0)
+        fatal("'store_objects_per_bucket' should be larger than 0.");
+
+    if (Config.Store.avgObjectSize <= 0)
+        fatal("'store_avg_object_size' should be larger than 0.");
+
+    /* Calculate size of hash table (maximum currently 64k buckets).  */
+    /* this is very bogus, its specific to the any Store maintaining an
+     * in-core index, not global */
+    size_t buckets = (Store::Root().maxSize() + Config.memMaxSize) / Config.Store.avgObjectSize;
+    debugs(20, DBG_IMPORTANT, "Swap maxSize " << (Store::Root().maxSize() >> 10) <<
+           " + " << ( Config.memMaxSize >> 10) << " KB, estimated " << buckets << " objects");
+    buckets /= Config.Store.objectsPerBucket;
+    debugs(20, DBG_IMPORTANT, "Target number of buckets: " << buckets);
+    /* ideally the full scan period should be configurable, for the
+     * moment it remains at approximately 24 hours.  */
+    store_hash_buckets = storeKeyHashBuckets(buckets);
+    debugs(20, DBG_IMPORTANT, "Using " << store_hash_buckets << " Store buckets");
+    debugs(20, DBG_IMPORTANT, "Max Mem  size: " << ( Config.memMaxSize >> 10) << " KB" <<
+           (Config.memShared ? " [shared]" : ""));
+    debugs(20, DBG_IMPORTANT, "Max Swap size: " << (Store::Root().maxSize() >> 10) << " KB");
+
+    store_table = hash_create(storeKeyHashCmp,
+                              store_hash_buckets, storeKeyHashHash);
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        /* this starts a search of the store dirs, loading their
+         * index. under the new Store api this should be
+         * driven by the StoreHashIndex, not by each store.
+        *
+        * That is, the HashIndex should perform a search of each dir it is
+        * indexing to do the hash insertions. The search is then able to
+        * decide 'from-memory', or 'from-clean-log' or 'from-dirty-log' or
+        * 'from-no-log'.
+        *
+         * Step 1: make the store rebuilds use a search internally
+        * Step 2: change the search logic to use the four modes described
+        *         above
+        * Step 3: have the hash index walk the searches itself.
+         */
+        if (dir(i).active())
+            store(i)->init();
+    }
+
+    if (strcasecmp(Config.store_dir_select_algorithm, "round-robin") == 0) {
+        storeDirSelectSwapDir = storeDirSelectSwapDirRoundRobin;
+        debugs(47, DBG_IMPORTANT, "Using Round Robin store dir selection");
+    } else {
+        storeDirSelectSwapDir = storeDirSelectSwapDirLeastLoad;
+        debugs(47, DBG_IMPORTANT, "Using Least Load store dir selection");
+    }
+}
+
+uint64_t
+Store::Disks::maxSize() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).doReportStat())
+            result += store(i)->maxSize();
+    }
+
+    return result;
+}
+
+uint64_t
+Store::Disks::minSize() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).doReportStat())
+            result += store(i)->minSize();
+    }
+
+    return result;
+}
+
+uint64_t
+Store::Disks::currentSize() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).doReportStat())
+            result += store(i)->currentSize();
+    }
+
+    return result;
+}
+
+uint64_t
+Store::Disks::currentCount() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).doReportStat())
+            result += store(i)->currentCount();
+    }
+
+    return result;
+}
+
+int64_t
+Store::Disks::maxObjectSize() const
+{
+    int64_t result = -1;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (dir(i).active() && store(i)->maxObjectSize() > result)
+            result = store(i)->maxObjectSize();
+    }
+
+    return result;
+}
+
+void
+Store::Disks::getStats(StoreInfoStats &stats) const
+{
+    // accumulate per-disk cache stats
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        StoreInfoStats dirStats;
+        store(i)->getStats(dirStats);
+        stats += dirStats;
+    }
+
+    // common to all disks
+    stats.swap.open_disk_fd = store_open_disk_fd;
+
+    // memory cache stats are collected in StoreController::getStats(), for now
+}
+
+void
+Store::Disks::stat(StoreEntry & output) const
+{
+    int i;
+
+    /* Now go through each store, calling its stat routine */
+
+    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        storeAppendPrintf(&output, "\n");
+        store(i)->stat(output);
+    }
+}
+
+void
+Store::Disks::reference(StoreEntry &e)
+{
+    e.disk().reference(e);
+}
+
+bool
+Store::Disks::dereference(StoreEntry &e)
+{
+    return e.disk().dereference(e);
+}
+
+void
+Store::Disks::maintain()
+{
+    int i;
+    /* walk each fs */
+
+    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        /* XXX FixMe: This should be done "in parallell" on the different
+         * cache_dirs, not one at a time.
+         */
+        /* call the maintain function .. */
+        store(i)->maintain();
+    }
+}
+
+void
+Store::Disks::sync()
+{
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
+        store(i)->sync();
+}
+
+void 
+Store::Disks::markForUnlink(StoreEntry &e) {
+    if (e.swap_filen >= 0)
+        store(e.swap_dirn)->markForUnlink(e);
+}
+
+void 
+Store::Disks::unlink(StoreEntry &e) {
+    if (e.swap_filen >= 0)
+        store(e.swap_dirn)->unlink(e);
+}
+
+bool
+Store::Disks::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
+{
+    if (const int cacheDirs = Config.cacheSwap.n_configured) {
+        // ask each cache_dir until the entry is found; use static starting
+        // point to avoid asking the same subset of disks more often
+        // TODO: coordinate with put() to be able to guess the right disk often
+        static int idx = 0;
+        for (int n = 0; n < cacheDirs; ++n) {
+            idx = (idx + 1) % cacheDirs;
+            SwapDir &sd = dir(idx);
+            if (!sd.active())
+                continue;
+
+            if (sd.anchorCollapsed(collapsed, inSync)) {
+                debugs(20, 3, "cache_dir " << idx << " anchors " << collapsed);
+                return true;
+            }
+        }
+    }
+
+    debugs(20, 4, "none of " << Config.cacheSwap.n_configured <<
+           " cache_dirs have " << collapsed);
+    return false;
+}
+
+bool
+Store::Disks::updateCollapsed(StoreEntry &collapsed)
+{
+    return collapsed.swap_filen >= 0 &&
+        dir(collapsed.swap_dirn).updateCollapsed(collapsed);
+}
+
+
+/* Store::Disks globals that should be converted to use RegisteredRunner */
+
+void
+storeDirOpenSwapLogs()
+{
+    for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
+        INDEXSD(dirn)->openLog();
+}
+
+void
+storeDirCloseSwapLogs()
+{
+    for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
+        INDEXSD(dirn)->closeLog();
+}
+
+/**
+ *  storeDirWriteCleanLogs
+ *
+ *  Writes a "clean" swap log file from in-memory metadata.
+ *  This is a rewrite of the original function to troll each
+ *  StoreDir and write the logs, and flush at the end of
+ *  the run. Thanks goes to Eric Stern, since this solution
+ *  came out of his COSS code.
+ */
+int
+storeDirWriteCleanLogs(int reopen)
+{
+    const StoreEntry *e = NULL;
+    int n = 0;
+
+    struct timeval start;
+    double dt;
+    RefCount<SwapDir> sd;
+    int dirn;
+    int notdone = 1;
+
+    // Check for store_dirs_rebuilding because fatal() often calls us in early
+    // initialization phases, before store log is initialized and ready. Also,
+    // some stores probably do not support log cleanup during Store rebuilding.
+    if (StoreController::store_dirs_rebuilding) {
+        debugs(20, DBG_IMPORTANT, "Not currently OK to rewrite swap log.");
+        debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Operation aborted.");
+        return 0;
+    }
+
+    debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Starting...");
+    getCurrentTime();
+    start = current_time;
+
+    for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
+        sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
+
+        if (sd->writeCleanStart() < 0) {
+            debugs(20, DBG_IMPORTANT, "log.clean.start() failed for dir #" << sd->index);
+            continue;
+        }
+    }
+
+    /*
+     * This may look inefficient as CPU wise it is more efficient to do this
+     * sequentially, but I/O wise the parallellism helps as it allows more
+     * hdd spindles to be active.
+     */
+    while (notdone) {
+        notdone = 0;
+
+        for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
+            sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
+
+            if (NULL == sd->cleanLog)
+                continue;
+
+            e = sd->cleanLog->nextEntry();
+
+            if (!e)
+                continue;
+
+            notdone = 1;
+
+            if (!sd->canLog(*e))
+                continue;
+
+            sd->cleanLog->write(*e);
+
+            if ((++n & 0xFFFF) == 0) {
+                getCurrentTime();
+                debugs(20, DBG_IMPORTANT, "  " << std::setw(7) << n  <<
+                       " entries written so far.");
+            }
+        }
+    }
+
+    /* Flush */
+    for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
+        dynamic_cast<SwapDir *>(INDEXSD(dirn))->writeCleanDone();
+
+    if (reopen)
+        storeDirOpenSwapLogs();
+
+    getCurrentTime();
+
+    dt = tvSubDsec(start, current_time);
+
+    debugs(20, DBG_IMPORTANT, "  Finished.  Wrote " << n << " entries.");
+    debugs(20, DBG_IMPORTANT, "  Took "<< std::setw(3)<< std::setprecision(2) << dt <<
+           " seconds ("<< std::setw(6) << ((double) n / (dt > 0.0 ? dt : 1.0)) << " entries/sec).");
+
+    return n;
+}
+
+/* Globals that should be converted to static Store::Disks methods */
+
+void
+allocate_new_swapdir(Store::DiskConfig *swap)
+{
+    if (swap->swapDirs == NULL) {
+        swap->n_allocated = 4;
+        swap->swapDirs = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
+    }
+
+    if (swap->n_allocated == swap->n_configured) {
+        swap->n_allocated <<= 1;
+        SwapDir::Pointer *const tmp = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
+        memcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
+        xfree(swap->swapDirs);
+        swap->swapDirs = tmp;
+    }
+}
+
+void
+free_cachedir(Store::DiskConfig *swap)
+{
+    int i;
+    /* DON'T FREE THESE FOR RECONFIGURE */
+
+    if (reconfiguring)
+        return;
+
+    for (i = 0; i < swap->n_configured; ++i) {
+        /* TODO XXX this lets the swapdir free resources asynchronously
+        * swap->swapDirs[i]->deactivate();
+        * but there may be such a means already.
+        * RBC 20041225
+        */
+        swap->swapDirs[i] = NULL;
+    }
+
+    safe_free(swap->swapDirs);
+    swap->swapDirs = NULL;
+    swap->n_allocated = 0;
+    swap->n_configured = 0;
+}
+
+/* Globals that should be moved to some Store::UFS-specific logging module */
+
+/**
+ * An entry written to the swap log MUST have the following
+ * properties.
+ *   1.  It MUST be a public key.  It does no good to log
+ *       a public ADD, change the key, then log a private
+ *       DEL.  So we need to log a DEL before we change a
+ *       key from public to private.
+ *   2.  It MUST have a valid (> -1) swap_filen.
+ */
+void
+storeDirSwapLog(const StoreEntry * e, int op)
+{
+    assert (e);
+    assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
+    assert(e->swap_filen >= 0);
+    /*
+     * icons and such; don't write them to the swap log
+     */
+
+    if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
+        return;
+
+    assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
+
+    debugs(20, 3, "storeDirSwapLog: " <<
+           swap_log_op_str[op] << " " <<
+           e->getMD5Text() << " " <<
+           e->swap_dirn << " " <<
+           std::hex << std::uppercase << std::setfill('0') << std::setw(8) << e->swap_filen);
+
+    dynamic_cast<SwapDir *>(INDEXSD(e->swap_dirn))->logEntry(*e, op);
+}
diff --git a/src/store/Disks.h b/src/store/Disks.h
new file mode 100644 (file)
index 0000000..c557d8d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_DISKS_H
+#define SQUID_STORE_DISKS_H
+
+#include "store/Controlled.h"
+#include "store/forward.h"
+
+namespace Store {
+
+/// summary view of all disk caches (cache_dirs) combined
+class Disks: public Controlled
+{
+public:
+    /* Storage API */
+    virtual void create() override;
+    virtual void init() override;
+    virtual StoreEntry *get(const cache_key *) override;
+    virtual uint64_t maxSize() const override;
+    virtual uint64_t minSize() const override;
+    virtual uint64_t currentSize() const override;
+    virtual uint64_t currentCount() const override;
+    virtual int64_t maxObjectSize() const override;
+    virtual void getStats(StoreInfoStats &stats) const override;
+    virtual void stat(StoreEntry &) const override;
+    virtual void sync() override;
+    virtual void reference(StoreEntry &) override;
+    virtual bool dereference(StoreEntry &e) override;
+    virtual void maintain() override;
+    virtual bool anchorCollapsed(StoreEntry &e, bool &inSync) override;
+    virtual bool updateCollapsed(StoreEntry &e) override;
+    virtual void markForUnlink(StoreEntry &) override;
+    virtual void unlink(StoreEntry &) override;
+    virtual int callback() override;
+
+private:
+    /* migration logic */
+    SwapDir *store(int const x) const;
+    SwapDir &dir(int const idx) const;
+};
+
+} // namespace Store
+
+/* Store::Disks globals that should be converted to use RegisteredRunner */
+void storeDirOpenSwapLogs(void);
+int storeDirWriteCleanLogs(int reopen);
+void storeDirCloseSwapLogs(void);
+
+/* Globals that should be converted to static Store::Disks methods */
+void allocate_new_swapdir(Store::DiskConfig *swap);
+void free_cachedir(Store::DiskConfig *swap);
+
+/* Globals that should be converted to Store::Disks private data members */
+typedef int STDIRSELECT(const StoreEntry *e);
+extern STDIRSELECT *storeDirSelectSwapDir;
+
+/* Globals that should be moved to some Store::UFS-specific logging module */
+void storeDirSwapLog(const StoreEntry *e, int op);
+
+#endif /* SQUID_STORE_DISKS_H */
diff --git a/src/store/LocalSearch.cc b/src/store/LocalSearch.cc
new file mode 100644 (file)
index 0000000..8a71e1b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 47    Store Search */
+
+#include "squid.h"
+#include "Debug.h"
+#include "globals.h"
+#include "store/LocalSearch.h"
+#include "StoreSearch.h"
+
+namespace Store {
+
+/// iterates local store_table
+class LocalSearch : public StoreSearch
+{
+    CBDATA_CLASS(LocalSearch);
+
+public:
+    LocalSearch();
+
+    /* StoreSearch API */
+    virtual void next(void (callback)(void *cbdata), void *cbdata) override;
+    virtual bool next() override;
+    virtual bool error() const override;
+    virtual bool isDone() const override;
+    virtual StoreEntry *currentItem() override;
+
+private:
+    void copyBucket();
+    void (*callback)(void *cbdata);
+    void *cbdata;
+    bool _done;
+    int bucket;
+    std::vector<StoreEntry *> entries;
+};
+
+} // namespace Store
+
+CBDATA_NAMESPACED_CLASS_INIT(Store, LocalSearch);
+
+StoreSearch *
+Store::NewLocalSearch()
+{
+    return new LocalSearch;
+}
+
+Store::LocalSearch::LocalSearch() :
+    callback(NULL),
+    cbdata(NULL),
+    _done(false),
+    bucket(0)
+{}
+
+void
+Store::LocalSearch::next(void (aCallback)(void *), void *aCallbackData)
+{
+    next();
+    aCallback (aCallbackData);
+}
+
+bool
+Store::LocalSearch::next()
+{
+    if (!entries.empty())
+        entries.pop_back();
+
+    while (!isDone() && !entries.size())
+        copyBucket();
+
+    return currentItem() != NULL;
+}
+
+bool
+Store::LocalSearch::error() const
+{
+    return false;
+}
+
+bool
+Store::LocalSearch::isDone() const
+{
+    return bucket >= store_hash_buckets || _done;
+}
+
+StoreEntry *
+Store::LocalSearch::currentItem()
+{
+    if (!entries.size())
+        return NULL;
+
+    return entries.back();
+}
+
+void
+Store::LocalSearch::copyBucket()
+{
+    /* probably need to lock the store entries...
+     * we copy them all to prevent races on the links. */
+    debugs(47, 3, "Store::LocalSearch::copyBucket #" << bucket);
+    assert (!entries.size());
+    hash_link *link_ptr = NULL;
+    hash_link *link_next = NULL;
+    link_next = hash_get_bucket(store_table, bucket);
+
+    while (NULL != (link_ptr = link_next)) {
+        link_next = link_ptr->next;
+        StoreEntry *e = (StoreEntry *) link_ptr;
+
+        entries.push_back(e);
+    }
+
+    ++bucket;
+    debugs(47,3, "got entries: " << entries.size());
+}
similarity index 56%
rename from src/fs/forward.h
rename to src/store/LocalSearch.h
index 81077a0afc8d591cae21d8460c5efa51dfbf7ecf..fd0977abece7203b6e9c3b0e3fcbf2d28600f077 100644 (file)
@@ -6,11 +6,13 @@
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
-#ifndef SQUID_FORWARD_H_
-#define SQUID_FORWARD_H_
+#ifndef SQUID_STORE_LOCAL_SEARCH_H
+#define SQUID_STORE_LOCAL_SEARCH_H
 
-typedef int32_t sfileno;
-typedef signed int sdirno;
+#include "store/forward.h"
 
-#endif /* SQUID_FORWARD_H_ */
+namespace Store {
+    StoreSearch *NewLocalSearch();
+} // namespace Store
 
+#endif /* SQUID_STORE_LOCAL_SEARCH_H */
diff --git a/src/store/Makefile.am b/src/store/Makefile.am
new file mode 100644 (file)
index 0000000..6b99618
--- /dev/null
@@ -0,0 +1,24 @@
+## Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+##
+## Squid software is distributed under GPLv2+ license and includes
+## contributions from numerous individuals and organizations.
+## Please see the COPYING and CONTRIBUTORS files for details.
+##
+
+include $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+noinst_LTLIBRARIES = libstore.la
+
+libstore_la_SOURCES= \
+       Controlled.h \
+       Controller.cc \
+       Controller.h \
+       Disk.cc \
+       Disk.h \
+       Disks.cc \
+       Disks.h \
+       forward.h \
+       LocalSearch.cc \
+       LocalSearch.h \
+       Storage.h
diff --git a/src/store/Storage.h b/src/store/Storage.h
new file mode 100644 (file)
index 0000000..1abc994
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_STORAGE_H
+#define SQUID_STORE_STORAGE_H
+
+#include "base/RefCount.h"
+#include "store/forward.h"
+
+class StoreInfoStats;
+
+namespace Store {
+
+/// A "response storage" abstraction.
+/// This API is shared among Controller and Controlled classes.
+class Storage: public RefCountable
+{
+public:
+    virtual ~Storage() {}
+
+    /// create system resources needed for this store to operate in the future
+    virtual void create() = 0;
+
+    /// Start preparing the store for use. To check readiness, callers should
+    /// use readable() and writable() methods.
+    virtual void init() = 0;
+
+    /// Retrieve a store entry from the store (blocking)
+    virtual StoreEntry *get(const cache_key *) = 0;
+
+    /**
+     * The maximum size the store will support in normal use. Inaccuracy is
+     * permitted, but may throw estimates for memory etc out of whack.
+     */
+    virtual uint64_t maxSize() const = 0;
+
+    /// the minimum size the store will shrink to via normal housekeeping
+    virtual uint64_t minSize() const = 0;
+
+    /// current size
+    virtual uint64_t currentSize() const = 0;
+
+    /// the total number of objects stored right now
+    virtual uint64_t currentCount() const = 0;
+
+    /// the maximum size of a storable object; -1 if unlimited
+    virtual int64_t maxObjectSize() const = 0;
+
+    /// collect statistics
+    virtual void getStats(StoreInfoStats &stats) const = 0;
+
+    /**
+     * Output stats to the provided store entry.
+     \todo make these calls asynchronous
+     */
+    virtual void stat(StoreEntry &e) const = 0;
+
+    /// expect an unlink() call after the entry becomes idle
+    virtual void markForUnlink(StoreEntry &e) = 0;
+
+    /// remove the entry from the store
+    virtual void unlink(StoreEntry &e) = 0;
+
+    /// called once every main loop iteration; TODO: Move to UFS code.
+    virtual int callback() { return 0; }
+
+    /// perform regular periodic maintenance; TODO: move to UFSSwapDir::Maintain
+    virtual void maintain() = 0;
+
+    /// prepare for shutdown
+    virtual void sync() {}
+};
+
+} // namespace Store
+
+#endif /* SQUID_STORE_STORAGE_H */
+
diff --git a/src/store/forward.h b/src/store/forward.h
new file mode 100644 (file)
index 0000000..0bace2f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_STORE_FORWARD_H
+#define SQUID_STORE_FORWARD_H
+
+typedef int32_t sfileno;
+typedef signed int sdirno;
+
+/// maximum number of entries per cache_dir
+enum { SwapFilenMax = 0xFFFFFF }; // keep in sync with StoreEntry::swap_filen
+
+/// Store key.
+typedef unsigned char cache_key;
+
+class StoreSearch;
+class StoreClient;
+class StoreEntry;
+class MemStore;
+class Transients;
+
+namespace Store
+{
+    class Storage;
+    class Controller;
+    class Controlled;
+    class Disks;
+    class Disk;
+    class DiskConfig;
+
+    typedef ::StoreEntry Entry;
+    typedef ::MemStore Memory;
+    typedef ::Transients Transients;
+} // namespace Store
+
+// TODO: Remove these once all code has been transitioned to Store namespace.
+typedef Store::Controller StoreController;
+typedef Store::Disks StoreHashIndex;
+typedef Store::Disk SwapDir;
+template <class C> class RefCount;
+typedef RefCount<Store::Disk> SwapDirPointer;
+
+#endif /* SQUID_STORE_FORWARD_H */
+
index e2101c6d7984f4d8c5a277c3f5318ff9fe552fcf..f4c830960d2d0e69b1a88176e47829a266d4969e 100644 (file)
@@ -297,7 +297,7 @@ storeDigestRebuildResume(void)
 {
     assert(sd_state.rebuild_lock);
     assert(!sd_state.rewrite_lock);
-    sd_state.theSearch = Store::Root().search(NULL, NULL);
+    sd_state.theSearch = Store::Root().search();
     /* resize or clear */
 
     if (!storeDigestResize())
diff --git a/src/store_dir.cc b/src/store_dir.cc
deleted file mode 100644 (file)
index 7f1b218..0000000
+++ /dev/null
@@ -1,1350 +0,0 @@
-/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* DEBUG: section 47    Store Directory Routines */
-
-#include "squid.h"
-#include "globals.h"
-#include "mem_node.h"
-#include "MemObject.h"
-#include "MemStore.h"
-#include "profiler/Profiler.h"
-#include "SquidConfig.h"
-#include "SquidMath.h"
-#include "SquidTime.h"
-#include "Store.h"
-#include "store_key_md5.h"
-#include "StoreHashIndex.h"
-#include "swap_log_op.h"
-#include "SwapDir.h"
-#include "tools.h"
-#include "Transients.h"
-// for tvSubDsec() which should be in SquidTime.h
-#include "util.h"
-
-#include <cerrno>
-#include <climits>
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-static STDIRSELECT storeDirSelectSwapDirRoundRobin;
-static STDIRSELECT storeDirSelectSwapDirLeastLoad;
-
-/*
- * store_dirs_rebuilding is initialized to _1_ as a hack so that
- * storeDirWriteCleanLogs() doesn't try to do anything unless _all_
- * cache_dirs have been read.  For example, without this hack, Squid
- * will try to write clean log files if -kparse fails (becasue it
- * calls fatal()).
- */
-int StoreController::store_dirs_rebuilding = 1;
-
-StoreController::StoreController() : swapDir (new StoreHashIndex())
-    , memStore(NULL), transients(NULL)
-{}
-
-StoreController::~StoreController()
-{
-    delete memStore;
-    delete transients;
-}
-
-/*
- * This function pointer is set according to 'store_dir_select_algorithm'
- * in squid.conf.
- */
-STDIRSELECT *storeDirSelectSwapDir = storeDirSelectSwapDirLeastLoad;
-
-void
-StoreController::init()
-{
-    if (Config.memShared && IamWorkerProcess()) {
-        memStore = new MemStore;
-        memStore->init();
-    }
-
-    swapDir->init();
-
-    if (0 == strcasecmp(Config.store_dir_select_algorithm, "round-robin")) {
-        storeDirSelectSwapDir = storeDirSelectSwapDirRoundRobin;
-        debugs(47, DBG_IMPORTANT, "Using Round Robin store dir selection");
-    } else {
-        storeDirSelectSwapDir = storeDirSelectSwapDirLeastLoad;
-        debugs(47, DBG_IMPORTANT, "Using Least Load store dir selection");
-    }
-
-    if (UsingSmp() && IamWorkerProcess() && Config.onoff.collapsed_forwarding) {
-        transients = new Transients;
-        transients->init();
-    }
-}
-
-void
-StoreController::createOneStore(Store &aStore)
-{
-    /*
-     * On Windows, fork() is not available.
-     * The following is a workaround for create store directories sequentially
-     * when running on native Windows port.
-     */
-#if !_SQUID_WINDOWS_
-
-    if (fork())
-        return;
-
-#endif
-
-    aStore.create();
-
-#if !_SQUID_WINDOWS_
-
-    exit(0);
-
-#endif
-}
-
-void
-StoreController::create()
-{
-    swapDir->create();
-
-#if !_SQUID_WINDOWS_
-
-    pid_t pid;
-
-    do {
-        int status;
-#if _SQUID_NEXT_
-
-        pid = wait3(&status, WNOHANG, NULL);
-#else
-
-        pid = waitpid(-1, &status, 0);
-#endif
-
-    } while (pid > 0 || (pid < 0 && errno == EINTR));
-
-#endif
-}
-
-/**
- * Determine whether the given directory can handle this object
- * size
- *
- * Note: if the object size is -1, then the only swapdirs that
- * will return true here are ones that have min and max unset,
- * ie any-sized-object swapdirs. This is a good thing.
- */
-bool
-SwapDir::objectSizeIsAcceptable(int64_t objsize) const
-{
-    // If the swapdir has no range limits, then it definitely can
-    if (min_objsize <= 0 && max_objsize == -1)
-        return true;
-
-    /*
-     * If the object size is -1 and the storedir has limits we
-     * can't store it there.
-     */
-    if (objsize == -1)
-        return false;
-
-    // Else, make sure that the object size will fit.
-    if (max_objsize == -1 && min_objsize <= objsize)
-        return true;
-    else
-        return min_objsize <= objsize && max_objsize > objsize;
-}
-
-/*
- * This new selection scheme simply does round-robin on all SwapDirs.
- * A SwapDir is skipped if it is over the max_size (100%) limit, or
- * overloaded.
- */
-static int
-storeDirSelectSwapDirRoundRobin(const StoreEntry * e)
-{
-    // e->objectLen() is negative at this point when we are still STORE_PENDING
-    ssize_t objsize = e->mem_obj->expectedReplySize();
-    if (objsize != -1)
-        objsize += e->mem_obj->swap_hdr_sz;
-
-    // Increment the first candidate once per selection (not once per
-    // iteration) to reduce bias when some disk(s) attract more entries.
-    static int firstCandidate = 0;
-    if (++firstCandidate >= Config.cacheSwap.n_configured)
-        firstCandidate = 0;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        const int dirn = (firstCandidate + i) % Config.cacheSwap.n_configured;
-        const SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(dirn));
-
-        int load = 0;
-        if (!sd->canStore(*e, objsize, load))
-            continue;
-
-        if (load < 0 || load > 1000) {
-            continue;
-        }
-
-        return dirn;
-    }
-
-    return -1;
-}
-
-/*
- * Spread load across all of the store directories
- *
- * Note: We should modify this later on to prefer sticking objects
- * in the *tightest fit* swapdir to conserve space, along with the
- * actual swapdir usage. But for now, this hack will do while
- * testing, so you should order your swapdirs in the config file
- * from smallest max-size= to largest max-size=.
- *
- * We also have to choose nleast == nconf since we need to consider
- * ALL swapdirs, regardless of state. Again, this is a hack while
- * we sort out the real usefulness of this algorithm.
- */
-static int
-storeDirSelectSwapDirLeastLoad(const StoreEntry * e)
-{
-    int64_t most_free = 0;
-    ssize_t least_objsize = -1;
-    int least_load = INT_MAX;
-    int load;
-    int dirn = -1;
-    int i;
-    RefCount<SwapDir> SD;
-
-    // e->objectLen() is negative at this point when we are still STORE_PENDING
-    ssize_t objsize = e->mem_obj->expectedReplySize();
-
-    if (objsize != -1)
-        objsize += e->mem_obj->swap_hdr_sz;
-
-    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        SD = dynamic_cast<SwapDir *>(INDEXSD(i));
-        SD->flags.selected = false;
-
-        if (!SD->canStore(*e, objsize, load))
-            continue;
-
-        if (load < 0 || load > 1000)
-            continue;
-
-        if (load > least_load)
-            continue;
-
-        const int64_t cur_free = SD->maxSize() - SD->currentSize();
-
-        /* If the load is equal, then look in more details */
-        if (load == least_load) {
-            /* closest max-size fit */
-
-            if (least_objsize != -1)
-                if (SD->maxObjectSize() > least_objsize)
-                    continue;
-
-            /* most free */
-            if (cur_free < most_free)
-                continue;
-        }
-
-        least_load = load;
-        least_objsize = SD->maxObjectSize();
-        most_free = cur_free;
-        dirn = i;
-    }
-
-    if (dirn >= 0)
-        dynamic_cast<SwapDir *>(INDEXSD(dirn))->flags.selected = true;
-
-    return dirn;
-}
-
-/*
- * An entry written to the swap log MUST have the following
- * properties.
- *   1.  It MUST be a public key.  It does no good to log
- *       a public ADD, change the key, then log a private
- *       DEL.  So we need to log a DEL before we change a
- *       key from public to private.
- *   2.  It MUST have a valid (> -1) swap_filen.
- */
-void
-storeDirSwapLog(const StoreEntry * e, int op)
-{
-    assert (e);
-    assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
-    assert(e->swap_filen >= 0);
-    /*
-     * icons and such; don't write them to the swap log
-     */
-
-    if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
-        return;
-
-    assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
-
-    debugs(20, 3, "storeDirSwapLog: " <<
-           swap_log_op_str[op] << " " <<
-           e->getMD5Text() << " " <<
-           e->swap_dirn << " " <<
-           std::hex << std::uppercase << std::setfill('0') << std::setw(8) << e->swap_filen);
-
-    dynamic_cast<SwapDir *>(INDEXSD(e->swap_dirn))->logEntry(*e, op);
-}
-
-void
-StoreController::getStats(StoreInfoStats &stats) const
-{
-    if (memStore)
-        memStore->getStats(stats);
-    else {
-        // move this code to a non-shared memory cache class when we have it
-        stats.mem.shared = false;
-        stats.mem.capacity = Config.memMaxSize;
-        stats.mem.size = mem_node::StoreMemSize();
-        stats.mem.count = hot_obj_count;
-    }
-
-    swapDir->getStats(stats);
-
-    // low-level info not specific to memory or disk cache
-    stats.store_entry_count = StoreEntry::inUseCount();
-    stats.mem_object_count = MemObject::inUseCount();
-}
-
-void
-StoreController::stat(StoreEntry &output) const
-{
-    storeAppendPrintf(&output, "Store Directory Statistics:\n");
-    storeAppendPrintf(&output, "Store Entries          : %lu\n",
-                      (unsigned long int)StoreEntry::inUseCount());
-    storeAppendPrintf(&output, "Maximum Swap Size      : %" PRIu64 " KB\n",
-                      maxSize() >> 10);
-    storeAppendPrintf(&output, "Current Store Swap Size: %.2f KB\n",
-                      currentSize() / 1024.0);
-    storeAppendPrintf(&output, "Current Capacity       : %.2f%% used, %.2f%% free\n",
-                      Math::doublePercent(currentSize(), maxSize()),
-                      Math::doublePercent((maxSize() - currentSize()), maxSize()));
-
-    if (memStore)
-        memStore->stat(output);
-
-    /* now the swapDir */
-    swapDir->stat(output);
-}
-
-/* if needed, this could be taught to cache the result */
-uint64_t
-StoreController::maxSize() const
-{
-    /* TODO: include memory cache ? */
-    return swapDir->maxSize();
-}
-
-uint64_t
-StoreController::minSize() const
-{
-    /* TODO: include memory cache ? */
-    return swapDir->minSize();
-}
-
-uint64_t
-StoreController::currentSize() const
-{
-    return swapDir->currentSize();
-}
-
-uint64_t
-StoreController::currentCount() const
-{
-    return swapDir->currentCount();
-}
-
-int64_t
-StoreController::maxObjectSize() const
-{
-    return swapDir->maxObjectSize();
-}
-
-void
-SwapDir::diskFull()
-{
-    if (currentSize() >= maxSize())
-        return;
-
-    max_size = currentSize();
-
-    debugs(20, DBG_IMPORTANT, "WARNING: Shrinking cache_dir #" << index << " to " << currentSize() / 1024.0 << " KB");
-}
-
-void
-storeDirOpenSwapLogs(void)
-{
-    for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
-        dynamic_cast<SwapDir *>(INDEXSD(dirn))->openLog();
-}
-
-void
-storeDirCloseSwapLogs(void)
-{
-    for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
-        dynamic_cast<SwapDir *>(INDEXSD(dirn))->closeLog();
-}
-
-/*
- *  storeDirWriteCleanLogs
- *
- *  Writes a "clean" swap log file from in-memory metadata.
- *  This is a rewrite of the original function to troll each
- *  StoreDir and write the logs, and flush at the end of
- *  the run. Thanks goes to Eric Stern, since this solution
- *  came out of his COSS code.
- */
-int
-storeDirWriteCleanLogs(int reopen)
-{
-    const StoreEntry *e = NULL;
-    int n = 0;
-
-    struct timeval start;
-    double dt;
-    RefCount<SwapDir> sd;
-    int dirn;
-    int notdone = 1;
-
-    if (StoreController::store_dirs_rebuilding) {
-        debugs(20, DBG_IMPORTANT, "Not currently OK to rewrite swap log.");
-        debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Operation aborted.");
-        return 0;
-    }
-
-    debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Starting...");
-    getCurrentTime();
-    start = current_time;
-
-    for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
-        sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
-
-        if (sd->writeCleanStart() < 0) {
-            debugs(20, DBG_IMPORTANT, "log.clean.start() failed for dir #" << sd->index);
-            continue;
-        }
-    }
-
-    /*
-     * This may look inefficient as CPU wise it is more efficient to do this
-     * sequentially, but I/O wise the parallellism helps as it allows more
-     * hdd spindles to be active.
-     */
-    while (notdone) {
-        notdone = 0;
-
-        for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
-            sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
-
-            if (NULL == sd->cleanLog)
-                continue;
-
-            e = sd->cleanLog->nextEntry();
-
-            if (!e)
-                continue;
-
-            notdone = 1;
-
-            if (!sd->canLog(*e))
-                continue;
-
-            sd->cleanLog->write(*e);
-
-            if ((++n & 0xFFFF) == 0) {
-                getCurrentTime();
-                debugs(20, DBG_IMPORTANT, "  " << std::setw(7) << n  <<
-                       " entries written so far.");
-            }
-        }
-    }
-
-    /* Flush */
-    for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
-        dynamic_cast<SwapDir *>(INDEXSD(dirn))->writeCleanDone();
-
-    if (reopen)
-        storeDirOpenSwapLogs();
-
-    getCurrentTime();
-
-    dt = tvSubDsec(start, current_time);
-
-    debugs(20, DBG_IMPORTANT, "  Finished.  Wrote " << n << " entries.");
-    debugs(20, DBG_IMPORTANT, "  Took "<< std::setw(3)<< std::setprecision(2) << dt <<
-           " seconds ("<< std::setw(6) << ((double) n / (dt > 0.0 ? dt : 1.0)) << " entries/sec).");
-
-    return n;
-}
-
-StoreSearch *
-StoreController::search(String const url, HttpRequest *request)
-{
-    /* cheat, for now you can't search the memory hot cache */
-    return swapDir->search(url, request);
-}
-
-StorePointer
-StoreHashIndex::store(int const x) const
-{
-    return INDEXSD(x);
-}
-
-SwapDir &
-StoreHashIndex::dir(const int i) const
-{
-    SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(i));
-    assert(sd);
-    return *sd;
-}
-
-void
-StoreController::sync(void)
-{
-    if (memStore)
-        memStore->sync();
-    swapDir->sync();
-}
-
-/*
- * handle callbacks all avaliable fs'es
- */
-int
-StoreController::callback()
-{
-    /* This will likely double count. Thats ok. */
-    PROF_start(storeDirCallback);
-
-    /* mem cache callbacks ? */
-    int result = swapDir->callback();
-
-    PROF_stop(storeDirCallback);
-
-    return result;
-}
-
-int
-storeDirGetBlkSize(const char *path, int *blksize)
-{
-    struct statvfs sfs;
-
-    if (xstatvfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
-        *blksize = 2048;
-        return 1;
-    }
-
-    *blksize = (int) sfs.f_frsize;
-
-    // Sanity check; make sure we have a meaningful value.
-    if (*blksize < 512)
-        *blksize = 2048;
-
-    return 0;
-}
-
-#define fsbtoblk(num, fsbs, bs) \
-    (((fsbs) != 0 && (fsbs) < (bs)) ? \
-            (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
-int
-storeDirGetUFSStats(const char *path, int *totl_kb, int *free_kb, int *totl_in, int *free_in)
-{
-    struct statvfs sfs;
-
-    if (xstatvfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
-        return 1;
-    }
-
-    *totl_kb = (int) fsbtoblk(sfs.f_blocks, sfs.f_frsize, 1024);
-    *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_frsize, 1024);
-    *totl_in = (int) sfs.f_files;
-    *free_in = (int) sfs.f_ffree;
-    return 0;
-}
-
-void
-allocate_new_swapdir(SquidConfig::_cacheSwap * swap)
-{
-    if (swap->swapDirs == NULL) {
-        swap->n_allocated = 4;
-        swap->swapDirs = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
-    }
-
-    if (swap->n_allocated == swap->n_configured) {
-        swap->n_allocated <<= 1;
-        SwapDir::Pointer *const tmp = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
-        memcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
-        xfree(swap->swapDirs);
-        swap->swapDirs = tmp;
-    }
-}
-
-void
-free_cachedir(SquidConfig::_cacheSwap * swap)
-{
-    int i;
-    /* DON'T FREE THESE FOR RECONFIGURE */
-
-    if (reconfiguring)
-        return;
-
-    for (i = 0; i < swap->n_configured; ++i) {
-        /* TODO XXX this lets the swapdir free resources asynchronously
-        * swap->swapDirs[i]->deactivate();
-        * but there may be such a means already.
-        * RBC 20041225
-        */
-        swap->swapDirs[i] = NULL;
-    }
-
-    safe_free(swap->swapDirs);
-    swap->swapDirs = NULL;
-    swap->n_allocated = 0;
-    swap->n_configured = 0;
-}
-
-/* this should be a virtual method on StoreEntry,
- * i.e. e->referenced()
- * so that the entry can notify the creating Store
- */
-void
-StoreController::reference(StoreEntry &e)
-{
-    // special entries do not belong to any specific Store, but are IN_MEMORY
-    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
-        return;
-
-    /* Notify the fs that we're referencing this object again */
-
-    if (e.swap_dirn > -1)
-        swapDir->reference(e);
-
-    // Notify the memory cache that we're referencing this object again
-    if (memStore && e.mem_status == IN_MEMORY)
-        memStore->reference(e);
-
-    // TODO: move this code to a non-shared memory cache class when we have it
-    if (e.mem_obj) {
-        if (mem_policy->Referenced)
-            mem_policy->Referenced(mem_policy, &e, &e.mem_obj->repl);
-    }
-}
-
-bool
-StoreController::dereference(StoreEntry &e, bool wantsLocalMemory)
-{
-    // special entries do not belong to any specific Store, but are IN_MEMORY
-    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
-        return true;
-
-    bool keepInStoreTable = false; // keep only if somebody needs it there
-
-    /* Notify the fs that we're not referencing this object any more */
-
-    if (e.swap_filen > -1)
-        keepInStoreTable = swapDir->dereference(e, wantsLocalMemory) || keepInStoreTable;
-
-    // Notify the memory cache that we're not referencing this object any more
-    if (memStore && e.mem_status == IN_MEMORY)
-        keepInStoreTable = memStore->dereference(e, wantsLocalMemory) || keepInStoreTable;
-
-    // TODO: move this code to a non-shared memory cache class when we have it
-    if (e.mem_obj) {
-        if (mem_policy->Dereferenced)
-            mem_policy->Dereferenced(mem_policy, &e, &e.mem_obj->repl);
-        // non-shared memory cache relies on store_table
-        if (!memStore)
-            keepInStoreTable = wantsLocalMemory || keepInStoreTable;
-    }
-
-    return keepInStoreTable;
-}
-
-StoreEntry *
-StoreController::get(const cache_key *key)
-{
-    if (StoreEntry *e = find(key)) {
-        // this is not very precise: some get()s are not initiated by clients
-        e->touch();
-        return e;
-    }
-    return NULL;
-}
-
-/// Internal method to implements the guts of the Store::get() API:
-/// returns an in-transit or cached object with a given key, if any.
-StoreEntry *
-StoreController::find(const cache_key *key)
-{
-    if (StoreEntry *e = swapDir->get(key)) {
-        // TODO: ignore and maybe handleIdleEntry() unlocked intransit entries
-        // because their backing store slot may be gone already.
-        debugs(20, 3, HERE << "got in-transit entry: " << *e);
-        return e;
-    }
-
-    // Must search transients before caches because we must sync those we find.
-    if (transients) {
-        if (StoreEntry *e = transients->get(key)) {
-            debugs(20, 3, "got shared in-transit entry: " << *e);
-            bool inSync = false;
-            const bool found = anchorCollapsed(*e, inSync);
-            if (!found || inSync)
-                return e;
-            assert(!e->locked()); // ensure release will destroyStoreEntry()
-            e->release(); // do not let others into the same trap
-            return NULL;
-        }
-    }
-
-    if (memStore) {
-        if (StoreEntry *e = memStore->get(key)) {
-            debugs(20, 3, HERE << "got mem-cached entry: " << *e);
-            return e;
-        }
-    }
-
-    // TODO: this disk iteration is misplaced; move to StoreHashIndex when
-    // the global store_table is no longer used for in-transit objects.
-    if (const int cacheDirs = Config.cacheSwap.n_configured) {
-        // ask each cache_dir until the entry is found; use static starting
-        // point to avoid asking the same subset of disks more often
-        // TODO: coordinate with put() to be able to guess the right disk often
-        static int idx = 0;
-        for (int n = 0; n < cacheDirs; ++n) {
-            idx = (idx + 1) % cacheDirs;
-            SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
-            if (!sd->active())
-                continue;
-
-            if (StoreEntry *e = sd->get(key)) {
-                debugs(20, 3, HERE << "cache_dir " << idx <<
-                       " got cached entry: " << *e);
-                return e;
-            }
-        }
-    }
-
-    debugs(20, 4, HERE << "none of " << Config.cacheSwap.n_configured <<
-           " cache_dirs have " << storeKeyText(key));
-    return NULL;
-}
-
-void
-StoreController::get(String const, STOREGETCLIENT, void *)
-{
-    fatal("not implemented");
-}
-
-/// updates the collapsed entry with the corresponding on-disk entry, if any
-/// In other words, the SwapDir::anchorCollapsed() API applied to all disks.
-bool
-StoreController::anchorCollapsedOnDisk(StoreEntry &collapsed, bool &inSync)
-{
-    // TODO: move this loop to StoreHashIndex, just like the one in get().
-    if (const int cacheDirs = Config.cacheSwap.n_configured) {
-        // ask each cache_dir until the entry is found; use static starting
-        // point to avoid asking the same subset of disks more often
-        // TODO: coordinate with put() to be able to guess the right disk often
-        static int idx = 0;
-        for (int n = 0; n < cacheDirs; ++n) {
-            idx = (idx + 1) % cacheDirs;
-            SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
-            if (!sd->active())
-                continue;
-
-            if (sd->anchorCollapsed(collapsed, inSync)) {
-                debugs(20, 3, "cache_dir " << idx << " anchors " << collapsed);
-                return true;
-            }
-        }
-    }
-
-    debugs(20, 4, "none of " << Config.cacheSwap.n_configured <<
-           " cache_dirs have " << collapsed);
-    return false;
-}
-
-void StoreController::markForUnlink(StoreEntry &e)
-{
-    if (transients && e.mem_obj && e.mem_obj->xitTable.index >= 0)
-        transients->markForUnlink(e);
-    if (memStore && e.mem_obj && e.mem_obj->memCache.index >= 0)
-        memStore->markForUnlink(e);
-    if (e.swap_filen >= 0)
-        e.store()->markForUnlink(e);
-}
-
-// move this into [non-shared] memory cache class when we have one
-/// whether e should be kept in local RAM for possible future caching
-bool
-StoreController::keepForLocalMemoryCache(StoreEntry &e) const
-{
-    if (!e.memoryCachable())
-        return false;
-
-    // does the current and expected size obey memory caching limits?
-    assert(e.mem_obj);
-    const int64_t loadedSize = e.mem_obj->endOffset();
-    const int64_t expectedSize = e.mem_obj->expectedReplySize(); // may be < 0
-    const int64_t ramSize = max(loadedSize, expectedSize);
-    const int64_t ramLimit = min(
-                                 static_cast<int64_t>(Config.memMaxSize),
-                                 static_cast<int64_t>(Config.Store.maxInMemObjSize));
-    return ramSize <= ramLimit;
-}
-
-void
-StoreController::memoryOut(StoreEntry &e, const bool preserveSwappable)
-{
-    bool keepInLocalMemory = false;
-    if (memStore)
-        memStore->write(e); // leave keepInLocalMemory false
-    else
-        keepInLocalMemory = keepForLocalMemoryCache(e);
-
-    debugs(20, 7, HERE << "keepInLocalMemory: " << keepInLocalMemory);
-
-    if (!keepInLocalMemory)
-        e.trimMemory(preserveSwappable);
-}
-
-void
-StoreController::memoryUnlink(StoreEntry &e)
-{
-    if (memStore)
-        memStore->unlink(e);
-    else // TODO: move into [non-shared] memory cache class when we have one
-        e.destroyMemObject();
-}
-
-void
-StoreController::memoryDisconnect(StoreEntry &e)
-{
-    if (memStore)
-        memStore->disconnect(e);
-    // else nothing to do for non-shared memory cache
-}
-
-void
-StoreController::transientsAbandon(StoreEntry &e)
-{
-    if (transients) {
-        assert(e.mem_obj);
-        if (e.mem_obj->xitTable.index >= 0)
-            transients->abandon(e);
-    }
-}
-
-void
-StoreController::transientsCompleteWriting(StoreEntry &e)
-{
-    if (transients) {
-        assert(e.mem_obj);
-        if (e.mem_obj->xitTable.index >= 0)
-            transients->completeWriting(e);
-    }
-}
-
-int
-StoreController::transientReaders(const StoreEntry &e) const
-{
-    return (transients && e.mem_obj && e.mem_obj->xitTable.index >= 0) ?
-           transients->readers(e) : 0;
-}
-
-void
-StoreController::transientsDisconnect(MemObject &mem_obj)
-{
-    if (transients)
-        transients->disconnect(mem_obj);
-}
-
-void
-StoreController::handleIdleEntry(StoreEntry &e)
-{
-    bool keepInLocalMemory = false;
-
-    if (EBIT_TEST(e.flags, ENTRY_SPECIAL)) {
-        // Icons (and cache digests?) should stay in store_table until we
-        // have a dedicated storage for them (that would not purge them).
-        // They are not managed [well] by any specific Store handled below.
-        keepInLocalMemory = true;
-    } else if (memStore) {
-        // leave keepInLocalMemory false; memStore maintains its own cache
-    } else {
-        keepInLocalMemory = keepForLocalMemoryCache(e) && // in good shape and
-                            // the local memory cache is not overflowing
-                            (mem_node::InUseCount() <= store_pages_max);
-    }
-
-    // An idle, unlocked entry that only belongs to a SwapDir which controls
-    // its own index, should not stay in the global store_table.
-    if (!dereference(e, keepInLocalMemory)) {
-        debugs(20, 5, HERE << "destroying unlocked entry: " << &e << ' ' << e);
-        destroyStoreEntry(static_cast<hash_link*>(&e));
-        return;
-    }
-
-    debugs(20, 5, HERE << "keepInLocalMemory: " << keepInLocalMemory);
-
-    // TODO: move this into [non-shared] memory cache class when we have one
-    if (keepInLocalMemory) {
-        e.setMemStatus(IN_MEMORY);
-        e.mem_obj->unlinkRequest();
-    } else {
-        e.purgeMem(); // may free e
-    }
-}
-
-void
-StoreController::allowCollapsing(StoreEntry *e, const RequestFlags &reqFlags,
-                                 const HttpRequestMethod &reqMethod)
-{
-    e->makePublic(); // this is needed for both local and SMP collapsing
-    if (transients)
-        transients->startWriting(e, reqFlags, reqMethod);
-    debugs(20, 3, "may " << (transients && e->mem_obj->xitTable.index >= 0 ?
-                             "SMP-" : "locally-") << "collapse " << *e);
-}
-
-void
-StoreController::syncCollapsed(const sfileno xitIndex)
-{
-    assert(transients);
-
-    StoreEntry *collapsed = transients->findCollapsed(xitIndex);
-    if (!collapsed) { // the entry is no longer locally active, ignore update
-        debugs(20, 7, "not SMP-syncing not-transient " << xitIndex);
-        return;
-    }
-    assert(collapsed->mem_obj);
-    assert(collapsed->mem_obj->smpCollapsed);
-
-    debugs(20, 7, "syncing " << *collapsed);
-
-    bool abandoned = transients->abandoned(*collapsed);
-    bool found = false;
-    bool inSync = false;
-    if (memStore && collapsed->mem_obj->memCache.io == MemObject::ioDone) {
-        found = true;
-        inSync = true;
-        debugs(20, 7, "fully mem-loaded " << *collapsed);
-    } else if (memStore && collapsed->mem_obj->memCache.index >= 0) {
-        found = true;
-        inSync = memStore->updateCollapsed(*collapsed);
-    } else if (collapsed->swap_filen >= 0) {
-        found = true;
-        inSync = collapsed->store()->updateCollapsed(*collapsed);
-    } else {
-        found = anchorCollapsed(*collapsed, inSync);
-    }
-
-    if (abandoned && collapsed->store_status == STORE_PENDING) {
-        debugs(20, 3, "aborting abandoned but STORE_PENDING " << *collapsed);
-        collapsed->abort();
-        return;
-    }
-
-    if (inSync) {
-        debugs(20, 5, "synced " << *collapsed);
-        collapsed->invokeHandlers();
-    } else if (found) { // unrecoverable problem syncing this entry
-        debugs(20, 3, "aborting unsyncable " << *collapsed);
-        collapsed->abort();
-    } else { // the entry is still not in one of the caches
-        debugs(20, 7, "waiting " << *collapsed);
-    }
-}
-
-/// Called for in-transit entries that are not yet anchored to a cache.
-/// For cached entries, return true after synchronizing them with their cache
-/// (making inSync true on success). For not-yet-cached entries, return false.
-bool
-StoreController::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
-{
-    // this method is designed to work with collapsed transients only
-    assert(collapsed.mem_obj);
-    assert(collapsed.mem_obj->xitTable.index >= 0);
-    assert(collapsed.mem_obj->smpCollapsed);
-
-    debugs(20, 7, "anchoring " << collapsed);
-
-    bool found = false;
-    if (memStore)
-        found = memStore->anchorCollapsed(collapsed, inSync);
-    if (!found && Config.cacheSwap.n_configured)
-        found = anchorCollapsedOnDisk(collapsed, inSync);
-
-    if (found) {
-        if (inSync)
-            debugs(20, 7, "anchored " << collapsed);
-        else
-            debugs(20, 5, "failed to anchor " << collapsed);
-    } else {
-        debugs(20, 7, "skipping not yet cached " << collapsed);
-    }
-
-    return found;
-}
-
-StoreHashIndex::StoreHashIndex()
-{
-    if (store_table)
-        abort();
-    assert (store_table == NULL);
-}
-
-StoreHashIndex::~StoreHashIndex()
-{
-    if (store_table) {
-        hashFreeItems(store_table, destroyStoreEntry);
-        hashFreeMemory(store_table);
-        store_table = NULL;
-    }
-}
-
-int
-StoreHashIndex::callback()
-{
-    int result = 0;
-    int j;
-    static int ndir = 0;
-
-    do {
-        j = 0;
-
-        for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-            if (ndir >= Config.cacheSwap.n_configured)
-                ndir = ndir % Config.cacheSwap.n_configured;
-
-            int temp_result = store(ndir)->callback();
-
-            ++ndir;
-
-            j += temp_result;
-
-            result += temp_result;
-
-            if (j > 100)
-                fatal ("too much io\n");
-        }
-    } while (j > 0);
-
-    ++ndir;
-
-    return result;
-}
-
-void
-StoreHashIndex::create()
-{
-    if (Config.cacheSwap.n_configured == 0) {
-        debugs(0, DBG_PARSE_NOTE(DBG_CRITICAL), "No cache_dir stores are configured.");
-    }
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).active())
-            store(i)->create();
-    }
-}
-
-/* Lookup an object in the cache.
- * return just a reference to object, don't start swapping in yet. */
-StoreEntry *
-StoreHashIndex::get(const cache_key *key)
-{
-    PROF_start(storeGet);
-    debugs(20, 3, "storeGet: looking up " << storeKeyText(key));
-    StoreEntry *p = static_cast<StoreEntry *>(hash_lookup(store_table, key));
-    PROF_stop(storeGet);
-    return p;
-}
-
-void
-StoreHashIndex::get(String const, STOREGETCLIENT, void *)
-{
-    fatal("not implemented");
-}
-
-void
-StoreHashIndex::init()
-{
-    if (Config.Store.objectsPerBucket <= 0)
-        fatal("'store_objects_per_bucket' should be larger than 0.");
-
-    if (Config.Store.avgObjectSize <= 0)
-        fatal("'store_avg_object_size' should be larger than 0.");
-
-    /* Calculate size of hash table (maximum currently 64k buckets).  */
-    /* this is very bogus, its specific to the any Store maintaining an
-     * in-core index, not global */
-    size_t buckets = (Store::Root().maxSize() + Config.memMaxSize) / Config.Store.avgObjectSize;
-    debugs(20, DBG_IMPORTANT, "Swap maxSize " << (Store::Root().maxSize() >> 10) <<
-           " + " << ( Config.memMaxSize >> 10) << " KB, estimated " << buckets << " objects");
-    buckets /= Config.Store.objectsPerBucket;
-    debugs(20, DBG_IMPORTANT, "Target number of buckets: " << buckets);
-    /* ideally the full scan period should be configurable, for the
-     * moment it remains at approximately 24 hours.  */
-    store_hash_buckets = storeKeyHashBuckets(buckets);
-    debugs(20, DBG_IMPORTANT, "Using " << store_hash_buckets << " Store buckets");
-    debugs(20, DBG_IMPORTANT, "Max Mem  size: " << ( Config.memMaxSize >> 10) << " KB" <<
-           (Config.memShared ? " [shared]" : ""));
-    debugs(20, DBG_IMPORTANT, "Max Swap size: " << (Store::Root().maxSize() >> 10) << " KB");
-
-    store_table = hash_create(storeKeyHashCmp,
-                              store_hash_buckets, storeKeyHashHash);
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        /* this starts a search of the store dirs, loading their
-         * index. under the new Store api this should be
-         * driven by the StoreHashIndex, not by each store.
-        *
-        * That is, the HashIndex should perform a search of each dir it is
-        * indexing to do the hash insertions. The search is then able to
-        * decide 'from-memory', or 'from-clean-log' or 'from-dirty-log' or
-        * 'from-no-log'.
-        *
-         * Step 1: make the store rebuilds use a search internally
-        * Step 2: change the search logic to use the four modes described
-        *         above
-        * Step 3: have the hash index walk the searches itself.
-         */
-        if (dir(i).active())
-            store(i)->init();
-    }
-}
-
-uint64_t
-StoreHashIndex::maxSize() const
-{
-    uint64_t result = 0;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).doReportStat())
-            result += store(i)->maxSize();
-    }
-
-    return result;
-}
-
-uint64_t
-StoreHashIndex::minSize() const
-{
-    uint64_t result = 0;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).doReportStat())
-            result += store(i)->minSize();
-    }
-
-    return result;
-}
-
-uint64_t
-StoreHashIndex::currentSize() const
-{
-    uint64_t result = 0;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).doReportStat())
-            result += store(i)->currentSize();
-    }
-
-    return result;
-}
-
-uint64_t
-StoreHashIndex::currentCount() const
-{
-    uint64_t result = 0;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).doReportStat())
-            result += store(i)->currentCount();
-    }
-
-    return result;
-}
-
-int64_t
-StoreHashIndex::maxObjectSize() const
-{
-    int64_t result = -1;
-
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        if (dir(i).active() && store(i)->maxObjectSize() > result)
-            result = store(i)->maxObjectSize();
-    }
-
-    return result;
-}
-
-void
-StoreHashIndex::getStats(StoreInfoStats &stats) const
-{
-    // accumulate per-disk cache stats
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        StoreInfoStats dirStats;
-        store(i)->getStats(dirStats);
-        stats += dirStats;
-    }
-
-    // common to all disks
-    stats.swap.open_disk_fd = store_open_disk_fd;
-
-    // memory cache stats are collected in StoreController::getStats(), for now
-}
-
-void
-StoreHashIndex::stat(StoreEntry & output) const
-{
-    int i;
-
-    /* Now go through each store, calling its stat routine */
-
-    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        storeAppendPrintf(&output, "\n");
-        store(i)->stat(output);
-    }
-}
-
-void
-StoreHashIndex::reference(StoreEntry &e)
-{
-    e.store()->reference(e);
-}
-
-bool
-StoreHashIndex::dereference(StoreEntry &e, bool wantsLocalMemory)
-{
-    return e.store()->dereference(e, wantsLocalMemory);
-}
-
-void
-StoreHashIndex::maintain()
-{
-    int i;
-    /* walk each fs */
-
-    for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
-        /* XXX FixMe: This should be done "in parallell" on the different
-         * cache_dirs, not one at a time.
-         */
-        /* call the maintain function .. */
-        store(i)->maintain();
-    }
-}
-
-void
-StoreHashIndex::sync()
-{
-    for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
-        store(i)->sync();
-}
-
-StoreSearch *
-StoreHashIndex::search(String const url, HttpRequest *)
-{
-    if (url.size())
-        fatal ("Cannot search by url yet\n");
-
-    return new StoreSearchHashIndex (this);
-}
-
-CBDATA_CLASS_INIT(StoreSearchHashIndex);
-
-StoreSearchHashIndex::StoreSearchHashIndex(RefCount<StoreHashIndex> aSwapDir) :
-    sd(aSwapDir),
-    callback(NULL),
-    cbdata(NULL),
-    _done(false),
-    bucket(0)
-{}
-
-/* do not link
-StoreSearchHashIndex::StoreSearchHashIndex(StoreSearchHashIndex const &);
-*/
-
-StoreSearchHashIndex::~StoreSearchHashIndex()
-{}
-
-void
-StoreSearchHashIndex::next(void (aCallback)(void *), void *aCallbackData)
-{
-    next();
-    aCallback (aCallbackData);
-}
-
-bool
-StoreSearchHashIndex::next()
-{
-    if (!entries.empty())
-        entries.pop_back();
-
-    while (!isDone() && !entries.size())
-        copyBucket();
-
-    return currentItem() != NULL;
-}
-
-bool
-StoreSearchHashIndex::error() const
-{
-    return false;
-}
-
-bool
-StoreSearchHashIndex::isDone() const
-{
-    return bucket >= store_hash_buckets || _done;
-}
-
-StoreEntry *
-StoreSearchHashIndex::currentItem()
-{
-    if (!entries.size())
-        return NULL;
-
-    return entries.back();
-}
-
-void
-StoreSearchHashIndex::copyBucket()
-{
-    /* probably need to lock the store entries...
-     * we copy them all to prevent races on the links. */
-    debugs(47, 3, "StoreSearchHashIndex::copyBucket #" << bucket);
-    assert (!entries.size());
-    hash_link *link_ptr = NULL;
-    hash_link *link_next = NULL;
-    link_next = hash_get_bucket(store_table, bucket);
-
-    while (NULL != (link_ptr = link_next)) {
-        link_next = link_ptr->next;
-        StoreEntry *e = (StoreEntry *) link_ptr;
-
-        entries.push_back(e);
-    }
-
-    ++bucket;
-    debugs(47,3, "got entries: " << entries.size());
-}
-
index 10c6410c1cb41228b9ead9ce99f93e60821e4c01..17ce90433ff9f0b826437a3c9dc5fe23a4cbee01 100644 (file)
@@ -10,7 +10,8 @@
 #include "MemObject.h"
 #include "SquidConfig.h"
 #include "Store.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
 
 StoreIoStats store_io_stats;
 
@@ -60,7 +61,7 @@ StoreIOState::Pointer
 storeOpen(StoreEntry * e, StoreIOState::STFNCB * file_callback, StoreIOState::STIOCB * callback,
           void *callback_data)
 {
-    return dynamic_cast<SwapDir *>(e->store().getRaw())->openStoreIO(*e, file_callback, callback, callback_data);
+    return e->disk().openStoreIO(*e, file_callback, callback, callback_data);
 }
 
 void
index 6170314cd2bbdb53ce6016be26091e61f5044e35..5bcd04ed4e9024541a0ffd1c799c8fb20a2d1759 100644 (file)
 #define SQUID_STORE_KEY_MD5_H_
 
 #include "hash.h"
+#include "store/forward.h"
 
 class HttpRequestMethod;
 class HttpRequest;
 
-/* MD5 cache keys */
-typedef unsigned char cache_key;
-
 cache_key *storeKeyDup(const cache_key *);
 cache_key *storeKeyCopy(cache_key *, const cache_key *);
 void storeKeyFree(const cache_key *);
index 710d04470260ffb91dbe8c10a1a30dc7e2041e49..f1f179b99704732cb6c7fba42b0ba9d955894c9e 100644 (file)
 #include "SquidTime.h"
 #include "StatCounters.h"
 #include "Store.h"
+#include "store/Disk.h"
 #include "store_digest.h"
 #include "store_key_md5.h"
 #include "store_rebuild.h"
 #include "StoreSearch.h"
-#include "SwapDir.h"
 // for tvSubDsec() which should be in SquidTime.h
 #include "util.h"
 
@@ -56,7 +56,7 @@ storeCleanup(void *)
     static int seen = 0;
 
     if (currentSearch == NULL || currentSearch->isDone())
-        currentSearch = Store::Root().search(NULL, NULL);
+        currentSearch = Store::Root().search();
 
     size_t statCount = 500;
 
index 4bb54f7e4df011516e0751aea72f8a703f943851..2bfb75babc45f238c4bd878d50dd97d54cb14320 100644 (file)
 #include "MemObject.h"
 #include "SquidConfig.h"
 #include "StatCounters.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
 #include "store_log.h"
 #include "swap_log_op.h"
-#include "SwapDir.h"
 
 static void storeSwapOutStart(StoreEntry * e);
 static StoreIOState::STIOCB storeSwapOutFileClosed;
@@ -299,12 +300,12 @@ storeSwapOutFileClosed(void *data, int errflag, StoreIOState::Pointer self)
             /* FIXME: this should be handle by the link from store IO to
              * Store, rather than being a top level API call.
              */
-            e->store()->diskFull();
+            e->disk().diskFull();
             storeConfigure();
         }
 
         if (e->swap_filen >= 0)
-            e->unlink();
+            e->disk().unlink(*e);
 
         assert(e->swap_status == SWAPOUT_NONE);
 
@@ -319,7 +320,7 @@ storeSwapOutFileClosed(void *data, int errflag, StoreIOState::Pointer self)
 
         e->swap_file_sz = e->objectLen() + mem->swap_hdr_sz;
         e->swap_status = SWAPOUT_DONE;
-        e->store()->swappedOut(*e);
+        e->disk().swappedOut(*e);
 
         // XXX: For some Stores, it is pointless to re-check cachability here
         // and it leads to double counts in store_check_cachable_hist. We need
index 4660bf0182d7848855f75c267a928c35287d46a1..406266c40a21a32195f114ac26ed0f4071a0df3b 100644 (file)
 
 /** macro to stub a function which returns a reference to dynamic
  *  Aborts unit tests requiring its definition with a message about the missing linkage
- *  This macro uses 'new x' to construct a stack vailable for the reference, may leak.
- *  \param x may be the type to define or a constructor call with parameter values
+ *  \param x underlying or "referred to" type
  */
-#define STUB_RETREF(x) { stub_fatal(STUB_API " required"); return new x; }
+#define STUB_RETREF(x) { stub_fatal(STUB_API " required"); return *(x *)nullptr; }
 
-/** macro to stub a function which returns a reference to static
- *  Aborts unit tests requiring its definition with a message about the missing linkage
- *  This macro uses static variable definition to avoid leaks.
- *  \param x  the type name to define
- */
-#define STUB_RETSTATREF(x) { stub_fatal(STUB_API " required"); static x v; return v; }
+/** Same as STUB_RETREF(). TODO: Remove */
+#define STUB_RETSTATREF(x) STUB_RETREF(x)
 
 #endif /* STUB */
 
index 6e001d0c21eef490d5057eb6692309872512ae8d..5f92009311a1cb6b9d3e37e64c3ba92bf80f9ab3 100644 (file)
@@ -69,10 +69,3 @@ TestSwapDir::openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STI
 void
 TestSwapDir::parse(int, char*)
 {}
-
-StoreSearch *
-TestSwapDir::search(String, HttpRequest *)
-{
-    return NULL;
-}
-
index 00bdd7956095a707a7e6a4a8e5bb4902a831922b..0fc66373405dbc9bfcb7aae8c72e5c55ed61daa1 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef TEST_TESTSWAPDIR
 #define TEST_TESTSWAPDIR
 
-#include "SwapDir.h"
+#include "store/Disk.h"
 
 class TestSwapDir : public SwapDir
 {
@@ -19,20 +19,21 @@ public:
 
     bool statsCalled;
 
-    virtual uint64_t maxSize() const;
-    virtual uint64_t currentSize() const;
-    virtual uint64_t currentCount() const;
-    virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */
-    virtual void swappedOut(const StoreEntry &e) {}
-
-    virtual void reconfigure();
-    virtual void init();
-    virtual bool unlinkdUseful() const;
-    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
-    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
-    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
-    virtual void parse(int, char*);
-    virtual StoreSearch *search(String, HttpRequest *);
+    /* Store::Disk API */
+    virtual uint64_t maxSize() const override;
+    virtual uint64_t currentSize() const override;
+    virtual uint64_t currentCount() const override;
+    virtual void stat(StoreEntry &) const override;
+    virtual void swappedOut(const StoreEntry &e) override {}
+    virtual void reconfigure() override;
+    virtual void init() override;
+    virtual bool unlinkdUseful() const override;
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const override;
+    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) override;
+    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) override;
+    virtual void parse(int, char*) override;
+    virtual void markForUnlink(StoreEntry &) override {}
+    virtual void unlink(StoreEntry &) override {}
 };
 
 typedef RefCount<TestSwapDir> TestSwapDirPointer;
index 8c703b0f4dd5b5cd9499d0bce5966366e91b1f77..ca78f4693e91273f0fdb3723cd6b815df42a05ff 100644 (file)
@@ -24,19 +24,16 @@ void MemStore::disconnect(StoreEntry &e) STUB
 void MemStore::reference(StoreEntry &) STUB
 void MemStore::maintain() STUB
 void MemStore::noteFreeMapSlice(const Ipc::StoreMapSliceId) STUB
-void MemStore::get(String const, STOREGETCLIENT, void *) STUB
 void MemStore::init() STUB
 void MemStore::getStats(StoreInfoStats&) const STUB
 void MemStore::stat(StoreEntry &) const STUB
-int MemStore::callback() STUB_RETVAL(0)
 StoreEntry *MemStore::get(const cache_key *) STUB_RETVAL(NULL)
 uint64_t MemStore::maxSize() const STUB_RETVAL(0)
 uint64_t MemStore::minSize() const STUB_RETVAL(0)
 uint64_t MemStore::currentSize() const STUB_RETVAL(0)
 uint64_t MemStore::currentCount() const STUB_RETVAL(0)
 int64_t MemStore::maxObjectSize() const STUB_RETVAL(0)
-StoreSearch *MemStore::search(String const, HttpRequest *) STUB_RETVAL(NULL)
-bool MemStore::dereference(StoreEntry &, bool) STUB_RETVAL(false)
+bool MemStore::dereference(StoreEntry &) STUB_RETVAL(false)
 void MemStore::markForUnlink(StoreEntry&) STUB
 bool MemStore::anchorCollapsed(StoreEntry&, bool&) STUB_RETVAL(false)
 bool MemStore::updateCollapsed(StoreEntry&) STUB_RETVAL(false)
index e75130a9ac8fdafac8aba0a640c5236659807ae1..d7f309290abc0a544a6f3827a3f5915562501ea0 100644 (file)
@@ -7,9 +7,9 @@
  */
 
 #include "squid.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
 
-#define STUB_API "SwapDir.cc"
+#define STUB_API "store/Disk.cc"
 #include "tests/STUB.h"
 
 // SwapDir::SwapDir(char const *) STUB
@@ -17,7 +17,6 @@
 void SwapDir::create() STUB
 void SwapDir::dump(StoreEntry &) const STUB
 bool SwapDir::doubleCheck(StoreEntry &) STUB_RETVAL(false)
-void SwapDir::unlink(StoreEntry &) STUB
 void SwapDir::getStats(StoreInfoStats &) const STUB
 void SwapDir::stat(StoreEntry &) const STUB
 void SwapDir::statfs(StoreEntry &)const STUB
@@ -26,11 +25,9 @@ uint64_t SwapDir::minSize() const STUB_RETVAL(0)
 int64_t SwapDir::maxObjectSize() const STUB_RETVAL(0)
 void SwapDir::maxObjectSize(int64_t) STUB
 void SwapDir::reference(StoreEntry &) STUB
-bool SwapDir::dereference(StoreEntry &, bool) STUB_RETVAL(false)
-int SwapDir::callback() STUB_RETVAL(0)
+bool SwapDir::dereference(StoreEntry &) STUB_RETVAL(false)
 bool SwapDir::canStore(const StoreEntry &, int64_t, int &) const STUB_RETVAL(false)
 bool SwapDir::canLog(StoreEntry const &)const STUB_RETVAL(false)
-void SwapDir::sync() STUB
 void SwapDir::openLog() STUB
 void SwapDir::closeLog() STUB
 int SwapDir::writeCleanStart() STUB_RETVAL(0)
@@ -47,5 +44,4 @@ void SwapDir::optionReadOnlyDump(StoreEntry *) const STUB
 bool SwapDir::optionObjectSizeParse(char const *, const char *, int) STUB_RETVAL(false)
 void SwapDir::optionObjectSizeDump(StoreEntry *) const STUB
 StoreEntry * SwapDir::get(const cache_key *) STUB_RETVAL(NULL)
-void SwapDir::get(String const, STOREGETCLIENT , void *) STUB
 
index 352afde3131ba503716d05f2b7ca4c9ee045ad06..3111737e877ba1c7f8763f238ef84c08210c5415 100644 (file)
@@ -17,14 +17,10 @@ const char *pingStatusStr[] = { };
 const char *memStatusStr[] = { };
 const char *swapStatusStr[] = { };
 
-/* and code defined in the wrong .cc file */
-#include "SwapDir.h"
-void StoreController::maintain() STUB
 #include "RemovalPolicy.h"
 RemovalPolicy * createRemovalPolicy(RemovalPolicySettings * settings) STUB_RETVAL(NULL)
 
 #include "Store.h"
-StorePointer Store::CurrentRoot = NULL;
 StoreIoStats store_io_stats;
 bool StoreEntry::checkDeferRead(int fd) const STUB_RETVAL(false)
 const char *StoreEntry::getMD5Text() const STUB_RETVAL(NULL)
@@ -41,7 +37,6 @@ void StoreEntry::replaceHttpReply(HttpReply *, bool andStartWriting) STUB
 bool StoreEntry::mayStartSwapOut() STUB_RETVAL(false)
 void StoreEntry::trimMemory(const bool preserveSwappable) STUB
 void StoreEntry::abort() STUB
-void StoreEntry::unlink() STUB
 void StoreEntry::makePublic() STUB
 void StoreEntry::makePrivate() STUB
 void StoreEntry::setPublicKey() STUB
@@ -76,7 +71,7 @@ void StoreEntry::setNoDelay (bool const) STUB
 bool StoreEntry::modifiedSince(HttpRequest * request) const STUB_RETVAL(false)
 bool StoreEntry::hasIfMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
 bool StoreEntry::hasIfNoneMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
-RefCount<SwapDir> StoreEntry::store() const STUB_RETVAL(NULL)
+Store::Disk &StoreEntry::disk() const STUB_RETREF(Store::Disk)
 size_t StoreEntry::inUseCount() STUB_RETVAL(0)
 void StoreEntry::getPublicByRequestMethod(StoreClient * aClient, HttpRequest * request, const HttpRequestMethod& method) STUB
 void StoreEntry::getPublicByRequest(StoreClient * aClient, HttpRequest * request) STUB
@@ -102,14 +97,14 @@ void NullStoreEntry::operator delete(void *address) STUB
 // private virtual. Why is this linked from outside?
 const char *NullStoreEntry::getSerialisedMetaData() STUB_RETVAL(NULL)
 
-void Store::Root(Store *) STUB
-void Store::Root(RefCount<Store>) STUB
+Store::Controller &Store::Root() STUB_RETREF(Store::Controller)
+void Store::Init(Store::Controller *root) STUB
+void Store::FreeMemory() STUB
 void Store::Stats(StoreEntry * output) STUB
 void Store::Maintain(void *unused) STUB
-void Store::create() STUB
-void Store::diskFull() STUB
-void Store::sync() STUB
-void Store::unlink(StoreEntry &) STUB
+int Store::Controller::store_dirs_rebuilding = 0;
+StoreSearch *Store::Controller::search() STUB_RETVAL(NULL)
+void Store::Controller::maintain() STUB
 
 std::ostream &operator <<(std::ostream &os, const StoreEntry &)
 {
@@ -124,9 +119,7 @@ StoreEntry *storeGetPublicByRequest(HttpRequest * request) STUB_RETVAL(NULL)
 StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method) STUB_RETVAL(NULL)
 StoreEntry *storeCreateEntry(const char *, const char *, const RequestFlags &, const HttpRequestMethod&) STUB_RETVAL(NULL)
 StoreEntry *storeCreatePureEntry(const char *storeId, const char *logUrl, const RequestFlags &, const HttpRequestMethod&) STUB_RETVAL(NULL)
-void storeInit(void) STUB
 void storeConfigure(void) STUB
-void storeFreeMemory(void) STUB
 int expiresMoreThan(time_t, time_t) STUB_RETVAL(0)
 void storeAppendPrintf(StoreEntry *, const char *,...) STUB
 void storeAppendVPrintf(StoreEntry *, const char *, va_list ap) STUB
index 96d4568319e4e27f6f0b65b3db030deb6e17a219..e8da82424c01cbafe51bcedd81a0cbaa4d355418 100644 (file)
@@ -10,8 +10,8 @@
 
 #include "squid.h"
 #include "MemBuf.h"
+#include "store/Controller.h"
 #include "store_rebuild.h"
-#include "SwapDir.h"
 
 #include <cstring>
 
index 0ab3021771d1e58dbb098bf5f3b20a21da6a653b..bd55655a39eab0a8fbe52eae6854d54e61e0f65f 100644 (file)
@@ -13,7 +13,6 @@
 #include "MemObject.h"
 #include "Store.h"
 #include "StoreFileSystem.h"
-#include "SwapDir.h"
 #include "testDiskIO.h"
 #include "testStoreSupport.h"
 #include "unitTestMain.h"
index cd67e192c4c4e43d878de2ddfd53ee95fac4d7f9..7f3a480a3c6bf84223d28a65f619b52c4e9cec48 100644 (file)
@@ -31,8 +31,7 @@ void
 testPackableStream::testGetStream()
 {
     /* Setup a store root so we can create a StoreEntry */
-    StorePointer aStore (new TestStore);
-    Store::Root(aStore);
+    Store::Init();
 
     CapturingStoreEntry * anEntry = new CapturingStoreEntry();
     {
@@ -57,6 +56,6 @@ testPackableStream::testGetStream()
         CPPUNIT_ASSERT_EQUAL(String("12345677.7 some text   !."), anEntry->_appended_text);
     }
     delete anEntry; // does the unlock()
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
index 3e2c0ab33e57cd09416d169239229b2446f5f70c..f38a0835ed4a2418777ea93fca6557c9b50e67e2 100644 (file)
 #include "RequestFlags.h"
 #include "SquidConfig.h"
 #include "Store.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
 #include "StoreFileSystem.h"
 #include "StoreSearch.h"
-#include "SwapDir.h"
 #include "testRock.h"
 #include "testStoreSupport.h"
 #include "unitTestMain.h"
@@ -61,7 +62,7 @@ testRock::setUp()
     if (Ipc::Mem::Segment::BasePath == NULL)
         Ipc::Mem::Segment::BasePath = ".";
 
-    Store::Root(new StoreController);
+    Store::Init();
 
     store = new Rock::SwapDir();
 
@@ -94,7 +95,7 @@ testRock::tearDown()
 {
     CPPUNIT_NS::TestFixture::tearDown();
 
-    Store::Root(NULL);
+    Store::FreeMemory();
 
     store = NULL;
 
index 79b2694c6c30840865e1a48f9e2a28e6395759d3..a088640a3fbd4da3eac263d9aa23a335693464a1 100644 (file)
@@ -75,7 +75,7 @@ TestStore::stat(StoreEntry &) const
 }
 
 StoreSearch *
-TestStore::search(String const url, HttpRequest *)
+TestStore::search()
 {
     return NULL;
 }
@@ -83,41 +83,42 @@ TestStore::search(String const url, HttpRequest *)
 void
 testStore::testSetRoot()
 {
-    StorePointer aStore(new TestStore);
-    Store::Root(aStore);
+    Store::Controller *aStore(new TestStore);
+    Store::Init(aStore);
 
-    CPPUNIT_ASSERT_EQUAL(&Store::Root(),aStore.getRaw());
-    Store::Root(NULL);
+    CPPUNIT_ASSERT_EQUAL(&Store::Root(), aStore);
+    Store::FreeMemory();
 }
 
 void
 testStore::testUnsetRoot()
 {
-    StorePointer aStore(new TestStore);
-    StorePointer aStore2(new TestStore);
-    Store::Root(aStore);
-    Store::Root(aStore2);
-    CPPUNIT_ASSERT_EQUAL(&Store::Root(),aStore2.getRaw());
-    Store::Root(NULL);
+    Store::Controller *aStore(new TestStore);
+    Store::Controller *aStore2(new TestStore);
+    Store::Init(aStore);
+    Store::FreeMemory();
+    Store::Init(aStore2);
+    CPPUNIT_ASSERT_EQUAL(&Store::Root(),aStore2);
+    Store::FreeMemory();
 }
 
 void
 testStore::testStats()
 {
-    TestStorePointer aStore(new TestStore);
-    Store::Root(aStore.getRaw());
+    TestStore *aStore(new TestStore);
+    Store::Init(aStore);
     CPPUNIT_ASSERT_EQUAL(false, aStore->statsCalled);
     Store::Stats(NullStoreEntry::getInstance());
     CPPUNIT_ASSERT_EQUAL(true, aStore->statsCalled);
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
 void
 testStore::testMaxSize()
 {
-    StorePointer aStore(new TestStore);
-    Store::Root(aStore.getRaw());
+    Store::Controller *aStore(new TestStore);
+    Store::Init(aStore);
     CPPUNIT_ASSERT_EQUAL(static_cast<uint64_t>(3), aStore->maxSize());
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
index ffc48493257cba21aaeb20ce9eba655a019f2fbf..14014ff426877d0ee918d8c736107becbb5adfeb 100644 (file)
@@ -10,6 +10,7 @@
 #define SQUID_SRC_TEST_STORE_H
 
 #include "Store.h"
+#include "store/Controlled.h"
 
 #include <cppunit/extensions/HelperMacros.h>
 
@@ -35,11 +36,8 @@ protected:
     void testMaxSize();
 };
 
-/* subclass of Store to allow testing of methods without having all the
- * other components live
- */
-
-class TestStore : public Store
+/// allows testing of methods without having all the other components live
+class TestStore : public Store::Controller
 {
 
 public:
@@ -73,9 +71,9 @@ public:
 
     virtual void reference(StoreEntry &) {} /* Reference this object */
 
-    virtual bool dereference(StoreEntry &, bool) { return true; }
+    virtual bool dereference(StoreEntry &) { return true; }
 
-    virtual StoreSearch *search(String const url, HttpRequest *);
+    virtual StoreSearch *search();
 };
 
 typedef RefCount<TestStore> TestStorePointer;
index 5ea856489e81be1cbfadf6dcb5c5efc10cb609de..32433e3b82ee256f8f888ee049b13ab151b5824c 100644 (file)
@@ -11,8 +11,8 @@
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "Store.h"
+#include "store/Disks.h"
 #include "StoreSearch.h"
-#include "SwapDir.h"
 #include "testStoreController.h"
 #include "TestSwapDir.h"
 
@@ -29,12 +29,11 @@ addSwapDir(TestSwapDirPointer aStore)
 void
 testStoreController::testStats()
 {
+    Store::Init();
     StoreEntry *logEntry = new StoreEntry;
     logEntry->makeMemObject();
     logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod());
     logEntry->store_status = STORE_PENDING;
-    StorePointer aRoot (new StoreController);
-    Store::Root(aRoot);
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
@@ -45,7 +44,7 @@ testStoreController::testStats()
     free_cachedir(&Config.cacheSwap);
     CPPUNIT_ASSERT_EQUAL(true, aStore->statsCalled);
     CPPUNIT_ASSERT_EQUAL(true, aStore2->statsCalled);
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
 static void
@@ -75,20 +74,18 @@ testStoreController::testMaxSize()
     logEntry->makeMemObject();
     logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod());
     logEntry->store_status = STORE_PENDING;
-    StorePointer aRoot (new StoreController);
-    Store::Root(aRoot);
+    Store::Init();
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
     addSwapDir(aStore2);
     CPPUNIT_ASSERT_EQUAL(static_cast<uint64_t>(6), Store::Root().maxSize());
     free_cachedir(&Config.cacheSwap);
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
 static StoreEntry *
-addedEntry(StorePointer hashStore,
-           StorePointer aStore,
+addedEntry(Store::Disk *aStore,
            String name,
            String varySpec,
            String varyKey
@@ -103,7 +100,7 @@ addedEntry(StorePointer hashStore,
     e->swap_dirn = -1;
 
     for (int i=0; i < Config.cacheSwap.n_configured; ++i) {
-        if (INDEXSD (i) == aStore.getRaw())
+        if (INDEXSD(i) == aStore)
             e->swap_dirn = i;
     }
 
@@ -136,16 +133,15 @@ void
 testStoreController::testSearch()
 {
     commonInit();
-    StorePointer aRoot (new StoreController());
-    Store::Root(aRoot);
+    Store::Init();
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
     addSwapDir(aStore2);
     Store::Root().init();
-    StoreEntry * entry1 = addedEntry (&Store::Root(), aStore.getRaw(), "name", NULL, NULL);
-    StoreEntry * entry2 = addedEntry (&Store::Root(), aStore2.getRaw(), "name2", NULL, NULL);
-    StoreSearchPointer search = aRoot->search (NULL, NULL); /* search for everything in the store */
+    StoreEntry * entry1 = addedEntry(aStore.getRaw(), "name", NULL, NULL);
+    StoreEntry * entry2 = addedEntry(aStore2.getRaw(), "name2", NULL, NULL);
+    StoreSearchPointer search = Store::Root().search(); /* search for everything in the store */
 
     /* nothing should be immediately available */
     CPPUNIT_ASSERT_EQUAL(false, search->error());
@@ -190,6 +186,6 @@ testStoreController::testSearch()
     CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(NULL), search->currentItem());
     //CPPUNIT_ASSERT_EQUAL(false, search->next());
 
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
index 5e205ff1cdde77dcbe67f729dd4ea8bbcf387445..ca14beccaa3eb72fad804240ce922bc4fc7ec6eb 100644 (file)
@@ -11,9 +11,8 @@
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "Store.h"
-#include "StoreHashIndex.h"
+#include "store/Disks.h"
 #include "StoreSearch.h"
-#include "SwapDir.h"
 #include "testStoreHashIndex.h"
 #include "TestSwapDir.h"
 
@@ -34,8 +33,7 @@ testStoreHashIndex::testStats()
     logEntry->makeMemObject();
     logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod());
     logEntry->store_status = STORE_PENDING;
-    StorePointer aRoot (new StoreHashIndex());
-    Store::Root(aRoot);
+    Store::Init();
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
@@ -46,7 +44,7 @@ testStoreHashIndex::testStats()
     free_cachedir(&Config.cacheSwap);
     CPPUNIT_ASSERT_EQUAL(true, aStore->statsCalled);
     CPPUNIT_ASSERT_EQUAL(true, aStore2->statsCalled);
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
 void
@@ -56,20 +54,18 @@ testStoreHashIndex::testMaxSize()
     logEntry->makeMemObject();
     logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod());
     logEntry->store_status = STORE_PENDING;
-    StorePointer aRoot (new StoreHashIndex());
-    Store::Root(aRoot);
+    Store::Init();
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
     addSwapDir(aStore2);
     CPPUNIT_ASSERT_EQUAL(static_cast<uint64_t>(6), Store::Root().maxSize());
     free_cachedir(&Config.cacheSwap);
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
 StoreEntry *
-addedEntry(StorePointer hashStore,
-           StorePointer aStore,
+addedEntry(Store::Disk *aStore,
            String name,
            String varySpec,
            String varyKey
@@ -84,7 +80,7 @@ addedEntry(StorePointer hashStore,
     e->swap_dirn = -1;
 
     for (int i=0; i < Config.cacheSwap.n_configured; ++i) {
-        if (INDEXSD (i) == aStore.getRaw())
+        if (INDEXSD(i) == aStore)
             e->swap_dirn = i;
     }
 
@@ -133,16 +129,15 @@ void
 testStoreHashIndex::testSearch()
 {
     commonInit();
-    StorePointer aRoot (new StoreHashIndex());
-    Store::Root(aRoot);
+    Store::Init();
     TestSwapDirPointer aStore (new TestSwapDir);
     TestSwapDirPointer aStore2 (new TestSwapDir);
     addSwapDir(aStore);
     addSwapDir(aStore2);
     Store::Root().init();
-    StoreEntry * entry1 = addedEntry (&Store::Root(), aStore.getRaw(), "name", NULL, NULL);
-    StoreEntry * entry2 = addedEntry (&Store::Root(), aStore2.getRaw(), "name2", NULL, NULL);
-    StoreSearchPointer search = aRoot->search (NULL, NULL); /* search for everything in the store */
+    StoreEntry * entry1 = addedEntry(aStore.getRaw(), "name", NULL, NULL);
+    StoreEntry * entry2 = addedEntry(aStore2.getRaw(), "name2", NULL, NULL);
+    StoreSearchPointer search = Store::Root().search(); /* search for everything in the store */
 
     /* nothing should be immediately available */
     CPPUNIT_ASSERT_EQUAL(false, search->error());
@@ -187,6 +182,6 @@ testStoreHashIndex::testSearch()
     CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(NULL), search->currentItem());
     //CPPUNIT_ASSERT_EQUAL(false, search->next());
 
-    Store::Root(NULL);
+    Store::FreeMemory();
 }
 
index 3665531d4ecb723f8a57ba97f4bd0ae5114d7c18..97356a583128ce4006cbe8a8b6c9d717616f3550 100644 (file)
@@ -16,7 +16,7 @@
 #include "RequestFlags.h"
 #include "SquidConfig.h"
 #include "Store.h"
-#include "SwapDir.h"
+#include "store/Disks.h"
 #include "testStoreSupport.h"
 #include "testUfs.h"
 #include "unitTestMain.h"
 
 CPPUNIT_TEST_SUITE_REGISTRATION( testUfs );
 
-typedef RefCount<Fs::Ufs::UFSSwapDir> SwapDirPointer;
+typedef RefCount<Fs::Ufs::UFSSwapDir> MySwapDirPointer;
 extern REMOVALPOLICYCREATE createRemovalPolicy_lru; /* XXX fails with --enable-removal-policies=heap */
 
 static void
-addSwapDir(SwapDirPointer aStore)
+addSwapDir(MySwapDirPointer aStore)
 {
     allocate_new_swapdir(&Config.cacheSwap);
     Config.cacheSwap.swapDirs[Config.cacheSwap.n_configured] = aStore.getRaw();
@@ -92,9 +92,9 @@ testUfs::testUfsSearch()
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 
-    Store::Root(new StoreController);
+    Store::Init();
 
-    SwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
+    MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
 
     aStore->IO = new Fs::Ufs::UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
 
@@ -167,7 +167,7 @@ testUfs::testUfsSearch()
     /* here we cheat: we know that UFSSwapDirs search off disk. If we did an init call to a new
      * swapdir instance, we'd not be testing a clean build.
      */
-    StoreSearchPointer search = aStore->search (NULL, NULL); /* search for everything in the store */
+    StoreSearchPointer search = Store::Root().search(); /* search for everything in the store */
 
     /* nothing should be immediately available */
 #if 0
@@ -201,7 +201,7 @@ testUfs::testUfsSearch()
     CPPUNIT_ASSERT_EQUAL(true, search->isDone());
     CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(NULL), search->currentItem());
 
-    Store::Root(NULL);
+    Store::FreeMemory();
 
     free_cachedir(&Config.cacheSwap);
 
@@ -229,8 +229,8 @@ testUfs::testUfsDefaultEngine()
     // objects such as "StorePointer aRoot" from being called.
     CPPUNIT_ASSERT(!store_table); // or StoreHashIndex ctor will abort below
 
-    Store::Root(new StoreController);
-    SwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
+    Store::Init();
+    MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
     addSwapDir(aStore);
     commonInit();
     Config.replPolicy = new RemovalPolicySettings;
@@ -245,7 +245,7 @@ testUfs::testUfsDefaultEngine()
     safe_free(config_line);
     CPPUNIT_ASSERT(aStore->IO->io != NULL);
 
-    Store::Root(NULL);
+    Store::FreeMemory();
     free_cachedir(&Config.cacheSwap);
     safe_free(Config.replPolicy->type);
     delete Config.replPolicy;
index f8dc5412e07ddfdaa7eb541f38292c30f0c76808..72ad55beff9ea6e509eccab104f38bf3f29fbb2f 100644 (file)
 #include "anyp/PortCfg.h"
 #include "base/Subscription.h"
 #include "client_side.h"
-#include "disk.h"
+#include "fatal.h"
 #include "fde.h"
 #include "fqdncache.h"
+#include "fs_io.h"
 #include "htcp.h"
 #include "ICP.h"
 #include "ip/Intercept.h"
@@ -26,7 +27,7 @@
 #include "SquidConfig.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
-#include "SwapDir.h"
+#include "store/Disks.h"
 #include "tools.h"
 #include "wordlist.h"
 
index 55a7fdc08d8ce33c063d3c4b3320ab9a9ea8a53a..dd3427931041aa1664386134a5390a5c586d9d9c 100644 (file)
 #include "squid.h"
 
 #if USE_UNLINKD
-#include "disk.h"
 #include "fd.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
+#include "SquidConfig.h"
 #include "SquidIpc.h"
 #include "SquidTime.h"
 #include "StatCounters.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
 #include "tools.h"
 #include "xusleep.h"
 
index 01cc818b95bcfe17f8ea0f4c00f3730d689a3f9a..3c2bac142d0e430c2fa2affb9c4d9333ce1cf346 100644 (file)
@@ -21,8 +21,8 @@
 #include "ip/Address.h"
 #include "md5.h"
 #include "Parsing.h"
+#include "SquidConfig.h"
 #include "Store.h"
-#include "SwapDir.h"
 
 #if HAVE_NETDB_H
 #include <netdb.h>