annotate src/lib/file-cache.c @ 2868:316756b50150 HEAD

Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
author Timo Sirainen <tss@iki.fi>
date Mon, 08 Nov 2004 03:02:52 +0200
parents bf1e718e7370
children d1780331ad04
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2866
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (c) 2004 Timo Sirainen */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "buffer.h"
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "mmap-util.h"
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "file-cache.h"
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include <sys/stat.h>
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 struct file_cache {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 int fd;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 buffer_t *page_bitmask;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 void *mmap_base;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 size_t mmap_length;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 size_t read_highwater;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 };
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 struct file_cache *file_cache_new(int fd)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 struct file_cache *cache;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 cache = i_new(struct file_cache, 1);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 cache->fd = fd;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 cache->page_bitmask = buffer_create_dynamic(default_pool, 128);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 return cache;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 void file_cache_free(struct file_cache *cache)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 if (cache->mmap_base != NULL) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 if (munmap_anon(cache->mmap_base, cache->mmap_length) < 0)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 i_error("munmap_anon() failed: %m");
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 buffer_free(cache->page_bitmask);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 i_free(cache);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 void file_cache_set_fd(struct file_cache *cache, int fd)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 cache->fd = fd;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 file_cache_invalidate(cache, 0, cache->mmap_length);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 ssize_t file_cache_read(struct file_cache *cache, uoff_t offset, size_t size)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 size_t page_size = mmap_get_page_size();
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 size_t poffset, psize, mmap_needed, dest_offset, dest_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 unsigned char *bits, *dest;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 ssize_t ret;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 i_assert(size < INT_MAX);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 if (offset + size > cache->mmap_length &&
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 offset + size - cache->mmap_length > 1024*1024) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 /* growing more than a megabyte, make sure that the
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 file is large enough so we don't allocate memory
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 more than needed */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 struct stat st;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 if (fstat(cache->fd, &st) < 0) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 i_error("fstat(file_cache) failed: %m");
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 return -1;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 if (offset + size > (uoff_t)st.st_size) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 if (offset >= (uoff_t)st.st_size)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 return 0;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 size = (uoff_t)st.st_size - offset;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 poffset = offset / page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 psize = (offset + size + page_size-1) / page_size - poffset;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 i_assert(psize > 0);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 mmap_needed = (poffset + psize) * page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 if (mmap_needed > cache->mmap_length) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 /* grow mmaping */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 if (cache->mmap_base == NULL) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 cache->mmap_base = mmap_anon(mmap_needed);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 if (cache->mmap_base == MAP_FAILED) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 i_error("mmap_anon(%"PRIuSIZE_T") failed: %m",
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 mmap_needed);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 return -1;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 } else {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 cache->mmap_base = mremap_anon(cache->mmap_base,
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 cache->mmap_length,
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 mmap_needed,
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 MREMAP_MAYMOVE);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 if (cache->mmap_base == MAP_FAILED) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 i_error("mremap_anon(%"PRIuSIZE_T") failed: %m",
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 mmap_needed);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 return -1;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 cache->mmap_length = mmap_needed;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 bits = buffer_get_space_unsafe(cache->page_bitmask, poffset / CHAR_BIT,
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 (psize + CHAR_BIT - 1) / CHAR_BIT);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 dest_offset = poffset * page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 dest = PTR_OFFSET(cache->mmap_base, dest_offset);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 dest_size = page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 poffset %= CHAR_BIT;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 while (psize > 0) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 if (bits[poffset / CHAR_BIT] & (1 << (poffset % CHAR_BIT))) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 /* page is already in cache */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 psize--; poffset++;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 dest += page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 dest_offset += page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 continue;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 ret = pread(cache->fd, dest, dest_size, dest_offset);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 if (ret <= 0) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 if (ret < 0)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 return -1;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 /* EOF */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 /* FIXME: we should mark the last block cached and
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 invalidate it only when trying to read past the
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 file */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 return dest_offset <= offset ? 0 :
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 dest_offset - offset < size ?
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 dest_offset - offset : size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 dest += ret;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 dest_offset += ret;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 if (cache->read_highwater < dest_offset)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 cache->read_highwater = dest_offset;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 if ((size_t)ret != dest_size) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 /* partial read - probably EOF but make sure. */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 dest_size -= ret;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 continue;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 bits[poffset / CHAR_BIT] |= 1 << (poffset % CHAR_BIT);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 dest_size = page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 psize--; poffset++;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 return size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 const void *file_cache_get_map(struct file_cache *cache, size_t *size_r)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 *size_r = cache->read_highwater;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 return cache->mmap_base;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 void file_cache_invalidate(struct file_cache *cache, uoff_t offset, size_t size)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160 size_t page_size = mmap_get_page_size();
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 unsigned char *bits, mask;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 unsigned int i;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 if (offset >= cache->read_highwater)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 return;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 if (size > cache->read_highwater - offset)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 size = cache->read_highwater - offset;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 size = (offset + size + page_size-1) / page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 offset /= page_size;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 size -= offset;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173
2868
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
174 if (size != 1) {
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
175 /* tell operating system that we don't need the memory anymore
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
176 and it may free it. don't bother to do it for single pages,
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
177 there's a good chance that they get re-read back
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
178 immediately. */
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
179 (void)madvise(PTR_OFFSET(cache->mmap_base, offset * page_size),
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
180 size * page_size, MADV_DONTNEED);
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
181 }
316756b50150 Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents: 2866
diff changeset
182
2866
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 bits = buffer_get_space_unsafe(cache->page_bitmask, offset / CHAR_BIT,
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 (size + CHAR_BIT - 1) / CHAR_BIT);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 /* set the first byte */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187 for (i = offset % CHAR_BIT, mask = 0; i < CHAR_BIT && size > 0; i++) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 mask |= 1 << i;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
189 size--;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 *bits++ &= ~mask;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 /* set the middle bytes */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 memset(bits, 0, size / CHAR_BIT);
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 bits += size / CHAR_BIT;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 size %= CHAR_BIT;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 /* set the last byte */
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 if (size > 0) {
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 mask = 0;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 for (i = 0, mask = 0; i < size; i++)
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 mask |= 1 << i;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 *bits &= ~mask;
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 }
bf1e718e7370 Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 }