功能:增强 Schema 系统和添加新示例

- 扩展 Schema 支持更多数据类型(Duration、URL、JSON 等)
- 优化 SSTable 编码解码性能
- 添加多个新示例程序:
  - all_types: 展示所有支持的数据类型
  - new_types: 演示新增类型的使用
  - struct_tags: 展示结构体标签功能
  - time_duration: 时间和持续时间处理示例
- 完善测试用例和文档
- 优化代码结构和错误处理
This commit is contained in:
2025-10-10 00:20:45 +08:00
parent 6d04487789
commit 77087d36c6
41 changed files with 3008 additions and 452 deletions

View File

@@ -9,8 +9,10 @@ import (
"sort"
"strings"
"sync"
"time"
"github.com/edsrzf/mmap-go"
"github.com/shopspring/decimal"
)
const (
@@ -230,47 +232,101 @@ func encodeSSTableRowBinary(row *SSTableRow, schema *Schema) ([]byte, error) {
// writeFieldBinaryValue 写入字段值(二进制格式)
func writeFieldBinaryValue(buf *bytes.Buffer, typ FieldType, value any) error {
switch typ {
case FieldTypeInt64:
var v int64
switch val := value.(type) {
case int:
v = int64(val)
case int64:
v = val
case int32:
v = int64(val)
case int16:
v = int64(val)
case int8:
v = int64(val)
case float64:
v = int64(val)
default:
return fmt.Errorf("cannot convert %T to int64", value)
// 有符号整数类型
case Int:
v, ok := value.(int)
if !ok {
return fmt.Errorf("expected int, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, int64(v))
case Int8:
v, ok := value.(int8)
if !ok {
return fmt.Errorf("expected int8, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case FieldTypeFloat:
var v float64
switch val := value.(type) {
case float64:
v = val
case float32:
v = float64(val)
default:
return fmt.Errorf("cannot convert %T to float64", value)
case Int16:
v, ok := value.(int16)
if !ok {
return fmt.Errorf("expected int16, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case FieldTypeBool:
var b byte
if value.(bool) {
b = 1
case Int32, Rune:
// rune 和 int32 底层类型相同(都是 int32
v, ok := value.(int32)
if !ok {
return fmt.Errorf("expected int32 (or rune), got %T", value)
}
return buf.WriteByte(b)
return binary.Write(buf, binary.LittleEndian, v)
case FieldTypeString:
s := value.(string)
case Int64:
v, ok := value.(int64)
if !ok {
return fmt.Errorf("expected int64, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
// 无符号整数类型
case Uint:
v, ok := value.(uint)
if !ok {
return fmt.Errorf("expected uint, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, uint64(v))
case Uint8, Byte:
// byte 和 uint8 底层类型相同
v, ok := value.(uint8)
if !ok {
return fmt.Errorf("expected uint8 or byte, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case Uint16:
v, ok := value.(uint16)
if !ok {
return fmt.Errorf("expected uint16, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case Uint32:
v, ok := value.(uint32)
if !ok {
return fmt.Errorf("expected uint32, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case Uint64:
v, ok := value.(uint64)
if !ok {
return fmt.Errorf("expected uint64, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
// 浮点类型
case Float32:
v, ok := value.(float32)
if !ok {
return fmt.Errorf("expected float32, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
case Float64:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("expected float64, got %T", value)
}
return binary.Write(buf, binary.LittleEndian, v)
// 字符串类型
case String:
s, ok := value.(string)
if !ok {
return fmt.Errorf("expected string, got %T", value)
}
// 写入长度
if err := binary.Write(buf, binary.LittleEndian, uint32(len(s))); err != nil {
return err
@@ -279,6 +335,55 @@ func writeFieldBinaryValue(buf *bytes.Buffer, typ FieldType, value any) error {
_, err := buf.WriteString(s)
return err
// 布尔类型
case Bool:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("expected bool, got %T", value)
}
var b byte
if v {
b = 1
}
return buf.WriteByte(b)
// Decimal 类型
case Decimal:
v, ok := value.(decimal.Decimal)
if !ok {
return fmt.Errorf("expected decimal.Decimal, got %T", value)
}
// 使用 MarshalBinary 序列化
data, err := v.MarshalBinary()
if err != nil {
return fmt.Errorf("marshal decimal: %w", err)
}
// 写入长度
if err := binary.Write(buf, binary.LittleEndian, uint32(len(data))); err != nil {
return err
}
// 写入数据
_, err = buf.Write(data)
return err
// 时间类型
case Time:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("expected time.Time, got %T", value)
}
// 存储为 Unix 时间戳int64
return binary.Write(buf, binary.LittleEndian, v.Unix())
// 时间间隔类型
case Duration:
v, ok := value.(time.Duration)
if !ok {
return fmt.Errorf("expected time.Duration, got %T", value)
}
// 存储为纳秒int64
return binary.Write(buf, binary.LittleEndian, int64(v))
default:
return fmt.Errorf("unsupported field type: %d", typ)
}
@@ -287,14 +392,65 @@ func writeFieldBinaryValue(buf *bytes.Buffer, typ FieldType, value any) error {
// writeFieldZeroValue 写入字段零值
func writeFieldZeroValue(buf *bytes.Buffer, typ FieldType) error {
switch typ {
case FieldTypeInt64:
// 有符号整数类型
case Int:
return binary.Write(buf, binary.LittleEndian, int64(0))
case FieldTypeFloat:
return binary.Write(buf, binary.LittleEndian, float64(0))
case FieldTypeBool:
return buf.WriteByte(0)
case FieldTypeString:
case Int8:
return binary.Write(buf, binary.LittleEndian, int8(0))
case Int16:
return binary.Write(buf, binary.LittleEndian, int16(0))
case Int32, Rune:
return binary.Write(buf, binary.LittleEndian, int32(0))
case Int64:
return binary.Write(buf, binary.LittleEndian, int64(0))
// 无符号整数类型
case Uint:
return binary.Write(buf, binary.LittleEndian, uint64(0))
case Uint8, Byte:
return binary.Write(buf, binary.LittleEndian, uint8(0))
case Uint16:
return binary.Write(buf, binary.LittleEndian, uint16(0))
case Uint32:
return binary.Write(buf, binary.LittleEndian, uint32(0))
case Uint64:
return binary.Write(buf, binary.LittleEndian, uint64(0))
// 浮点类型
case Float32:
return binary.Write(buf, binary.LittleEndian, float32(0))
case Float64:
return binary.Write(buf, binary.LittleEndian, float64(0))
// 字符串类型
case String:
return binary.Write(buf, binary.LittleEndian, uint32(0))
// 布尔类型
case Bool:
return buf.WriteByte(0)
// Decimal 类型(零值)
case Decimal:
zero := decimal.Zero
data, err := zero.MarshalBinary()
if err != nil {
return fmt.Errorf("marshal zero decimal: %w", err)
}
if err := binary.Write(buf, binary.LittleEndian, uint32(len(data))); err != nil {
return err
}
_, err = buf.Write(data)
return err
// 时间类型零值Unix epoch
case Time:
return binary.Write(buf, binary.LittleEndian, int64(0))
// 时间间隔类型(零值)
case Duration:
return binary.Write(buf, binary.LittleEndian, int64(0))
default:
return fmt.Errorf("unsupported field type: %d", typ)
}
@@ -416,7 +572,58 @@ func decodeSSTableRowBinaryPartial(data []byte, schema *Schema, fields []string)
// readFieldBinaryValue 读取字段值(二进制格式)
func readFieldBinaryValue(buf *bytes.Reader, typ FieldType, keep bool) (any, error) {
switch typ {
case FieldTypeInt64:
// 有符号整数类型
case Int:
var v int64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return int(v), nil
}
return nil, nil
case Int8:
var v int8
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Int16:
var v int16
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Int32:
var v int32
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Rune:
var v int32
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return rune(v), nil
}
return nil, nil
case Int64:
var v int64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
@@ -426,7 +633,79 @@ func readFieldBinaryValue(buf *bytes.Reader, typ FieldType, keep bool) (any, err
}
return nil, nil
case FieldTypeFloat:
// 无符号整数类型
case Uint:
var v uint64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return uint(v), nil
}
return nil, nil
case Uint8:
var v uint8
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Byte:
var v uint8
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return byte(v), nil
}
return nil, nil
case Uint16:
var v uint16
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Uint32:
var v uint32
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Uint64:
var v uint64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
// 浮点类型
case Float32:
var v float32
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
return v, nil
}
return nil, nil
case Float64:
var v float64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
@@ -436,17 +715,8 @@ func readFieldBinaryValue(buf *bytes.Reader, typ FieldType, keep bool) (any, err
}
return nil, nil
case FieldTypeBool:
b, err := buf.ReadByte()
if err != nil {
return nil, err
}
if keep {
return b == 1, nil
}
return nil, nil
case FieldTypeString:
// 字符串类型
case String:
var length uint32
if err := binary.Read(buf, binary.LittleEndian, &length); err != nil {
return nil, err
@@ -460,6 +730,60 @@ func readFieldBinaryValue(buf *bytes.Reader, typ FieldType, keep bool) (any, err
}
return nil, nil
// 布尔类型
case Bool:
b, err := buf.ReadByte()
if err != nil {
return nil, err
}
if keep {
return b == 1, nil
}
return nil, nil
// Decimal 类型
case Decimal:
var length uint32
if err := binary.Read(buf, binary.LittleEndian, &length); err != nil {
return nil, err
}
data := make([]byte, length)
if _, err := buf.Read(data); err != nil {
return nil, err
}
if keep {
var d decimal.Decimal
if err := d.UnmarshalBinary(data); err != nil {
return nil, fmt.Errorf("unmarshal decimal: %w", err)
}
return d, nil
}
return nil, nil
// 时间类型
case Time:
var v int64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
// 从 Unix 时间戳(秒)转换为 time.Time
return time.Unix(v, 0), nil
}
return nil, nil
// 时间间隔类型
case Duration:
var v int64
if err := binary.Read(buf, binary.LittleEndian, &v); err != nil {
return nil, err
}
if keep {
// 从纳秒转换为 time.Duration
return time.Duration(v), nil
}
return nil, nil
default:
return nil, fmt.Errorf("unsupported field type: %d", typ)
}