mirror of
https://github.com/hanzoai/volume.git
synced 2026-10-01 00:48:00 +00:00
A fork of Rancher's local-path-provisioner at v0.0.36. The behaviour is unchanged and deliberately so — a directory on the node a pod lands on is the right thing for a disk. What changes is identity. The provisioner answers to hanzo.ai/volume rather than rancher.io/local-path. That is not branding: two provisioners sharing one name race for the same claims, and a stock k3s carries the upstream one, so a cluster running both would settle our storage by chance. Data lives at /var/lib/hanzo/volume, so reading a Hanzo cluster does not mean learning another vendor's directory. Apache-2.0 as published, unaltered, with Rancher's attribution in NOTICE. The README says what this is not: durability. A volume here dies with its node. That is hanzoai/replicate's question, one layer up, and keeping the two apart is what lets the disk stay this simple.
105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
package jsoniter
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/modern-go/reflect2"
|
|
"io"
|
|
"unsafe"
|
|
)
|
|
|
|
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|
arrayType := typ.(*reflect2.UnsafeArrayType)
|
|
decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
|
|
return &arrayDecoder{arrayType, decoder}
|
|
}
|
|
|
|
func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|
arrayType := typ.(*reflect2.UnsafeArrayType)
|
|
if arrayType.Len() == 0 {
|
|
return emptyArrayEncoder{}
|
|
}
|
|
encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
|
|
return &arrayEncoder{arrayType, encoder}
|
|
}
|
|
|
|
type emptyArrayEncoder struct{}
|
|
|
|
func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
stream.WriteEmptyArray()
|
|
}
|
|
|
|
func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return true
|
|
}
|
|
|
|
type arrayEncoder struct {
|
|
arrayType *reflect2.UnsafeArrayType
|
|
elemEncoder ValEncoder
|
|
}
|
|
|
|
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
stream.WriteArrayStart()
|
|
elemPtr := unsafe.Pointer(ptr)
|
|
encoder.elemEncoder.Encode(elemPtr, stream)
|
|
for i := 1; i < encoder.arrayType.Len(); i++ {
|
|
stream.WriteMore()
|
|
elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
|
|
encoder.elemEncoder.Encode(elemPtr, stream)
|
|
}
|
|
stream.WriteArrayEnd()
|
|
if stream.Error != nil && stream.Error != io.EOF {
|
|
stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
|
|
}
|
|
}
|
|
|
|
func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return false
|
|
}
|
|
|
|
type arrayDecoder struct {
|
|
arrayType *reflect2.UnsafeArrayType
|
|
elemDecoder ValDecoder
|
|
}
|
|
|
|
func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
decoder.doDecode(ptr, iter)
|
|
if iter.Error != nil && iter.Error != io.EOF {
|
|
iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
|
|
}
|
|
}
|
|
|
|
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
|
|
c := iter.nextToken()
|
|
arrayType := decoder.arrayType
|
|
if c == 'n' {
|
|
iter.skipThreeBytes('u', 'l', 'l')
|
|
return
|
|
}
|
|
if c != '[' {
|
|
iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
c = iter.nextToken()
|
|
if c == ']' {
|
|
return
|
|
}
|
|
iter.unreadByte()
|
|
elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
|
|
decoder.elemDecoder.Decode(elemPtr, iter)
|
|
length := 1
|
|
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
|
|
if length >= arrayType.Len() {
|
|
iter.Skip()
|
|
continue
|
|
}
|
|
idx := length
|
|
length += 1
|
|
elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
|
|
decoder.elemDecoder.Decode(elemPtr, iter)
|
|
}
|
|
if c != ']' {
|
|
iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
|
|
return
|
|
}
|
|
}
|