示例#1
0
文件: file.go 项目: brgmnn/syncthing
func (s *file) freeChunks(enc []byte) (err error) {
	items, err := lldb.DecodeScalars(enc)
	if err != nil {
		return
	}

	var ok bool
	var next int64
	switch len(items) {
	case 2:
		return
	case 3:
		if next, ok = items[1].(int64); !ok || next == 0 {
			return fmt.Errorf("(file-007) corrupted DB: first chunk link")
		}
	default:
		return fmt.Errorf("(file-008) corrupted DB: first chunk")
	}

	for next != 0 {
		b, err := s.a.Get(nil, next)
		if err != nil {
			return err
		}

		if items, err = lldb.DecodeScalars(b); err != nil {
			return err
		}

		var h int64
		switch len(items) {
		case 1:
			// nop
		case 2:
			if h, ok = items[0].(int64); !ok {
				return fmt.Errorf("(file-009) corrupted DB: chunk link")
			}

		default:
			return fmt.Errorf("(file-010) corrupted DB: chunk items %d (%v)", len(items), items)
		}

		s.mu.Lock()
		if err = s.a.Free(next); err != nil {
			s.mu.Unlock()
			return err
		}

		s.mu.Unlock()
		next = h
	}
	return
}
示例#2
0
文件: file.go 项目: brgmnn/syncthing
func (s *file) free(h int64, blobCols []*col) (err error) {
	b, err := s.a.Get(nil, h) //LATER +bufs
	if err != nil {
		return
	}

	rec, err := lldb.DecodeScalars(b)
	if err != nil {
		return
	}

	for _, col := range blobCols {
		if col.index >= len(rec) {
			return fmt.Errorf("(file-004) file.free: corrupted DB (record len)")
		}
		if col.index+2 >= len(rec) {
			continue
		}

		switch x := rec[col.index+2].(type) {
		case nil:
			// nop
		case []byte:
			if err = s.freeChunks(x); err != nil {
				return
			}
		}
	}
	defer s.lock()()
	return s.a.Free(h)
}
示例#3
0
文件: file.go 项目: brgmnn/syncthing
func (it *fileBTreeIterator) Next() (k, v []interface{}, err error) {
	bk, bv, err := it.en.Next()
	if err != nil {
		return
	}

	if k, err = lldb.DecodeScalars(bk); err != nil {
		return
	}

	for i, val := range k {
		b, ok := val.([]byte)
		if !ok {
			continue
		}

		c := chunk{it.t.file, b}
		if k[i], err = c.expand(); err != nil {
			return nil, nil, err
		}
	}

	if err = enforce(k, it.t.colsK); err != nil {
		return
	}

	if v, err = lldb.DecodeScalars(bv); err != nil {
		return
	}

	for i, val := range v {
		b, ok := val.([]byte)
		if !ok {
			continue
		}

		c := chunk{it.t.file, b}
		if v[i], err = c.expand(); err != nil {
			return nil, nil, err
		}
	}

	err = enforce(v, it.t.colsV)
	return
}
示例#4
0
文件: file.go 项目: brgmnn/syncthing
func (s *file) collate(a, b []byte) int { //TODO w/ error return
	da, err := lldb.DecodeScalars(a)
	if err != nil {
		panic(err)
	}

	if err = s.expandBytes(da); err != nil {
		panic(err)
	}

	db, err := lldb.DecodeScalars(b)
	if err != nil {
		panic(err)
	}

	if err = s.expandBytes(db); err != nil {
		panic(err)
	}

	//dbg("da: %v, db: %v", da, db)
	return collate(da, db)
}
示例#5
0
文件: file.go 项目: brgmnn/syncthing
func (i *fileIndexIterator) nextPrev(f func() ([]byte, []byte, error)) ([]interface{}, int64, error) { //TODO(indices) blobs: +test
	bk, bv, err := f()
	if err != nil {
		return nil, -1, err
	}

	dk, err := lldb.DecodeScalars(bk)
	if err != nil {
		return nil, -1, err
	}

	b, ok := dk[0].([]byte)
	if ok {
		dk[0] = chunk{i.f, b}
		if expand(dk[:1]); err != nil {
			return nil, -1, err
		}
	}

	var k indexKey
	k.value = dk[:len(dk)-1]
	switch i.unique {
	case true:
		if isIndexNull(k.value) {
			return nil, dk[len(dk)-1].(int64), nil
		}

		dv, err := lldb.DecodeScalars(bv)
		if err != nil {
			return nil, -1, err
		}

		return k.value, dv[0].(int64), nil
	default:
		return k.value, dk[len(dk)-1].(int64), nil
	}
}
示例#6
0
文件: file.go 项目: brgmnn/syncthing
func (t *fileTemp) Get(k []interface{}) (v []interface{}, err error) {
	if err = expand(k); err != nil {
		return
	}

	if err = t.flatten(k); err != nil {
		return nil, err
	}

	bk, err := lldb.EncodeScalars(k...)
	if err != nil {
		return
	}

	bv, err := t.t.Get(nil, bk)
	if err != nil {
		return
	}

	return lldb.DecodeScalars(bv)
}
示例#7
0
文件: file.go 项目: brgmnn/syncthing
func (s *file) loadChunks(enc []byte) (v interface{}, err error) {
	items, err := lldb.DecodeScalars(enc)
	if err != nil {
		return
	}

	var ok bool
	var next int64
	switch len(items) {
	case 2:
		// nop
	case 3:
		if next, ok = items[1].(int64); !ok || next == 0 {
			return nil, fmt.Errorf("(file-011) corrupted DB: first chunk link")
		}
	default:
		//fmt.Printf("%d: %#v\n", len(items), items)
		return nil, fmt.Errorf("(file-012) corrupted DB: first chunk")
	}

	typ, ok := items[0].(int64)
	if !ok {
		return nil, fmt.Errorf("(file-013) corrupted DB: first chunk tag")
	}

	buf, ok := items[len(items)-1].([]byte)
	if !ok {
		return nil, fmt.Errorf("(file-014) corrupted DB: first chunk data")
	}

	for next != 0 {
		b, err := s.a.Get(nil, next)
		if err != nil {
			return nil, err
		}

		if items, err = lldb.DecodeScalars(b); err != nil {
			return nil, err
		}

		switch len(items) {
		case 1:
			next = 0
		case 2:
			if next, ok = items[0].(int64); !ok {
				return nil, fmt.Errorf("(file-015) corrupted DB: chunk link")
			}

			items = items[1:]
		default:
			return nil, fmt.Errorf("(file-016) corrupted DB: chunk items %d (%v)", len(items), items)
		}

		if b, ok = items[0].([]byte); !ok {
			return nil, fmt.Errorf("(file-017) corrupted DB: chunk data")
		}

		buf = append(buf, b...)
	}
	return s.codec.decode(buf, int(typ))
}
示例#8
0
文件: file.go 项目: brgmnn/syncthing
func (s *file) Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) { //NTYPE
	b, err := s.a.Get(nil, h) //LATER +bufs
	if err != nil {
		return
	}

	rec, err := lldb.DecodeScalars(b)
	if err != nil {
		return
	}

	for _, col := range cols {
		i := col.index + 2
		if i >= len(rec) || rec[i] == nil {
			continue
		}

		switch col.typ {
		case 0:
		case qBool:
		case qComplex64:
			rec[i] = complex64(rec[i].(complex128))
		case qComplex128:
		case qFloat32:
			rec[i] = float32(rec[i].(float64))
		case qFloat64:
		case qInt8:
			rec[i] = int8(rec[i].(int64))
		case qInt16:
			rec[i] = int16(rec[i].(int64))
		case qInt32:
			rec[i] = int32(rec[i].(int64))
		case qInt64:
		case qString:
		case qUint8:
			rec[i] = uint8(rec[i].(uint64))
		case qUint16:
			rec[i] = uint16(rec[i].(uint64))
		case qUint32:
			rec[i] = uint32(rec[i].(uint64))
		case qUint64:
		case qBlob, qBigInt, qBigRat, qTime, qDuration:
			switch x := rec[i].(type) {
			case []byte:
				rec[i] = chunk{f: s, b: x}
			default:
				return nil, fmt.Errorf("(file-006) corrupted DB: non nil chunk type is not []byte")
			}
		default:
			panic("internal error 045")
		}
	}

	if cols != nil {
		for n, dn := len(cols)+2, len(rec); dn < n; dn++ {
			rec = append(rec, nil)
		}
	}

	return rec, nil
}
示例#9
0
文件: file.go 项目: brgmnn/syncthing
//NTYPE
func infer(from []interface{}, to *[]*col) {
	if len(*to) == 0 {
		*to = make([]*col, len(from))
		for i := range *to {
			(*to)[i] = &col{}
		}
	}
	for i, c := range *to {
		if f := from[i]; f != nil {
			switch x := f.(type) {
			//case nil:
			case idealComplex:
				c.typ = qComplex128
				from[i] = complex128(x)
			case idealFloat:
				c.typ = qFloat64
				from[i] = float64(x)
			case idealInt:
				c.typ = qInt64
				from[i] = int64(x)
			case idealRune:
				c.typ = qInt32
				from[i] = int32(x)
			case idealUint:
				c.typ = qUint64
				from[i] = uint64(x)
			case bool:
				c.typ = qBool
			case complex128:
				c.typ = qComplex128
			case complex64:
				c.typ = qComplex64
			case float64:
				c.typ = qFloat64
			case float32:
				c.typ = qFloat32
			case int8:
				c.typ = qInt8
			case int16:
				c.typ = qInt16
			case int32:
				c.typ = qInt32
			case int64:
				c.typ = qInt64
			case string:
				c.typ = qString
			case uint8:
				c.typ = qUint8
			case uint16:
				c.typ = qUint16
			case uint32:
				c.typ = qUint32
			case uint64:
				c.typ = qUint64
			case []byte:
				c.typ = qBlob
			case *big.Int:
				c.typ = qBigInt
			case *big.Rat:
				c.typ = qBigRat
			case time.Time:
				c.typ = qTime
			case time.Duration:
				c.typ = qDuration
			case chunk:
				vals, err := lldb.DecodeScalars([]byte(x.b))
				if err != nil {
					panic(err)
				}

				if len(vals) == 0 {
					panic("internal error 040")
				}

				i, ok := vals[0].(int64)
				if !ok {
					panic("internal error 041")
				}

				c.typ = int(i)
			case map[string]interface{}: // map of ids of a cross join
			default:
				panic("internal error 042")
			}
		}
	}
}