sorted-doubly-ll
Version:
EVM package for a sorted doubly linked list
867 lines (866 loc) • 1.22 MB
JSON
{
"contractName": "SortedDoublyLL",
"abi": [],
"bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea165627a7a7230582075b77b32caddbed2be9bdbf1d846559d5c78e6a6e5c85890092cfc27da2a32d20029",
"deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea165627a7a7230582075b77b32caddbed2be9bdbf1d846559d5c78e6a6e5c85890092cfc27da2a32d20029",
"sourceMap": "1251:12905:1:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24",
"deployedSourceMap": "1251:12905:1:-;;;;;;;;",
"source": "pragma solidity 0.5.0;\n\nimport \"openzeppelin-solidity/contracts/math/SafeMath.sol\";\n\n\n/*\n * @title A sorted doubly linked list with nodes sorted in descending order. Optionally accepts insert position hints\n *\n * Given a new node with a `key`, a hint is of the form `(prevId, nextId)` s.t. `prevId` and `nextId` are adjacent in the list.\n * `prevId` is a node with a key >= `key` and `nextId` is a node with a key <= `key`. If the sender provides a hint that is a valid insert position\n * the insert operation is a constant time storage write. However, the provided hint in a given transaction might be a valid insert position, but if other transactions are included first, when\n * the given transaction is executed the provided hint may no longer be a valid insert position. For example, one of the nodes referenced might be removed or their keys may\n * be updated such that the the pair of nodes in the hint no longer represent a valid insert position. If one of the nodes in the hint becomes invalid, we still try to use the other\n * valid node as a starting point for finding the appropriate insert position. If both nodes in the hint become invalid, we use the head of the list as a starting point\n * to find the appropriate insert position.\n */\nlibrary SortedDoublyLL {\n using SafeMath for uint256;\n\n // Information for a node in the list\n struct Node {\n uint256 key; // Node's key used for sorting\n address nextId; // Id of next node (smaller key) in the list\n address prevId; // Id of previous node (larger key) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest key\n address tail; // Tail of the list. Also the node in the list with the smallest key\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping (address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n /*\n * @dev Set the maximum size of the list\n * @param _size Maximum size\n */\n function setMaxSize(Data storage self, uint256 _size) internal {\n // New max size must be greater than old max size\n require(\n _size > self.maxSize,\n \"new max size must be greater than old max size\"\n );\n\n self.maxSize = _size;\n }\n\n /*\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(Data storage self, address _id, uint256 _key, address _prevId, address _nextId) internal {\n // List must not be full\n require(\n !isFull(self),\n \"cannot insert into a full list\"\n );\n // List must not already contain node\n require(\n !contains(self, _id),\n \"cannot insert node that already exists\"\n );\n // Node id must not be null\n require(\n _id != address(0),\n \"cannot insert node with a null id\"\n );\n // Key must be non-zero\n require(\n _key > 0,\n \"cannot insert node with zero key\"\n );\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!validInsertPosition(self, _key, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = findInsertPosition(self, _key, prevId, nextId);\n }\n\n self.nodes[_id].key = _key;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n self.head = _id;\n self.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n self.nodes[_id].nextId = self.head;\n self.nodes[self.head].prevId = _id;\n self.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n self.nodes[_id].prevId = self.tail;\n self.nodes[self.tail].nextId = _id;\n self.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n self.nodes[_id].nextId = nextId;\n self.nodes[_id].prevId = prevId;\n self.nodes[prevId].nextId = _id;\n self.nodes[nextId].prevId = _id;\n }\n\n self.size = self.size.add(1);\n }\n\n /*\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(Data storage self, address _id) internal {\n // List must contain the node\n require(\n contains(self, _id),\n \"cannot remote node that does not exist\"\n );\n\n if (self.size > 1) {\n // List contains more than a single node\n if (_id == self.head) {\n // The removed node is the head\n // Set head to next node\n self.head = self.nodes[_id].nextId;\n // Set prev pointer of new head to null\n self.nodes[self.head].prevId = address(0);\n } else if (_id == self.tail) {\n // The removed node is the tail\n // Set tail to previous node\n self.tail = self.nodes[_id].prevId;\n // Set next pointer of new tail to null\n self.nodes[self.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n self.nodes[self.nodes[_id].prevId].nextId = self.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n self.nodes[self.nodes[_id].nextId].prevId = self.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n self.head = address(0);\n self.tail = address(0);\n }\n\n delete self.nodes[_id];\n self.size = self.size.sub(1);\n }\n\n /*\n * @dev Update the key of a node in the list\n * @param _id Node's id\n * @param _newKey Node's new key\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function updateKey(Data storage self, address _id, uint256 _newKey, address _prevId, address _nextId) internal {\n // List must contain the node\n require(\n contains(self, _id),\n \"cannot update node that does not exist\"\n );\n\n // Remove node from the list\n remove(self, _id);\n\n if (_newKey > 0) {\n // Insert node if it has a non-zero key\n insert(self, _id, _newKey, _prevId, _nextId);\n }\n }\n\n /*\n * @dev Checks if the list contains a node\n * @param _transcoder Address of transcoder\n */\n function contains(Data storage self, address _id) internal view returns (bool) {\n // List only contains non-zero keys, so if key is non-zero the node exists\n return self.nodes[_id].key > 0;\n }\n\n /*\n * @dev Checks if the list is full\n */\n function isFull(Data storage self) internal view returns (bool) {\n return self.size == self.maxSize;\n }\n\n /*\n * @dev Checks if the list is empty\n */\n function isEmpty(Data storage self) internal view returns (bool) {\n return self.size == 0;\n }\n\n /*\n * @dev Returns the current size of the list\n */\n function getSize(Data storage self) internal view returns (uint256) {\n return self.size;\n }\n\n /*\n * @dev Returns the maximum size of the list\n */\n function getMaxSize(Data storage self) internal view returns (uint256) {\n return self.maxSize;\n }\n\n /*\n * @dev Returns the key of a node in the list\n * @param _id Node's id\n */\n function getKey(Data storage self, address _id) internal view returns (uint256) {\n return self.nodes[_id].key;\n }\n\n /*\n * @dev Returns the first node in the list (node with the largest key)\n */\n function getFirst(Data storage self) internal view returns (address) {\n return self.head;\n }\n\n /*\n * @dev Returns the last node in the list (node with the smallest key)\n */\n function getLast(Data storage self) internal view returns (address) {\n return self.tail;\n }\n\n /*\n * @dev Returns the next node (with a smaller key) in the list for a given node\n * @param _id Node's id\n */\n function getNext(Data storage self, address _id) internal view returns (address) {\n return self.nodes[_id].nextId;\n }\n\n /*\n * @dev Returns the previous node (with a larger key) in the list for a given node\n * @param _id Node's id\n */\n function getPrev(Data storage self, address _id) internal view returns (address) {\n return self.nodes[_id].prevId;\n }\n\n /*\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given key\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(Data storage self, uint256 _key, address _prevId, address _nextId) internal view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty(self);\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return self.head == _nextId && _key >= self.nodes[_nextId].key;\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return self.tail == _prevId && _key <= self.nodes[_prevId].key;\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_key` falls between the two nodes' keys\n return self.nodes[_prevId].nextId == _nextId && self.nodes[_prevId].key >= _key && _key >= self.nodes[_nextId].key;\n }\n }\n\n /*\n * @dev Descend the list (larger keys to smaller keys) to find a valid insert position\n * @param _key Node's key\n * @param _startId Id of node to start ascending the list from\n */\n function descendList(Data storage self, uint256 _key, address _startId) internal view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (self.head == _startId && _key >= self.nodes[_startId].key) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = self.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (prevId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {\n prevId = self.nodes[prevId].nextId;\n nextId = self.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /*\n * @dev Ascend the list (smaller keys to larger keys) to find a valid insert position\n * @param _key Node's key\n * @param _startId Id of node to start descending the list from\n */\n function ascendList(Data storage self, uint256 _key, address _startId) internal view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (self.tail == _startId && _key <= self.nodes[_startId].key) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = self.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (nextId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {\n nextId = self.nodes[nextId].prevId;\n prevId = self.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /*\n * @dev Find the insert position for a new node with the given key\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(Data storage self, uint256 _key, address _prevId, address _nextId) internal view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(self, prevId) || _key > self.nodes[prevId].key) {\n // `prevId` does not exist anymore or now has a smaller key than the given key\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(self, nextId) || _key < self.nodes[nextId].key) {\n // `nextId` does not exist anymore or now has a larger key than the given key\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return descendList(self, _key, self.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return ascendList(self, _key, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return descendList(self, _key, prevId);\n } else {\n // Descend list starting from `prevId`\n return descendList(self, _key, prevId);\n }\n }\n}",
"sourcePath": "/Users/yondonfu/Development/livepeer/sorted-doubly-ll/packages/sorted-doubly-ll/contracts/SortedDoublyLL.sol",
"ast": {
"absolutePath": "/Users/yondonfu/Development/livepeer/sorted-doubly-ll/packages/sorted-doubly-ll/contracts/SortedDoublyLL.sol",
"exportedSymbols": {
"SortedDoublyLL": [
1207
]
},
"id": 1208,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 224,
"literals": [
"solidity",
"0.5",
".0"
],
"nodeType": "PragmaDirective",
"src": "0:22:1"
},
{
"absolutePath": "openzeppelin-solidity/contracts/math/SafeMath.sol",
"file": "openzeppelin-solidity/contracts/math/SafeMath.sol",
"id": 225,
"nodeType": "ImportDirective",
"scope": 1208,
"sourceUnit": 1336,
"src": "24:59:1",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "library",
"documentation": null,
"fullyImplemented": true,
"id": 1207,
"linearizedBaseContracts": [
1207
],
"name": "SortedDoublyLL",
"nodeType": "ContractDefinition",
"nodes": [
{
"id": 228,
"libraryName": {
"contractScope": null,
"id": 226,
"name": "SafeMath",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1335,
"src": "1286:8:1",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SafeMath_$1335",
"typeString": "library SafeMath"
}
},
"nodeType": "UsingForDirective",
"src": "1280:27:1",
"typeName": {
"id": 227,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1299:7:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
},
{
"canonicalName": "SortedDoublyLL.Node",
"id": 235,
"members": [
{
"constant": false,
"id": 230,
"name": "key",
"nodeType": "VariableDeclaration",
"scope": 235,
"src": "1377:11:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 229,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1377:7:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 232,
"name": "nextId",
"nodeType": "VariableDeclaration",
"scope": 235,
"src": "1449:14:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 231,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1449:7:1",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 234,
"name": "prevId",
"nodeType": "VariableDeclaration",
"scope": 235,
"src": "1535:14:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 233,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1535:7:1",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"name": "Node",
"nodeType": "StructDefinition",
"scope": 1207,
"src": "1355:266:1",
"visibility": "public"
},
{
"canonicalName": "SortedDoublyLL.Data",
"id": 248,
"members": [
{
"constant": false,
"id": 237,
"name": "head",
"nodeType": "VariableDeclaration",
"scope": 248,
"src": "1681:12:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 236,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1681:7:1",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 239,
"name": "tail",
"nodeType": "VariableDeclaration",
"scope": 248,
"src": "1794:12:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 238,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1794:7:1",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 241,
"name": "maxSize",
"nodeType": "VariableDeclaration",
"scope": 248,
"src": "1908:15:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 240,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1908:7:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 243,
"name": "size",
"nodeType": "VariableDeclaration",
"scope": 248,
"src": "1981:12:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 242,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1981:7:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 247,
"name": "nodes",
"nodeType": "VariableDeclaration",
"scope": 248,
"src": "2054:31:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_mapping$_t_address_$_t_struct$_Node_$235_storage_$",
"typeString": "mapping(address => struct SortedDoublyLL.Node)"
},
"typeName": {
"id": 246,
"keyType": {
"id": 244,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "2063:7:1",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Mapping",
"src": "2054:25:1",
"typeDescriptions": {
"typeIdentifier": "t_mapping$_t_address_$_t_struct$_Node_$235_storage_$",
"typeString": "mapping(address => struct SortedDoublyLL.Node)"
},
"valueType": {
"contractScope": null,
"id": 245,
"name": "Node",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 235,
"src": "2074:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Node_$235_storage_ptr",
"typeString": "struct SortedDoublyLL.Node"
}
}
},
"value": null,
"visibility": "internal"
}
],
"name": "Data",
"nodeType": "StructDefinition",
"scope": 1207,
"src": "1659:494:1",
"visibility": "public"
},
{
"body": {
"id": 269,
"nodeType": "Block",
"src": "2315:219:1",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 259,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 256,
"name": "_size",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 252,
"src": "2404:5:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">",
"rightExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 257,
"name": "self",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 250,
"src": "2412:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
}
},
"id": 258,
"isConstant": false,
"isLValue": true,
"isPure": false,
"lValueRequested": false,
"memberName": "maxSize",
"nodeType": "MemberAccess",
"referencedDeclaration": 241,
"src": "2412:12:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "2404:20:1",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "6e6577206d61782073697a65206d7573742062652067726561746572207468616e206f6c64206d61782073697a65",
"id": 260,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2438:48:1",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_30180cb1a055b4f426da570ff72eaa2227ac83f4e78a0723078bb5e5c76e86a9",
"typeString": "literal_string \"new max size must be greater than old max size\""
},
"value": "new max size must be greater than old max size"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_30180cb1a055b4f426da570ff72eaa2227ac83f4e78a0723078bb5e5c76e86a9",
"typeString": "literal_string \"new max size must be greater than old max size\""
}
],
"id": 255,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
1409,
1410
],
"referencedDeclaration": 1410,
"src": "2383:7:1",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 261,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "2383:113:1",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 262,
"nodeType": "ExpressionStatement",
"src": "2383:113:1"
},
{
"expression": {
"argumentTypes": null,
"id": 267,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 263,
"name": "self",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 250,
"src": "2507:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
}
},
"id": 265,
"isConstant": false,
"isLValue": true,
"isPure": false,
"lValueRequested": true,
"memberName": "maxSize",
"nodeType": "MemberAccess",
"referencedDeclaration": 241,
"src": "2507:12:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 266,
"name": "_size",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 252,
"src": "2522:5:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "2507:20:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 268,
"nodeType": "ExpressionStatement",
"src": "2507:20:1"
}
]
},
"documentation": null,
"id": 270,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setMaxSize",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 253,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 250,
"name": "self",
"nodeType": "VariableDeclaration",
"scope": 270,
"src": "2272:17:1",
"stateVariable": false,
"storageLocation": "storage",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data"
},
"typeName": {
"contractScope": null,
"id": 249,
"name": "Data",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 248,
"src": "2272:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 252,
"name": "_size",
"nodeType": "VariableDeclaration",
"scope": 270,
"src": "2291:13:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 251,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "2291:7:1",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "2271:34:1"
},
"returnParameters": {
"id": 254,
"nodeType": "ParameterList",
"parameters": [],
"src": "2315:0:1"
},
"scope": 1207,
"src": "2252:282:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "internal"
},
{
"body": {
"id": 491,
"nodeType": "Block",
"src": "2881:1869:1",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 287,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "!",
"prefix": true,
"src": "2945:13:1",
"subExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 285,
"name": "self",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 272,
"src": "2953:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
}
],
"id": 284,
"name": "isFull",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 710,
"src": "2946:6:1",
"typeDescriptions": {
"typeIdentifier": "t_function_internal_view$_t_struct$_Data_$248_storage_ptr_$returns$_t_bool_$",
"typeString": "function (struct SortedDoublyLL.Data storage pointer) view returns (bool)"
}
},
"id": 286,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "2946:12:1",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "63616e6e6f7420696e7365727420696e746f20612066756c6c206c697374",
"id": 288,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "2972:32:1",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_c717684577a451051cd65ab3f9ba5a50cc9ef38655a6cc00364245ec33eaec6e",
"typeString": "literal_string \"cannot insert into a full list\""
},
"value": "cannot insert into a full list"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_c717684577a451051cd65ab3f9ba5a50cc9ef38655a6cc00364245ec33eaec6e",
"typeString": "literal_string \"cannot insert into a full list\""
}
],
"id": 283,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
1409,
1410
],
"referencedDeclaration": 1410,
"src": "2924:7:1",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 289,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "2924:90:1",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 290,
"nodeType": "ExpressionStatement",
"src": "2924:90:1"
},
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 296,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "!",
"prefix": true,
"src": "3091:20:1",
"subExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 293,
"name": "self",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 272,
"src": "3101:4:1",
"typeDescriptions": {
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
}
},
{
"argumentTypes": null,
"id": 294,
"name": "_id",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 274,
"src": "3107:3:1",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_struct$_Data_$248_storage_ptr",
"typeString": "struct SortedDoublyLL.Data storage pointer"
},
{
"typeIdentifier": "t_address",
"typeString": "address"
}
],
"id": 292,
"name": "contains",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 696,
"src": "3092:8:1",
"typeDescriptions": {
"typeIdentifier": "t_function_internal_view$_t_struct$_Data_$248_storage_ptr_$_t_address_$returns$_t_bool_$",
"typeString": "function (struct SortedDoublyLL.Data storage pointer,address) view returns (bool)"
}
},
"id": 295,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "3092:19:1",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "63616e6e6f7420696e73657274206e6f6465207468617420616c726561647920657869737473",
"id": 297,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "3125:40:1",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_ffcfe52afc7805b93498508456cf152482630a9e40c85ebae9fa3fdf5dc6849f",
"typeString": "literal_string \"cannot insert node that already exists\""
},
"value": "cannot insert node that already exists"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_ffcfe52afc7805b93498508456cf152482630a9e40c85ebae9fa3fdf5dc6849f",
"typeString": "literal_string \"cannot insert node that already exists\""
}
],
"id": 291,