123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include <map>
- #include "AutoLock.h"
- #include <bfc/platform/types.h>
- class ProgressTracker
- {
- public:
- static const uint64_t null_position;
- ProgressTracker()
- {
- current_position=0;
- current_chunk=0;
- chunks[0]=0;
- chunks[null_position]=null_position;
- };
- void Write(uint64_t bytes_written)
- {
- Nullsoft::Utility::AutoLock list_lock(list_guard);
- ChunkList::iterator next, itr = chunks.find(current_chunk);
- current_position += bytes_written;
- if (itr->second < current_position)
- itr->second = current_position;
- for (;;)
- {
- next = itr;
- ++next;
- if (next != chunks.end() && (next->first <= itr->second))
- {
- itr->second = next->second;
- chunks.erase(next);
- }
- else
- break;
- }
- }
- bool Valid(uint64_t requested_position, uint64_t requested_end)
- {
- Nullsoft::Utility::AutoLock list_lock(list_guard);
- for (ChunkList::iterator itr=chunks.begin();itr!=chunks.end();itr++)
- {
- if (requested_position >= itr->first)
- {
- if (requested_position < itr->second)
- {
- if (requested_end <= itr->second)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- }
- return false;
- }
- bool Seek(uint64_t requested_position, uint64_t requested_end, uint64_t *new_start, uint64_t *new_end)
- {
- Nullsoft::Utility::AutoLock list_lock(list_guard);
- uint64_t last_good_start=0;
- ChunkList::iterator itr;
- for (itr=chunks.begin();itr!=chunks.end();itr++)
- {
- if (requested_position >= itr->first)
- {
- current_chunk = itr->first;
- if (requested_position <= itr->second)
- {
- ChunkList::iterator next = itr;
- ++next;
- *new_end = next->first;
- *new_start = current_position = itr->second;
- if (requested_end <= itr->second)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- last_good_start = itr->second;
- }
- }
- }
- if (last_good_start > requested_position)
- *new_start = current_position = last_good_start;
- else
- {
-
- *new_start = current_chunk = current_position = requested_position;
- chunks[current_chunk] = current_chunk;
- }
- *new_end = null_position;
- return false;
- }
- #if 0
- void Dump()
- {
- ChunkList::iterator itr;
- for (itr=chunks.begin();itr!=chunks.end();itr++)
- {
- printf("%I64u - %I64u\n", itr->first, itr->second);
- }
- }
- #endif
- typedef std::map<uint64_t, uint64_t> ChunkList;
- ChunkList chunks;
- uint64_t current_chunk;
- uint64_t current_position;
- Nullsoft::Utility::LockGuard list_guard;
- };
- const uint64_t ProgressTracker::null_position = (uint64_t)-1;
|