+++ /dev/null
-#ifndef __BUFFERCACHE_H
-#define __BUFFERCACHE_H
-
-#include "include/buffer.h"
-#include "include/bufferlist.h"
-#include "include/lru.h"
-
-/** map<off_t, bufferptr> buffer_map;
-
-for writes:
-
-void map_or_alloc(size_t len, off_t off, bufferlist &blist);
-- build a bufferlist that includes bufferptr's for existing buffers
- in the map and (if necessary) newly allocated ones. caller can then use
-
- blist.copy_from(int off, int len, char *buf);
-
- to copy data into the bufferlist. (copy() copies data _out_, and append appends,
- but copy_from or copy_into or whatever doesn't exist yet.)
-
-
- for reads:
- void map_existing(size_t len, off_t off, map<off_t, bufferlist>& hits, map<off_t, size_t>& holes)
-
-- gives caller map of hits and holes.
-
-
-both of those could be wrapped up in a tidy class, aside from 2 things:
-
-- buffers need to be put in an lru of some sort with last_accessed etc.
- so we can flush them intelligently
-
-- maybe the buffers should be allocated w/ fixed size? for writes at least,
- the new buffers can always be created as 256k (or whatever) and the bufferptrs
- that reference them (in buffer_map) will point to the relevant substring.
- the map_or_alloc() bit just needs to be smart then to check the underlying
- buffer's alloc'd size and adjust those subsets as necessary.
-
- for reads, we'll be getting buffers of weird sizes coming from osds,
- so the cache should work with weird sized buffers regardless.
- (even if we always prefetch large blocks, files tails will come back small.)
-
-
- so somewhere in there there should be a buffer_head struct or something. maybe it shoudl be
-
- map<off_t, bufferhead> buffer_map;
-
- we can reuse the LRU (include/lru.h) thinger to handle lru stuff pretty easily.
- maybe
-
- class bufferhead : public LRUObject {
- bufferptr bptr;
- time_t last_written;
- int state; // clean, dirty, writing, reading
- };
-
-gets weird too if say multiple reads are issued on the same (or overlapping) ranges of bytes..
-only want to submit a single read request.
-
-s
-*/
-
-// bufferhead states
-#define BUFHD_STATE_CLEAN 1
-#define BUFHD_STATE_DIRTY 2
-#define BUFHD_STATE_WRITING 3
-#define BUFHD_STATE_READING 4
-
-class bufferhead : public LRUObject {
- bufferptr bptr;
- time_t last_written;
- int state;
-};
-
-class buffercache {
- private:
- map<off_t, bufferhead> buffer_map;
-
- map<off_t, bufferhead>::iterator overlap(size_t len, off_t off)
- {
- // returns iterator to buffer overlapping specified extent or end() if no overlap exists
- map<off_t, bufferhead>::iterator it = buffer_map.lower_bound(off);
- if (it == buffer_map.end() || (*it)->first < off + len) {
- return it;
- } else if (it == buffer_map.begin()) {
- return buffer_map.end();
- } else {
- --it;
- if ((*it)->first + (*it)->second.bptr.length() > off) {
- return it;
- } else {
- return buffer_map.end();
- }
- }
- }
-
- public:
- /* for writes
- build a bufferlist that includes bufferptr's for existing buffers
- in the map and (if necessary) newly allocated ones. caller can then use
-
- blist.copy_from(int off, int len, char *buf);
-
- to copy data into the bufferlist. (copy() copies data _out_, and append appends,
- but copy_from or copy_into or whatever doesn't exist yet.)
- */
- void map_or_alloc(size_t len, off_t off, bufferlist &blist)
- {
- }
-
- /* for reads
- gives caller maps of hits and holes
- */
- void map_existing(size_t len, off_t off, map<off_t, bufferhead>& hits, map<off_t, size_t>& holes)
- {
- off_t next_off = off;
- for (map<off_t, bufferhead>::iterator it = overlap(len, off);
- it != buffer_map.end() && (*it)->first < off + len;
- it++) {
- if ((*it)->first > next_off) {
- holes[next_off] = (size_t) ((*it)->first - next_off);
- }
- hits[(*it)->first] = (*it)->second;
- next_off = (*it)->first + (*it)->second.bptr.length();
- }
- if (next_off < off + len) {
- holes[next_off] = (size_t) (off + len - next_off);
- }
- }
-};
-
-#endif
-