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  }