func curs(pairs ...interface{}) queryCursor { if len(pairs)%2 != 0 { panic("curs() takes only even pairs") } pre := &bytes.Buffer{} if _, err := cmpbin.WriteUint(pre, uint64(len(pairs)/2)); err != nil { panic(err) } post := serialize.Invertible(&bytes.Buffer{}) for i := 0; i < len(pairs); i += 2 { k, v := pairs[i].(string), pairs[i+1] col, err := dstore.ParseIndexColumn(k) if err != nil { panic(err) } post.SetInvert(col.Descending) if err := serialize.WriteIndexColumn(pre, col); err != nil { panic(err) } if err := serialize.WriteProperty(post, serialize.WithoutContext, prop(v)); err != nil { panic(err) } } return queryCursor(serialize.Join(pre.Bytes(), post.Bytes())) }
func parseSuffix(ns string, suffixFormat []ds.IndexColumn, suffix []byte, count int) (raw [][]byte, decoded []ds.Property) { buf := serialize.Invertible(bytes.NewBuffer(suffix)) decoded = make([]ds.Property, len(suffixFormat)) raw = make([][]byte, len(suffixFormat)) err := error(nil) for i := range decoded { if count > 0 && i > count { break } needInvert := suffixFormat[i].Direction == ds.DESCENDING buf.SetInvert(needInvert) decoded[i], err = serialize.ReadProperty(buf, serialize.WithoutContext, globalAppID, ns) memoryCorruption(err) offset := len(suffix) - buf.Len() raw[i] = suffix[:offset] suffix = suffix[offset:] if needInvert { raw[i] = invert(raw[i]) } } return }
// permute calls cb for each index row, in the sorted order of the rows. func (s indexRowGen) permute(collSetFn func(k, v []byte)) { iVec := make([]int, len(s.propVec)) iVecLim := make([]int, len(s.propVec)) incPos := func() bool { for i := len(iVec) - 1; i >= 0; i-- { var done bool var newVal int if s.orders[i] == ds.ASCENDING { newVal = (iVec[i] + 1) % iVecLim[i] done = newVal != 0 } else { newVal = (iVec[i] - 1) if newVal < 0 { newVal = iVecLim[i] - 1 } else { done = true } } iVec[i] = newVal if done { return true } } return false } for i, sps := range s.propVec { iVecLim[i] = len(sps) } for i := range iVec { if s.orders[i] == ds.DESCENDING { iVec[i] = iVecLim[i] - 1 } } for { bufsiz := 0 for pvalSliceIdx, pvalIdx := range iVec { bufsiz += len(s.propVec[pvalSliceIdx][pvalIdx]) } buf := serialize.Invertible(bytes.NewBuffer(make([]byte, 0, bufsiz))) for pvalSliceIdx, pvalIdx := range iVec { data := s.propVec[pvalSliceIdx][pvalIdx] buf.SetInvert(s.orders[pvalSliceIdx] == ds.DESCENDING) buf.Write(data) } collSetFn(buf.Bytes(), []byte{}) if !incPos() { break } } }
func curs(pairs ...interface{}) queryCursor { if len(pairs)%2 != 0 { panic("curs() takes only even pairs") } pre := &bytes.Buffer{} cmpbin.WriteUint(pre, uint64(len(pairs)/2)) post := serialize.Invertible(&bytes.Buffer{}) for i := 0; i < len(pairs); i += 2 { k, v := pairs[i].(string), pairs[i+1] col := dsS.IndexColumn{Property: k} post.SetInvert(false) if k[0] == '-' { post.SetInvert(false) col.Property = k[1:] col.Direction = dsS.DESCENDING } serialize.WriteIndexColumn(pre, col) serialize.WriteProperty(post, serialize.WithoutContext, prop(v)) } return queryCursor(bjoin(pre.Bytes(), post.Bytes())) }