Back

dataCache.cpp coverage

overall coverage: 100.0%

line# code(run#)
1 #ifndef NO_MEMTRACE
2 #include "memtrace.h"
3 #endif
4
5 #include "myString.h"
6
7 String::DataCache::DataCache(String &s) : string(s), dataBlock(s.startBlock) {}(305)
8
9 String::DataCache::DataCache(const DataCache &c) = default;
10
11 char &String::DataCache::getChar(size_t idx)(803)
12 {
13 if (idx >= string.size) // throw error if index is out of range(803)
14 throw std::out_of_range("indexing error");(28)
15
16 size_t dbi = idx / 20; // index off the DataBlock of the requested character(775)
17 size_t lastDataBlcokIndex = string.size / 20; // index of the last DataBlock (based on size of string)(775)
18 unsigned char offset = idx % 20; // offset of character inside of string(775)
19 if (dbi == dataBlockIndex) // if the requested character is in the ceched block(775)
20 return dataBlock->data[offset]; // return character from the cache block(536)
21 if (dbi == 0) // is the requested character is in the first blokc(239)
22 return string.startBlock->data[offset]; // return character from the first block(87)
23 if (dbi == lastDataBlcokIndex) // if the requested character is in the last block(152)
24 return string.endBlock->data[offset]; // return it from the last block(126)
25
26 // At this point we have to move in the linked list to find the desired character
27 // So here are the distances we have to move
28 size_t distStart = dbi; // steps from the first block(26)
29 size_t distCache = dbi > dataBlockIndex ? dbi - dataBlockIndex : dataBlockIndex - dbi; // steps from the cached block(26)
30 // ^^has to check which side of the cached block the requested blokc is on
31 size_t distEnd = lastDataBlcokIndex - dbi; // distance from the end(26)
32
33 if (dbi < dataBlockIndex) // requested block is before the cached block(26)
34 {
35 if (distStart <= distCache) // requested blokc is closer (or the same distance) to the start block(6)
36 {
37 dataBlockIndex = 0; // move from the start block until the indexes match(5)
38 dataBlock = string.startBlock;(5)
39 while (dataBlockIndex != dbi)(10)
40 {
41 dataBlock = dataBlock->next;(5)
42 dataBlockIndex++;(5)
43 }
44 }
45 else // requested block is closer to the cached block
46 {
47 while (dataBlockIndex != dbi) // move from the cached block until indexes match(3)
48 {
49 dataBlock = dataBlock->prev;(2)
50 dataBlockIndex--;(2)
51 }
52 }
53 }
54 else // requested block is after the cached block (cannot be the same because we've checked that)
55 {
56 if (distEnd <= distCache) // requested block is closer (or the same distance) to the end blcok(20)
57 {
58 dataBlockIndex = lastDataBlcokIndex; // move from the end block until indexes match(13)
59 dataBlock = string.endBlock;(13)
60 while (dataBlockIndex != dbi)(27)
61 {
62 dataBlock = dataBlock->prev;(14)
63 dataBlockIndex--;(14)
64 }
65 }
66 else // requested block is closer to the cached block
67 {
68 while (dataBlockIndex != dbi) // move from the cached block until indexes match(14)
69 {
70 dataBlock = dataBlock->next;(7)
71 dataBlockIndex++;(7)
72 }
73 }
74 }
75
76 return dataBlock->data[offset]; // return requested character (cached block contains correct data)(26)
77 }
78
79 void String::DataCache::reset()(244)
80 {
81 dataBlockIndex = 0;(244)
82 dataBlock = string.startBlock;(244)
83 }(244)
84
85 String::DataCache::~DataCache() = default;