github.com/ndau/noms@v1.0.5/go/types/ordered_sequences.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package types 6 7 import ( 8 "github.com/ndau/noms/go/d" 9 ) 10 11 type orderedSequence interface { 12 sequence 13 getKey(idx int) orderedKey 14 search(key orderedKey) int 15 } 16 17 func newSetMetaSequence(level uint64, tuples []metaTuple, vrw ValueReadWriter) metaSequence { 18 return newMetaSequenceFromTuples(SetKind, level, tuples, vrw) 19 } 20 21 func newMapMetaSequence(level uint64, tuples []metaTuple, vrw ValueReadWriter) metaSequence { 22 return newMetaSequenceFromTuples(MapKind, level, tuples, vrw) 23 } 24 25 func newCursorAtValue(seq orderedSequence, val Value, forInsertion bool, last bool) *sequenceCursor { 26 var key orderedKey 27 if val != nil { 28 key = newOrderedKey(val) 29 } 30 return newCursorAt(seq, key, forInsertion, last) 31 } 32 33 func newCursorAt(seq orderedSequence, key orderedKey, forInsertion bool, last bool) *sequenceCursor { 34 var cur *sequenceCursor 35 for { 36 idx := 0 37 if last { 38 idx = -1 39 } 40 cur = newSequenceCursor(cur, seq, idx) 41 if key != emptyKey { 42 if !seekTo(cur, key, forInsertion && !seq.isLeaf()) { 43 return cur 44 } 45 } 46 47 cs := cur.getChildSequence() 48 if cs == nil { 49 break 50 } 51 seq = cs.(orderedSequence) 52 } 53 d.PanicIfFalse(cur != nil) 54 return cur 55 } 56 57 func seekTo(cur *sequenceCursor, key orderedKey, lastPositionIfNotFound bool) bool { 58 seq := cur.seq.(orderedSequence) 59 60 // Find smallest idx in seq where key(idx) >= key 61 cur.idx = seq.search(key) 62 seqLen := seq.seqLen() 63 if cur.idx == seqLen && lastPositionIfNotFound { 64 d.PanicIfFalse(cur.idx > 0) 65 cur.idx-- 66 } 67 68 return cur.idx < seqLen 69 } 70 71 // Gets the key used for ordering the sequence at current index. 72 func getCurrentKey(cur *sequenceCursor) orderedKey { 73 seq, ok := cur.seq.(orderedSequence) 74 if !ok { 75 d.Panic("need an ordered sequence here") 76 } 77 return seq.getKey(cur.idx) 78 } 79 80 func getMapValue(cur *sequenceCursor) Value { 81 if ml, ok := cur.seq.(mapLeafSequence); ok { 82 return ml.getValue(cur.idx) 83 } 84 85 return nil 86 } 87 88 // If |vw| is not nil, chunks will be eagerly written as they're created. Otherwise they are 89 // written when the root is written. 90 func newOrderedMetaSequenceChunkFn(kind NomsKind, vrw ValueReadWriter) makeChunkFn { 91 return func(level uint64, items []sequenceItem) (Collection, orderedKey, uint64) { 92 tuples := make([]metaTuple, len(items)) 93 numLeaves := uint64(0) 94 95 var lastKey orderedKey 96 for i, v := range items { 97 mt := v.(metaTuple) 98 key := mt.key() 99 d.PanicIfFalse(lastKey == emptyKey || lastKey.Less(key)) 100 lastKey = key 101 tuples[i] = mt // chunk is written when the root sequence is written 102 numLeaves += mt.numLeaves() 103 } 104 105 var col Collection 106 if kind == SetKind { 107 col = newSet(newSetMetaSequence(level, tuples, vrw)) 108 } else { 109 d.PanicIfFalse(MapKind == kind) 110 col = newMap(newMapMetaSequence(level, tuples, vrw)) 111 } 112 113 return col, tuples[len(tuples)-1].key(), numLeaves 114 } 115 }