コード例 #1
0
ファイル: main.go プロジェクト: mervin0502/kv
func main0(fn string, oMax int, w func(s string, a ...interface{}), oStat bool, first, last string, dump bool, oBuckets bool) error {
	f, err := os.Open(fn) // O_RDONLY
	if err != nil {
		return err
	}

	defer f.Close()

	bits, err := ioutil.TempFile("", "kvaudit-")
	if err != nil {
		return err
	}

	defer func() {
		nm := bits.Name()
		bits.Close()
		os.Remove(nm)
	}()

	a, err := lldb.NewAllocator(lldb.NewInnerFiler(lldb.NewSimpleFileFiler(f), 16), &lldb.Options{})
	if err != nil {
		return err
	}

	cnt := 0
	var stats lldb.AllocStats
	err = a.Verify(lldb.NewSimpleFileFiler(bits), func(err error) bool {
		cnt++
		w("%d: %v\n", cnt, err)
		return cnt < oMax
	}, &stats)
	if err != nil {
		return err
	}

	if oStat {
		w("Handles     %10d  // total valid handles in use\n", stats.Handles)
		w("Compression %10d  // number of compressed blocks\n", stats.Compression)
		w("TotalAtoms  %10d  // total number of atoms == AllocAtoms + FreeAtoms\n", stats.TotalAtoms)
		w("AllocBytes  %10d  // bytes allocated (after decompression, if/where used)\n", stats.AllocBytes)
		w("AllocAtoms  %10d  // atoms allocated/used, including relocation atoms\n", stats.AllocAtoms)
		w("Relocations %10d  // number of relocated used blocks\n", stats.Relocations)
		w("FreeAtoms   %10d  // atoms unused\n", stats.FreeAtoms)
	}
	if oBuckets {
		var alloc, free [14]int64
		sizes := [14]int64{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 4112}
		for atoms, cnt := range stats.AllocMap {
			if atoms >= 4096 {
				alloc[13] += cnt
				continue
			}

			for i := range sizes {
				if sizes[i+1] > atoms {
					alloc[i] += cnt
					break
				}
			}
		}
		for atoms, cnt := range stats.FreeMap {
			if atoms > 4096 {
				free[13] += cnt
				continue
			}

			for i := range sizes {
				if sizes[i+1] > atoms {
					free[i] += cnt
					break
				}
			}
		}
		w("Alloc blocks\n")
		for i, v := range alloc {
			w("%4d: %10d\n", sizes[i], v)
		}
		w("Free blocks\n")
		for i, v := range free {
			w("%4d: %10d\n", sizes[i], v)
		}
	}

	if !(first != "" || last != "" || dump) {
		return nil
	}

	t, err := lldb.OpenBTree(a, nil, 1)
	if err != nil {
		return err
	}

	dw := bufio.NewWriter(os.Stdout)
	defer dw.Flush()

	var e *lldb.BTreeEnumerator
	switch {
	case first != "":
		e, _, err = t.Seek([]byte(first))
	default:
		e, err = t.SeekFirst()
	}
	if err != nil {
		if err == io.EOF {
			err = nil
		}
		return err
	}

	blast := []byte(last)
	sep := []byte("->")
	for {
		k, v, err := e.Next()
		if err != nil {
			if err == io.EOF {
				err = nil
			}
			return err
		}

		dw.WriteString(fmt.Sprintf("+%d,%d:", len(k), len(v)))
		dw.Write(k)
		dw.Write(sep)
		dw.Write(v)
		dw.WriteByte('\n')

		if len(blast) != 0 && bytes.Compare(k, blast) >= 0 {
			break
		}
	}

	return nil
}
コード例 #2
0
ファイル: main.go プロジェクト: hellcoderz/kv
func main0(fn string, oMax int, w func(s string, a ...interface{}), oStat bool, first, last string, dump bool) error {
	f, err := os.Open(fn) // O_RDONLY
	if err != nil {
		return err
	}

	defer f.Close()

	bits, err := ioutil.TempFile("", "kvaudit-")
	if err != nil {
		return err
	}

	defer bits.Close()

	a, err := lldb.NewAllocator(lldb.NewInnerFiler(lldb.NewSimpleFileFiler(f), 16), &lldb.Options{})
	if err != nil {
		return err
	}

	cnt := 0
	var stats lldb.AllocStats
	err = a.Verify(lldb.NewSimpleFileFiler(bits), func(err error) bool {
		cnt++
		w("%d: %v\n", cnt, err)
		return cnt < oMax
	}, &stats)
	if oStat {
		w("%#v\n", &stats)
	}
	if err != nil {
		return err
	}

	if !(first != "" || last != "" || dump) {
		return nil
	}

	t, err := lldb.OpenBTree(a, nil, 1)
	if err != nil {
		return err
	}

	dw := bufio.NewWriter(os.Stdout)
	defer dw.Flush()

	var e *lldb.BTreeEnumerator
	switch {
	case first != "":
		e, _, err = t.Seek([]byte(first))
	default:
		e, err = t.SeekFirst()
	}
	if err != nil {
		if err == io.EOF {
			err = nil
		}
		return err
	}

	blast := []byte(last)
	sep := []byte("->")
	for {
		k, v, err := e.Next()
		if err != nil {
			if err == io.EOF {
				err = nil
			}
			return err
		}

		dw.WriteString(fmt.Sprintf("+%d,%d:", len(k), len(v)))
		dw.Write(k)
		dw.Write(sep)
		dw.Write(v)
		dw.WriteByte('\n')

		if len(blast) != 0 && bytes.Compare(k, blast) >= 0 {
			break
		}
	}

	return nil
}