00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _PIECE_H
00024 #define _PIECE_H
00025
00026 #include <map>
00027 #include <vector>
00028 #ifdef _WIN32
00029 #define MIN(a,b) (a<b)?a:b
00030 #endif
00031
00032 #define SLICE 16384
00033
00034
00035 class Session;
00036
00038
00039 class Piece
00040 {
00041 typedef std::map<size_t,size_t> slice_m;
00042 public:
00043 Piece(size_t nr,size_t piece_length);
00044 ~Piece();
00045
00046 size_t GetNumber() { return m_nr; }
00047 void Write(Session *,size_t offset, size_t length, unsigned char *);
00048 size_t NumberOfSlices() { return m_piece_length / SLICE; }
00049 size_t PieceLength() { return m_piece_length; }
00050 size_t SliceSize() { return SLICE; }
00051
00052 size_t Complete(size_t offset) { return m_complete[offset]; }
00053 void SetComplete(size_t offset,size_t length) { m_complete[offset] = length; }
00054 size_t Requested(size_t offset) { return m_requested[offset]; }
00055 void SetRequested(size_t offset,size_t length) {
00056 if (!length || length > m_requested[offset])
00057 m_requested[offset] = length;
00058 }
00059
00060 void ClearComplete();
00061 void ClearRequested();
00062
00063 bool GetRandomNotRequested(size_t& offset, size_t& length) {
00064 std::vector<size_t> available;
00065 for (size_t i = 0; i < m_piece_length; i += SLICE)
00066 {
00067 if (!Complete(i) && !Requested(i))
00068 {
00069 available.push_back(i);
00070 }
00071 }
00072 size_t q;
00073 if ((q = available.size()) > 0)
00074 {
00075 #ifdef _WIN32
00076 offset = available[rand() % q];
00077 #else
00078 offset = available[random() % q];
00079 #endif
00080 length = MIN(SLICE, m_piece_length - offset);
00081 return true;
00082 }
00083 return false;
00084 }
00085
00086 bool AllRequested() {
00087 for (size_t i = 0; i < m_piece_length; i += SLICE)
00088 {
00089 if (!Complete(i) && !Requested(i))
00090 {
00091 return false;
00092 }
00093 }
00094 return true;
00095 }
00096
00097 size_t NumberComplete() {
00098 size_t q = 0;
00099 for (size_t i = 0; i < m_piece_length; i += SLICE)
00100 {
00101 if (Complete(i))
00102 q++;
00103 }
00104 return q;
00105 }
00106 size_t NumberRequested() {
00107 size_t q = 0;
00108 for (size_t i = 0; i < m_piece_length; i += SLICE)
00109 {
00110 if (Requested(i) && !Complete(i))
00111 q++;
00112 }
00113 return q;
00114 }
00115 bool Complete() {
00116 for (size_t i = 0; i < m_piece_length; i += SLICE)
00117 {
00118 if (!Complete(i))
00119 {
00120 return false;
00121 }
00122 }
00123 return true;
00124 }
00125
00126 void save_slice_m(FILE *,slice_m& );
00127 void load_slice_m(FILE *,slice_m& );
00128 slice_m& MapComplete() { return m_complete; }
00129 slice_m& MapRequested() { return m_requested; }
00130
00131 private:
00132 Piece(const Piece& ) {}
00133 Piece& operator=(const Piece& ) { return *this; }
00134
00135 size_t m_nr;
00136 size_t m_piece_length;
00137 slice_m m_complete;
00138 slice_m m_requested;
00139 };
00140
00141
00142
00143
00144 #endif // _PIECE_H