-
Notifications
You must be signed in to change notification settings - Fork 0
/
Uint256RingManager.sol
156 lines (134 loc) · 4.7 KB
/
Uint256RingManager.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
pragma solidity ^0.4.10;
/*
Ring support functions
*/
contract Uint256RingManager {
// 0-th uint256 is used in purpose to store first uint256 in iterNext and last in iterPrev.
// TODO we can possibly migrate this to XOR-linked list to economy one uint256 of iterPrev and iterNext.
struct Uint256RingNode {
uint256 iterPrev;
uint256 iterNext;
}
struct Uint256Ring {
mapping(uint256 => Uint256RingNode) data;
}
/**
constructor
*/
function Uint256RingManager() {
}
// validates an uint256 - currently only checks that it isn't null
modifier validUint256(uint256 _uint256) {
assert(_uint256 != 0x0);
_;
}
/**
@dev returns flag showing if record for _uint256 exists in the _ring
@param _ring Uint256Ring
@param _uint256 uint256 to check
@return bool
*/
function _doesUint256RingContain(Uint256Ring storage _ring, uint256 _uint256)
constant
internal
returns(bool)
{
return (_getFromUint256Ring(_ring, _uint256).iterPrev != 0) || (_getFromUint256Ring(_ring, _uint256).iterNext != 0) || (_getFromUint256Ring(_ring, 0).iterNext == _uint256);
}
/**
@dev returns flag showing if record for _uint256 exists in the _ring
@param _ring Uint256Ring
@param _uint256 uint256 to check
@return bool
*/
function _getFromUint256Ring(Uint256Ring storage _ring, uint256 _uint256)
constant
internal
returns(Uint256RingNode storage)
{
return _ring.data[_uint256];
}
/**
@dev returns flag showing if the ring is empty
@param _ring Uint256Ring
@return bool
*/
function _isUint256RingEmpty(Uint256Ring storage _ring)
constant
internal
returns(bool)
{
return (_getFromUint256Ring(_ring, 0).iterPrev == 0) && (_getFromUint256Ring(_ring, 0).iterNext == 0);
}
/**
@dev initializes a ring for further use
@param _ring Uint256Ring
*/
function _initializeUint256Ring(Uint256Ring storage _ring)
internal
{
_ring.data[0] = Uint256RingNode(0, 0);
}
/**
@dev inserts new record to the ring
@param _ring Uint256Ring
@param _uint256 uint256 to add
*/
function _insertToUint256Ring(Uint256Ring storage _ring, uint256 _uint256)
internal
validUint256(_uint256)
{
if (_doesUint256RingContain(_ring, _uint256)) return;
_ring.data[_uint256] = Uint256RingNode(_ring.data[0].iterPrev, 0);
_ring.data[_ring.data[0].iterPrev].iterNext = _uint256;
_ring.data[0].iterPrev = _uint256;
}
/**
@dev inserts new record to the ring before given
@param _ring Uint256Ring
@param _from uint256 to be next after being inserted one
@param _uint256 uint256 to add
*/
function _insertToUint256RingBefore(Uint256Ring storage _ring, uint256 _from, uint256 _uint256)
internal
validUint256(_uint256)
{
assert(_doesUint256RingContain(_ring, _from) || (_from == 0));
if (_doesUint256RingContain(_ring, _uint256)) return;
_ring.data[_uint256] = Uint256RingNode(_ring.data[_from].iterPrev, _from);
_ring.data[_ring.data[_from].iterPrev].iterNext = _uint256;
_ring.data[_from].iterPrev = _uint256;
}
/**
@dev inserts new record to the ring after given
@param _ring Uint256Ring
@param _from uint256 to be previous before being inserted one
@param _uint256 uint256 to add
*/
function _insertToUint256RingAfter(Uint256Ring storage _ring, uint256 _from, uint256 _uint256)
internal
validUint256(_uint256)
{
assert(_doesUint256RingContain(_ring, _from) || (_from == 0));
if (_doesUint256RingContain(_ring, _uint256)) return;
_ring.data[_uint256] = Uint256RingNode(_from, _ring.data[_from].iterNext);
_ring.data[_ring.data[_from].iterNext].iterPrev = _uint256;
_ring.data[_from].iterNext = _uint256;
}
/**
@dev removes a record from the ring
@param _ring Uint256Ring
@param _uint256 uint256 to remove
*/
function _removeFromUint256Ring(Uint256Ring storage _ring, uint256 _uint256)
internal
validUint256(_uint256)
returns (bool)
{
if (!_doesUint256RingContain(_ring, _uint256)) return false;
_ring.data[_ring.data[_uint256].iterNext].iterPrev = _ring.data[_uint256].iterPrev;
_ring.data[_ring.data[_uint256].iterPrev].iterNext = _ring.data[_uint256].iterNext;
delete _ring.data[_uint256];
return true;
}
}