mem_obj->setNoDelay(newValue);
}
+// XXX: Type names mislead. STORE_DISK_CLIENT actually means that we should
+// open swapin file, aggressively trim memory, and ignore read-ahead gap.
+// It does not mean we will read from disk exclusively (or at all!).
+// XXX: May create STORE_DISK_CLIENT with no disk caching configured.
+// XXX: Collapsed clients cannot predict their type.
store_client_t
StoreEntry::storeClientType() const
{
if (swap_status == SWAPOUT_DONE) {
debugs(20,7, HERE << mem_obj << " lo: " << mem_obj->inmem_lo << " hi: " << mem_obj->endOffset() << " size: " << mem_obj->object_sz);
if (mem_obj->endOffset() == mem_obj->object_sz) {
- /* hot object fully swapped in */
+ /* hot object fully swapped in (XXX: or swapped out?) */
return STORE_MEM_CLIENT;
}
} else {
anEntry->unlock("store_client::copy");
}
-/*
- * This function is used below to decide if we have any more data to
- * send to the client. If the store_status is STORE_PENDING, then we
- * do have more data to send. If its STORE_OK, then
- * we continue checking. If the object length is negative, then we
- * don't know the real length and must open the swap file to find out.
- * However, if there is no swap file, then there is no more to send.
- * If the length is >= 0, then we compare it to the requested copy
- * offset.
- */
-static int
-storeClientNoMoreToSend(StoreEntry * e, store_client * sc)
+/// Whether there is (or will be) more entry data for us.
+bool
+store_client::moreToSend() const
{
- int64_t len;
+ if (entry->store_status == STORE_PENDING)
+ return true; // there may be more coming
- if (e->store_status == STORE_PENDING)
- return 0;
+ /* STORE_OK, including aborted entries: no more data is coming */
- if ((len = e->objectLen()) < 0)
- return e->swap_filen < 0;
+ const int64_t len = entry->objectLen();
- if (sc->copyInto.offset < len)
- return 0;
+ // If we do not know the entry length, then we have to open the swap file,
+ // which is only possible if there is one AND if we are allowed to use it.
+ const bool canSwapIn = entry->swap_filen >= 0 &&
+ getType() == STORE_DISK_CLIENT;
+ if (len < 0)
+ return canSwapIn;
- return 1;
+ if (copyInto.offset >= len)
+ return false; // sent everything there is
+
+ if (canSwapIn)
+ return true; // if we lack prefix, we can swap it in
+
+ // If we cannot swap in, make sure we have what we want in RAM. Otherwise,
+ // scheduleRead calls scheduleDiskRead which asserts on STORE_MEM_CLIENTs.
+ const MemObject *mem = entry->mem_obj;
+ return mem &&
+ mem->inmem_lo <= copyInto.offset && copyInto.offset < mem->endOffset();
}
static void
copyInto.offset << ", hi: " <<
mem->endOffset());
- if (storeClientNoMoreToSend(entry, this)) {
+ if (!moreToSend()) {
/* There is no more to send! */
debugs(33, 3, HERE << "There is no more to send!");
callback(0);