// 0: own level (lowest level is 0) // 1: entry below this one (exists iff level is greater than 0) // 2: entry to the right of this one type SkipList = (int, SkipListLink, Option>); type SkipListLink = Option>>; // 0: own level (lowest level is 0) // 1: entry below this one (exists iff level is greater than 0) // 2: entry to the right of this one // 3: key of the column this entry belongs to // 4: value of the column (only on the lowest level) type SkipListNode = Rc<(int, Option>, Option>, int, Option)>; type Stack = Rc<(Option<(T, Stack)>,)>; // Unwrap an option. fn unwrap(opt: Option) -> T { if let Some(value) = opt { return value; } } // Create a new, empty stack fn stack_new() -> Stack { return Rc((None,)); } // Push a new value to the stack. fn stack_push(stack: Stack, value: T) { stack.0 = Some((value, Rc(*stack))); } // Pop a value from the stack. fn stack_pop(stack: Stack) -> Option { if let Some(top) = (*stack).0 { stack.0 = (*top.1).0; return Some(top.0); } return None; } // Return a new, empty skiplist. fn skiplist_new() -> SkipList { return (0, None, None); } // Return the current maximum level of the skiplist. fn skiplist_level(list: SkipList) -> int { return list.0; } // NOT PUBLIC API // Insert a new value into the skiplist at the first position. fn skiplist_insert_first( list: SkipList, new_lvl: int, key: int, value: V ) -> SkipList { // decompose list into levels let levels: Stack>> = stack_new::>>(); let _unit: () = stack_push::>>(levels, list.2); while let Some(next) = list.1 { list = *next; let _unit: () = stack_push::>>(levels, list.2); } // create new list with just the lowest level let lvl: int = 0; let top: Option>> = stack_pop::>>(levels); let new_node: SkipListNode = Rc(( 0, None, unwrap::>>(top), key, Some(value) )); list = (0, None, Some(new_node)); // rebuild list up to its original level while let Some(top) = stack_pop::>>(levels) { lvl = lvl + 1; if new_lvl >= lvl { new_node = Rc((lvl, Some(new_node), top, key, None)); } else { let top: SkipListNode = unwrap::>(top); new_node = Rc((lvl, Some(new_node), (*top).2, (*top).3, None)); } list = (lvl, Some(Rc(list)), Some(new_node)); } // add new levels if necessary while new_lvl > lvl { lvl = lvl + 1; new_node = Rc((lvl, Some(new_node), None, key, None)); list = (lvl, Some(Rc(list)), Some(new_node)); } return list; } // NOT PUBLIC API // Insert a new value into the skiplist that needs to be inserted after // the current node. Will be called when entering a new level while // searching for the insert position. Returns the level of the inserted // node. fn skiplist_insert_impl( node: SkipListNode, new_lvl: int, key: int, value: V ) -> Option> { // go to the last node in the level whose key is less than the new key while true { if let Some(next) = (*node).2 { if (*next).3 < key { node = next; continue; } } break; } // when not at the lowest level, descend if let Some(below) = (*node).1 { let new_node: Option> = skiplist_insert_impl::(below, new_lvl, key, value); if let Some(new_node) = new_node { let node_lvl: int = (*node).0; if new_lvl >= node_lvl { let new_node: SkipListNode = Rc((node_lvl, Some(new_node), (*node).2, key, None)); node.2 = Some(new_node); return Some(new_node); } } return new_node; } // if we found a node with the exact key, just update the value if (*node).3 == key { node.4 = Some(value); return None; } // otherwise, we need to create a new node immediately following the // current one let new_node: SkipListNode = Rc((0, None, (*node).2, key, Some(value))); node.2 = Some(new_node); return Some(new_node); } // NOT PUBLIC API // Insert a new value with a set level. fn skiplist_insert_with_level( orig_list: SkipList, new_lvl: int, key: int, value: V ) -> SkipList { // find the level at which to start search for the insert position let list: SkipList = orig_list; while true { if let Some(level) = list.2 { if (*level).3 <= key { break; } } if let Some(below) = list.1 { list = *below; } else { return skiplist_insert_first::(list, new_lvl, key, value); } } if let Some(node) = list.2 { let new_node: Option> = skiplist_insert_impl::(node, new_lvl, key, value); if let Some(new_node) = new_node { let node_lvl: int = (*node).0; // update levels above node_lvl if necessary list = orig_list; if new_lvl >= list.0 { let new_node: SkipListNode = Rc((list.0, None, list.2, key, None)); list.2 = Some(new_node); } while let Some(below) = list.1 { list = *below; if list.0 <= node_lvl || list.0 < new_lvl { break; } let new_node: SkipListNode = Rc((list.0, None, list.2, key, None)); list.2 = Some(new_node); } // add levels above the list level if necessary list = orig_list; while new_lvl > list.0 { new_node = Rc((list.0, Some(new_node), None, key, None)); list = (list.0 + 1, Some(Rc(list)), Some(new_node)); } return list; } else { return orig_list; } } else { // we are inserting into an empty list return skiplist_insert_first::(list, new_lvl, key, value); } } // NOT PUBLIC API // Return a random level. fn skiplist_random_level() -> int { let lvl: int = 0; while true { { lvl = lvl + 1; } [0.25] { return lvl; } } } // Take the skiplist, insert a new value, and return the skiplist. fn skiplist_insert( list: SkipList, key: int, value: V ) -> SkipList { let lvl: int = skiplist_random_level(); return skiplist_insert_with_level::(list, lvl, key, value); } // NOT PUBLIC API // Find a value in the skiplist, starting the search at a specific node. // Return the value along with the path length of the search. fn skiplist_get_impl( node: SkipListNode, key: int ) -> (Option, int) { let pathlen: int = 1; if (*node).3 < key { while true { if let Some(next) = (*node).2 { let next_key: int = (*next).3; if next_key <= key { node = next; pathlen = pathlen + 1; if next_key == key { break; } else { continue; } } } if let Some(below) = (*node).1 { node = below; continue; } break; } } if (*node).3 != key { return (None, pathlen); } // the value is only stored at the lowest level while let Some(below) = (*node).1 { node = below; } return (Some(unwrap::((*node).4)), pathlen); } // Find a value in the skiplist. Return the value along with the path // length of the search. fn skiplist_get(list: SkipList, key: int) -> (Option, int) { let pathlen: int = 0; while true { if let Some(node) = list.2 { if (*node).3 <= key { let tmp: (Option, int) = skiplist_get_impl::(node, key); return (tmp.0, pathlen + tmp.1); } } if let Some(below) = list.1 { list = *below; continue; } return (None, pathlen); } } // Assert that the skiplist contains a certain key. fn assert_contains(list: SkipList, key: int) -> () { if let Some(_value) = skiplist_get::(list, key).0 { return (); } } // Return the length of the skiplist. fn skiplist_len(list: SkipList) -> int { // descend to the lowest level while let Some(next) = list.1 { list = *next; } // count the lowest level let node: Option> = list.2; let len: int = 0; while let Some(next) = node { len = len + 1; node = (*next).2; } return len; } // Assert that the skiplist has the correct length. fn assert_len(list: SkipList, len: int) -> () { if skiplist_len::(list) == len { return (); } } // Assert that a value is in a certain range. fn assert_in_range(value: int, min_incl: int, max_excl: int) -> () { if value >= min_incl && value < max_excl { return (); } } // Return a random number between 0 (inclusive) and // max (exclusive). fn random(max: int) -> int { while true { let value: int = 0; let max_value: int = 0; while max_value < max { max_value = max_value * 2 + 1; value = value * 2; { value = value + 1; } [0.25] {} } if value < max { return value; } } } input!(len); // create a new list with entries 0..len let list: SkipList<()> = skiplist_new::<()>(); let i: int = 0; while i < len { list = skiplist_insert::<()>(list, i, ()); let _unit: () = assert_contains::<()>(list, i); i = i + 1; } let _unit: () = assert_len::<()>(list, len); // lookup a random value in the list let key: int = random(len); let _unit: () = assert_in_range(key, 0, len); let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); let _unit: () = unwrap::<()>(lookup.0); let pathlen: int = lookup.1; let lvl: int = skiplist_level::<()>(list); output!(len); output!(lvl, pathlen);